flant/cert-manager-webhook-nicru

Ошибка с парсингом ответа от API nic.ru

Kerlay opened this issue · 18 comments

Kerlay commented

Проверил вручную ответ от API все работает корректно. А в логах наблюдается данная ошибка:

E0714 08:39:00.822400       1 get_zone_info.go:18] Error: parse "https://api.nic.ru/dns-master/zones/?token=<ACCESS_TOKEN>\n": net/url: invalid control character in URL
E0714 08:39:00.822688       1 runtime.go:77] Observed a panic: runtime error: invalid memory address or nil pointer dereference
goroutine 256030 [running]:
k8s.io/apiserver/pkg/endpoints/handlers/finisher.finishRequest.func1.1()
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/finisher/finisher.go:105 +0xaf
panic({0x20657c0, 0x3a5f1e0})
	/usr/local/go/src/runtime/panic.go:884 +0x212
net/http.(*Client).do(0xc000311060?, 0x0)
	/usr/local/go/src/net/http/client.go:590 +0xcc
net/http.(*Client).Do(...)
	/usr/local/go/src/net/http/client.go:581
main.(*nicruDNSProviderSolver).getZoneInfo(0x203000?, {0xc00064ada0, 0xd})
	/src/get_zone_info.go:21 +0x1d6
main.(*nicruDNSProviderSolver).Present(0x22db9a0?, 0xc000763d40)
	/src/main.go:56 +0x56
github.com/cert-manager/cert-manager/pkg/acme/webhook/registry/challengepayload.(*REST).callSolver(0xc0003102b0, {{0x0, 0x0}, {0xc00064ad70, 0x7}, {0xc00064ad78, 0x6}, {0xc00064ad80, 0xf}, {0xc0008bacf0, ...}, ...})
	/go/pkg/mod/github.com/cert-manager/cert-manager@v1.11.0/pkg/acme/webhook/registry/challengepayload/challenge_payload.go:86 +0x189
github.com/cert-manager/cert-manager/pkg/acme/webhook/registry/challengepayload.(*REST).Create(0x0?, {0xc000c7f201?, 0xc001125920?}, {0x277c690?, 0xc001125920}, 0x279bb20?, 0x27ab230?)
	/go/pkg/mod/github.com/cert-manager/cert-manager@v1.11.0/pkg/acme/webhook/registry/challengepayload/challenge_payload.go:66 +0xe5
k8s.io/apiserver/pkg/endpoints/handlers.(*namedCreaterAdapter).Create(0x0?, {0x2798f18?, 0xc0011259e0?}, {0xc0008c4240?, 0x279bb20?}, {0x277c690?, 0xc001125920?}, 0x1?, 0x0?)
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/create.go:249 +0x42
k8s.io/apiserver/pkg/endpoints/handlers.createHandler.func1.1()
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/create.go:178 +0xd8
k8s.io/apiserver/pkg/endpoints/handlers.createHandler.func1.2()
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/create.go:204 +0x413
k8s.io/apiserver/pkg/endpoints/handlers/finisher.finishRequest.func1()
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/finisher/finisher.go:117 +0x8f
created by k8s.io/apiserver/pkg/endpoints/handlers/finisher.finishRequest
	/go/pkg/mod/k8s.io/apiserver@v0.26.1/pkg/endpoints/handlers/finisher/finisher.go:92 +0xde

Здравствуйте. Покажите как выглядит секрет с токенами в кластере.
Он находится в одном namespace c cert-manager'ом?

Kerlay commented

Да конечно вот:

apiVersion: v1
data:
  ACCESS_TOKEN: <ACCESS_TOKEN>
  REFRESH_TOKEN: <REFRESH_TOKEN>
kind: Secret
metadata:
  creationTimestamp: "2023-07-14T14:59:13Z"
  labels:
    app.kubernetes.io/instance: cert-manager-webhook-nicru
  name: nicru-tokens
  namespace: cert-manager
  resourceVersion: "132810938"
  uid: 87c6297c-373f-4966-880c-43fb9f9323dd
type: Opaque

Так же увидел, что у вас там есть апдейт секрета, для обновления токена. Можно было создать еще тогда функцию, которая генерирует его. Из документации мы получаем следующего ввида запрос:

curl --location --request POST 'https://api.nic.ru/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'password=<pass>' \
--data-urlencode 'client_id=<clien_id>' \
--data-urlencode 'client_secret=<clien_secret>' \
--data-urlencode 'username=<account_username> \
--data-urlencode 'scope=.*' \
--data-urlencode 'offline=999999'

@Kerlay привет! Изначально не все чарты были в репозитории. Добавил отсутствующие: pki.yaml, rbac.yaml, service.yaml.
После их применения проблема должна уйти.

Kerlay commented

У меня есть уже все эти сущности, которые вы обновили. Я за основу брал из hetzner webhook.

Тогда покажите rbac для работы с секретом.

Kerlay commented
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}
  namespace: {{ .Release.Namespace | quote }}
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
---
# Grant the webhook permission to read the ConfigMap containing the Kubernetes
# apiserver's requestheader-ca-certificate.
# This ConfigMap is automatically created by the Kubernetes apiserver.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:webhook-authentication-reader
  namespace: kube-system
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: {{ include "cert-manager-webhook-nicru.fullname" . }}
    namespace: {{ .Release.Namespace }}
---
# apiserver gets the auth-delegator role to delegate auth decisions to
# the core apiserver
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:auth-delegator
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: {{ include "cert-manager-webhook-nicru.fullname" . }}
    namespace: {{ .Release.Namespace }}
---
# Grant cert-manager permission to validate using our apiserver
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:domain-solver
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
rules:
  - apiGroups:
      - {{ .Values.groupName }}
    resources:
      - '*'
    verbs:
      - 'create'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:domain-solver
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:domain-solver
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: {{ .Values.certManager.serviceAccountName }}
    namespace: {{ .Values.certManager.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:secret-reader
  namespace: {{ .Release.Namespace }}
rules:
  - apiGroups:
      - ""
    resources:
      - "secrets"
    {{- with .Values.secretName }}
    resourceNames:
    {{ toYaml . | indent 4 }}
    {{- end }}
    verbs:
      - "get"
      - "watch"
      - "list"
      - "create"
      - "update"
      - "patch"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:secret-reader
  namespace: {{ .Release.Namespace }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:secret-reader
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: {{ include "cert-manager-webhook-nicru.fullname" . }}
    namespace: {{ .Release.Namespace }}
---
# Grant cert-manager permission to validate using our apiserver
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:flowcontrol-solver
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
rules:
  - apiGroups:
      - "flowcontrol.apiserver.k8s.io"
    resources:
      - 'prioritylevelconfigurations'
      - 'flowschemas'
    verbs:
      - 'list'
      - 'watch'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:flowcontrol-solver
  labels:
    app: {{ include "cert-manager-webhook-nicru.name" . }}
    chart: {{ include "cert-manager-webhook-nicru.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}:flowcontrol-solver
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: {{ include "cert-manager-webhook-nicru.fullname" . }}
    namespace: {{ .Release.Namespace | quote }}
---
Kerlay commented

Он даже не пытается сделать апдейт секрета, ошибок в логах по этому поводу не вижу.

Kerlay commented

Вот такое еще в логах есть, это может влиять на работу?

W0720 14:16:04.059670       1 reflector.go:424] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: failed to list *v1beta3.FlowSchema: the server could not find the requested resource
E0720 14:16:04.059704       1 reflector.go:140] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: Failed to watch *v1beta3.FlowSchema: failed to list *v1beta3.FlowSchema: the server could not find the requested resource
W0720 14:16:40.851690       1 reflector.go:424] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: failed to list *v1beta3.PriorityLevelConfiguration: the server could not find the requested resource
E0720 14:16:40.851713       1 reflector.go:140] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: Failed to watch *v1beta3.PriorityLevelConfiguration: failed to list *v1beta3.PriorityLevelConfiguration: the server could not find the requested resource
W0720 14:16:42.855074       1 reflector.go:424] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: failed to list *v1beta3.FlowSchema: the server could not find the requested resource
E0720 14:16:42.855097       1 reflector.go:140] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: Failed to watch *v1beta3.FlowSchema: failed to list *v1beta3.FlowSchema: the server could not find the requested resource
Kerlay commented

Это все выполняется в k3s кластере.

Эти ошибки не влияют. Явно проблема с чтением секрета. Начнём с простого. Попробуйте заменить Role для работы с секретом на ClusterRole.

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}-update-secret
rules:
  - apiGroups:
      - ""
    resources:
      - secrets
    verbs:
      - 'get'
      - 'list'
      - 'watch'
      - 'patch'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}-update-secret
subjects:
  - kind: ServiceAccount
    name: {{ include "cert-manager-webhook-nicru.fullname" . }}
    namespace: {{ .Release.Namespace }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ include "cert-manager-webhook-nicru.fullname" . }}-update-secret
Kerlay commented

Я даже чарты все сделал как у вас, но все равно ошибка возникает.

Kerlay commented

Я вручную запрашиваю токен, подставляю в секрет. После этого удаляю pod с webhook. Он походу запрашивает новый токен, но не обновляет его в секрете. Потому что после перезапуска, когда я обращаюсь с токеном, который выпустил он уже просроченный считается. При этом каких либо ошибок связанных с тем что есть проблема с обновлением секрета нет.

Вот эти переменные корректно выставлены?

Kerlay commented

Да все корректно, я же получаю вручную через curl refresh и access токены.

Kerlay commented

Может quote добавить для этих переменных?

Можете попробовать, но они и так должны корректно восприниматься.
При раскрытии секрета токена никаких лишних символов нет? Если корректный токен руками прописать в секрет, ошибка сохраняется?

Kerlay commented

В общем issue можно закрыть. Спасибо больше. Я когда создавал секрет, то делал это следующим образом echo <secret> | base64 -w 0, а необходимо было echo -n "<secret>" | base64 -w 0 . Отработал вебхук.

Рад был помочь!