Skip to content
This repository was archived by the owner on Mar 13, 2022. It is now read-only.

Commit 281f17a

Browse files
committed
add support for server side apply
1 parent b0afc93 commit 281f17a

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

dynamic/client.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,20 @@ def patch(self, resource, body=None, name=None, namespace=None, **kwargs):
149149

150150
return self.request('patch', path, body=body, content_type=content_type, **kwargs)
151151

152+
def server_side_apply(self, resource, body=None, name=None, namespace=None, force_conflicts=None, **kwargs):
153+
body = self.serialize_body(body)
154+
name = name or body.get('metadata', {}).get('name')
155+
if not name:
156+
raise ValueError("name is required to patch {}.{}".format(resource.group_version, resource.kind))
157+
if resource.namespaced:
158+
namespace = self.ensure_namespace(resource, namespace, body)
159+
160+
# force content type to 'application/apply-patch+yaml'
161+
kwargs.update({'content_type': 'application/apply-patch+yaml'})
162+
path = resource.path(name=name, namespace=namespace)
163+
164+
return self.request('patch', path, body=body, force_conflicts=force_conflicts, **kwargs)
165+
152166
def watch(self, resource, namespace=None, name=None, label_selector=None, field_selector=None, resource_version=None, timeout=None, watcher=None):
153167
"""
154168
Stream events for a resource from the Kubernetes API
@@ -227,6 +241,10 @@ def request(self, method, path, body=None, **params):
227241
query_params.append(('orphanDependents', params['orphan_dependents']))
228242
if params.get('dry_run') is not None:
229243
query_params.append(('dryRun', params['dry_run']))
244+
if params.get('field_manager') is not None:
245+
query_params.append(('fieldManager', params['field_manager']))
246+
if params.get('force_conflicts') is not None:
247+
query_params.append(('force', params['force_conflicts']))
230248

231249
header_params = params.get('header_params', {})
232250
form_params = []

dynamic/test_client.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import time
1616
import unittest
1717
import uuid
18+
import json
1819

1920
from kubernetes.e2e_test import base
2021
from kubernetes.client import api_client
@@ -394,6 +395,29 @@ def test_node_apis_partial_object_metadata(self):
394395
self.assertEqual('PartialObjectMetadataList', resp.kind)
395396
self.assertEqual('meta.k8s.io/v1', resp.apiVersion)
396397

398+
def test_server_side_apply_api(self):
399+
client = DynamicClient(api_client.ApiClient(configuration=self.config))
400+
api = client.resources.get(
401+
api_version='v1', kind='Pod')
402+
403+
name = 'pod-' + short_uuid()
404+
pod_manifest = {
405+
'apiVersion': 'v1',
406+
'kind': 'Pod',
407+
'metadata': {'labels': {'name': name},
408+
'name': name},
409+
'spec': {'containers': [{
410+
'image': 'nginx',
411+
'name': 'nginx',
412+
'ports': [{'containerPort': 80,
413+
'protocol': 'TCP'}]}]}}
414+
415+
body = json.dumps(pod_manifest).encode()
416+
resp = api.server_side_apply(
417+
name=name, namespace='default', body=body,
418+
field_manager='kubernetes-unittests', dry_run="All")
419+
self.assertEqual('kubernetes-unittests', resp.metadata.managedFields[0].manager)
420+
397421

398422
class TestDynamicClientSerialization(unittest.TestCase):
399423

0 commit comments

Comments
 (0)