<p>I have the following CSR object in Kubernetes:</p>

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

<p>And I would like to approve it using the Python API client:</p>

<pre class="lang-py prettyprint-override"><code>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")
</code></pre>

<p>Now, the contents of the <code>csr</code> object are:</p>

<pre><code>{'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'}]}}

</code></pre>

<p>I would like to <strong>approve</strong> this cert programmatically, if I use kubectl to do it with (<code>-v=10</code> will make <code>kubectl</code> output the http trafffic):</p>

<pre><code>kubectl certificate approve test-certificate-0.my-namespace -v=10
</code></pre>

<p>I get to see the <code>PUT</code> operation used to <strong>Approve</strong> my certificate:</p>

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

<p>So I need to <code>PUT</code> to the <code>/approval</code> resource of the certificate object. Now, how do I do it with the Python Kubernetes client?</p>

<p>Here's to answer my question based on @jaxxstorm answer and my own investigation:</p>

<pre><code># 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)
</code></pre>

<p>After this, the KubeCA will approve and issue the new certificate. The issued certificate file can be obtained from the <code>response</code> object we just got:</p>

<pre><code>import base64
base64.b64decode(response.status.certificate) # this will return the decoded cert
</code></pre>
