Утвердить CSR в Kuberentes с помощью клиента Python

#python #kubernetes #kubernetes-python-client

#python #kubernetes #kubernetes-python-client

Вопрос:

У меня есть следующий объект CSR в Kubernetes:

 $ kubectl get csr
NAME                                     AGE       REQUESTOR                                      CONDITION
test-certificate-0.my-namespace          53m       system:serviceaccount:my-namespace:some-user   Pending
  

И я хотел бы утвердить его с помощью клиента Python API:

 from kuberentes import config, client
# configure session
config.load_kube_config()
# get a hold of the certs API
certs_api = client.CertificatesV1beta1Api()

# read my CSR
csr = certs_api.read_certificate_signing_request("test-certificate-0.my-namespace")
  

Теперь содержимое csr объекта является:

 {'api_version': 'certificates.k8s.io/v1beta1',
 'kind': 'CertificateSigningRequest',
 'metadata': {'annotations': None,
              'cluster_name': None,
              'creation_timestamp': datetime.datetime(2019, 3, 15, 14, 36, 28, tzinfo=tzutc()),
              'deletion_grace_period_seconds': None,
              'name': 'test-certificate-0.my-namespace',
              'namespace': None,
              'owner_references': None,
              'resource_version': '4269575',
              'self_link': '/apis/certificates.k8s.io/v1beta1/certificatesigningrequests/test-certificate-0.my-namespace',
              'uid': 'b818fa4e-472f-11e9-a394-124b379b4e12'},
 'spec': {'extra': None,
          'groups': ['system:serviceaccounts',
                     'system:serviceaccounts:cloudp-38483-test01',
                     'system:authenticated'],
          'request': 'redacted',
          'uid': 'd5bfde1b-4036-11e9-a394-124b379b4e12',
          'usages': ['digital signature', 'key encipherment', 'server auth'],
          'username': 'system:serviceaccount:test-certificate-0.my-namespace'},
 'status': {'certificate': 'redacted',
            'conditions': [{'last_update_time': datetime.datetime(2019, 3, 15, 15, 13, 32, tzinfo=tzutc()),
                            'message': 'This CSR was approved by kubectl certificate approve.',
                            'reason': 'KubectlApprove',
                            'type': 'Approved'}]}}

  

Я хотел бы утвердить этот сертификат программно, если я использую kubectl для этого ( -v=10 заставит kubectl выводить http-трафик):

 kubectl certificate approve test-certificate-0.my-namespace -v=10
  

Я вижу PUT операцию, использованную для утверждения моего сертификата:

 PUT https://my-kubernetes-cluster.com:8443/apis/certificates.k8s.io/v1beta1/certificatesigningrequests/test-certificate-0.my-namespace/approval
  

Итак, мне нужен PUT доступ к /approval ресурсу объекта certificate. Теперь, как мне это сделать с помощью клиента Python Kubernetes?

Ответ №1:

У него странное название, но оно есть в документах для клиента python — вы хотите replace_certificate_signing_request_approval

 # create an instance of the API class
api_instance = kubernetes.client.CertificatesV1beta1Api(kubernetes.client.ApiClient(configuration))
name = 'name_example' # str | name of the CertificateSigningRequest
body = kubernetes.client.V1beta1CertificateSigningRequest() # V1beta1CertificateSigningRequest | 
dry_run = 'dry_run_example' # str | When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed (optional)
pretty = 'pretty_example' # str | If 'true', then the output is pretty printed. (optional)

try: 
    api_response = api_instance.replace_certificate_signing_request_approval(name, body, dry_run=dry_run, pretty=pretty)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling CertificatesV1beta1Api->replace_certificate_signing_request_approval: %sn" % e)
  

Комментарии:

1. Я добавил больше информации к этому ответу в новом ответе. Спасибо!

Ответ №2:

Вот ответ на мой вопрос, основанный на ответе @ jaxxstorm и моем собственном расследовании:

 # Import required libs and configure your client
from datetime import datetime, timezone
from kubernetes import config, client
config.load_kube_config()

# this is the name of the CSR we want to Approve
name = 'my-csr'

# a reference to the API we'll use 
certs_api = client.CertificatesV1beta1Api()

# obtain the body of the CSR we want to sign
body = certs_api.read_certificate_signing_request_status(name)

# create an approval condition
approval_condition = client.V1beta1CertificateSigningRequestCondition(
    last_update_time=datetime.now(timezone.utc).astimezone(),
    message='This certificate was approved by Python Client API',
    reason='MyOwnReason',
    type='Approved')

# patch the existing `body` with the new conditions
# you might want to append the new conditions to the existing ones
body.status.conditions = [approval_condition]

# patch the Kubernetes object
response = certs_api.replace_certificate_signing_request_approval(name, body)
  

После этого KubeCA утвердит и выдаст новый сертификат. Выданный файл сертификата может быть получен из response объекта, который мы только что получили:

 import base64
base64.b64decode(response.status.certificate) # this will return the decoded cert
  

Комментарии:

1. Это работает и для client-go. В случае перехода клиента, это clientset.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(req) . Вот соответствующий фрагмент кода: github.com/kubernetes/client-go/blob/master/kubernetes/typed /…