2222from kubernetes_asyncio .client .api_client import ApiClient
2323from kubernetes_asyncio .client .exceptions import ApiException
2424from kubernetes_asyncio .config import Any
25+ from kubernetes_asyncio .dynamic .client import DynamicClient
2526
2627
2728async def create_from_yaml (
2829 k8s_client : ApiClient ,
2930 yaml_file : str ,
3031 verbose : bool = False ,
3132 namespace : str = "default" ,
33+ apply : bool = False ,
3234 ** kwargs : Any ,
3335) -> Any :
3436 """
@@ -44,6 +46,7 @@ async def create_from_yaml(
4446 the resource creation will fail. If the API object in
4547 the yaml file already contains a namespace definition
4648 this parameter has no effect.
49+ apply: bool. If True, use server-side apply for creating resources.
4750 Returns:
4851 An k8s api object or list of apis objects created from YAML.
4952 When a single object is generated, return type is dependent
@@ -70,7 +73,12 @@ async def create_from_yaml(
7073 for yml_document in yml_document_all :
7174 try :
7275 created = await create_from_dict (
73- k8s_client , yml_document , verbose , namespace = namespace , ** kwargs
76+ k8s_client ,
77+ yml_document ,
78+ verbose ,
79+ namespace = namespace ,
80+ apply = apply ,
81+ ** kwargs ,
7482 )
7583 k8s_objects .append (created )
7684 except FailToCreateError as failure :
@@ -88,6 +96,7 @@ async def create_from_dict(
8896 data : dict ,
8997 verbose : bool = False ,
9098 namespace : str = "default" ,
99+ apply : bool = False ,
91100 ** kwargs : Any ,
92101) -> Any :
93102 """
@@ -103,6 +112,7 @@ async def create_from_dict(
103112 the resource creation will fail. If the API object in
104113 the yaml file already contains a namespace definition
105114 this parameter has no effect.
115+ apply: bool. If True, use server-side apply for creating resources.
106116 Returns:
107117 An k8s api object or list of apis objects created from dict.
108118 When a single object is generated, return type is dependent
@@ -136,7 +146,7 @@ async def create_from_dict(
136146 yml_object ["kind" ] = kind
137147 try :
138148 created = await create_from_yaml_single_item (
139- k8s_client , yml_object , verbose , namespace , ** kwargs
149+ k8s_client , yml_object , verbose , namespace , apply = apply , ** kwargs
140150 )
141151 k8s_objects .append (created )
142152 except client .ApiException as api_exception :
@@ -145,7 +155,7 @@ async def create_from_dict(
145155 # This is a single object. Call the single item method
146156 try :
147157 created = await create_from_yaml_single_item (
148- k8s_client , data , verbose , namespace , ** kwargs
158+ k8s_client , data , verbose , namespace , apply = apply , ** kwargs
149159 )
150160 k8s_objects .append (created )
151161 except client .ApiException as api_exception :
@@ -162,8 +172,21 @@ async def create_from_yaml_single_item(
162172 yml_object : dict ,
163173 verbose : bool = False ,
164174 namespace : str = "default" ,
175+ apply : bool = False ,
165176 ** kwargs : Any ,
166177) -> Any :
178+ kind = yml_object ["kind" ]
179+ if apply is True :
180+ apply_client = await (await DynamicClient (k8s_client )).resources .get (
181+ api_version = yml_object ["apiVersion" ], kind = kind
182+ )
183+ resp = await apply_client .server_side_apply (
184+ body = yml_object , field_manager = "python-client" , ** kwargs
185+ )
186+ if verbose :
187+ print (f"{ kind } applied. status='{ str (resp .status )} '" )
188+ return resp
189+
167190 group , _ , version = yml_object ["apiVersion" ].partition ("/" )
168191 if version == "" :
169192 version = group
@@ -177,7 +200,6 @@ async def create_from_yaml_single_item(
177200 fcn_to_call = f"{ group } { version .capitalize ()} Api"
178201 k8s_api = getattr (client , fcn_to_call )(k8s_client )
179202 # Replace CamelCased action_type into snake_case
180- kind = yml_object ["kind" ]
181203 kind = re .sub ("(.)([A-Z][a-z]+)" , r"\1_\2" , kind )
182204 kind = re .sub ("([a-z0-9])([A-Z])" , r"\1_\2" , kind ).lower ()
183205 # Decide which namespace we are going to put the object in,
0 commit comments