-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Delete from yaml #1197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delete from yaml #1197
Changes from 5 commits
b61fb5c
5fc0f53
d339958
a8e5ac3
7e75c96
9605ff1
f153cf1
829ecc8
c86181b
1e3093b
424fb43
0108418
4e3d675
b010a19
414946e
ab1329c
0a3cbcb
399c166
704655f
8c1967f
ec5db9c
6ff6e44
3833f7e
5c90c18
92bf36b
598d41b
e842ec9
f1cc695
56ab983
0eb5f0f
a80b3f5
a9ad7d7
bfb46ff
0bd5e13
22d623b
b79ad68
a63bf99
32c5231
ebd9864
54377ea
a20b3a1
92d50aa
89e06d1
1233244
e0f4c5c
b03e37e
81374a3
4e81da5
0bf74fc
36838fc
371d252
c87c272
3ce0c5a
e87ad34
95b1d2c
2e22a7b
fa84691
de8d44e
2bfdf96
b0c1eab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import re | ||
from os import path | ||
|
||
import yaml | ||
|
||
from kubernetes import client | ||
|
||
|
||
def delete_from_yaml( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. overall, what is the difference between this and create_from_yaml? could you please list the differences in the PR description? is it possible to reuse to avoid dups? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I will do it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have written the difference between the methods create_from_yaml and delete_from_yaml editing the PR description and also fixed the issues as stated earlier. |
||
k8s_client, | ||
yaml_file, | ||
verbose=False, | ||
namespace="default", | ||
**kwargs): | ||
''' | ||
Input: | ||
yaml_file: string. Contains the path to yaml file. | ||
k8s_client: an ApiClient object, initialized with the client args. | ||
verbose: If True, print confirmation from the create action. | ||
Default is False. | ||
namespace: string. Contains the namespace to create all | ||
resources inside. The namespace must preexist otherwise | ||
the resource creation will fail. If the API object in | ||
the yaml file already contains a namespace definition | ||
this parameter has no effect. | ||
Available parameters for creating <kind>: | ||
:param async_req bool | ||
:param bool include_uninitialized: If true, partially initialized | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the initializer feature has been removed |
||
resources are included in the response. | ||
:param str pretty: If 'true', then the output is pretty printed. | ||
:param str dry_run: 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 | ||
Raises: | ||
FailToDeleteError which holds list of `client.rest.ApiException` | ||
instances for each object that failed to delete. | ||
''' | ||
# open yml file | ||
with open(path.abspath(yaml_file)) as f: | ||
#load all yml content | ||
yml_document_all = yaml.safe_load_all(f) | ||
|
||
failures=[] | ||
for yml_document in yml_document_all: | ||
try: | ||
# call delete from dict function | ||
delete_from_dict(k8s_client,yml_document,verbose, | ||
namespace=namespace, | ||
**kwargs) | ||
except FailToDeleteError as failure: | ||
# if error is returned add to failures list | ||
failures.extend(failure.api_exceptions) | ||
if failures: | ||
#display the error | ||
raise FailToDeleteError(failures) | ||
|
||
def delete_from_dict(k8s_client,yml_document, verbose,namespace="default",**kwargs): | ||
""" | ||
Perform an action from a dictionary containing valid kubernetes | ||
API object (i.e. List, Service, etc). | ||
Input: | ||
k8s_client: an ApiClient object, initialized with the client args. | ||
data: a dictionary holding valid kubernetes objects | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the comment doesn't match the parameter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed the comment with correct parameter |
||
verbose: If True, print confirmation from the create action. | ||
Default is False. | ||
namespace: string. Contains the namespace to create all | ||
resources inside. The namespace must preexist otherwise | ||
the resource creation will fail. If the API object in | ||
the yaml file already contains a namespace definition | ||
this parameter has no effect. | ||
Raises: | ||
FailToDeleteError which holds list of `client.rest.ApiException` | ||
instances for each object that failed to delete. | ||
""" | ||
api_exceptions = [] | ||
try: | ||
# call function delete_from_yaml_single_item | ||
delete_from_yaml_single_item( | ||
k8s_client, yml_document, verbose, namespace=namespace, **kwargs | ||
) | ||
except client.rest.ApiException as api_exception: | ||
api_exceptions.append(api_exception) | ||
|
||
if api_exceptions: | ||
raise FailToDeleteError(api_exceptions) | ||
|
||
|
||
def delete_from_yaml_single_item(k8s_client, yml_document, verbose=False, **kwargs): | ||
# get group and version from apiVersion | ||
group,_,version = yml_document["apiVersion"].partition("/") | ||
if version == "": | ||
version = group | ||
group = "core" | ||
# Take care for the case e.g. api_type is "apiextensions.k8s.io" | ||
group = "".join(group.rsplit(".k8s.io", 1)) | ||
# convert group name from DNS subdomain format to | ||
# python class name convention | ||
group = "".join(word.capitalize() for word in group.split('.')) | ||
func = "{0}{1}Api".format(group, version.capitalize()) | ||
k8s_api = getattr(client, func)(k8s_client) | ||
kind = yml_document["kind"] | ||
kind = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', kind) | ||
kind = re.sub('([a-z0-9])([A-Z])', r'\1_\2', kind).lower() | ||
|
||
if getattr(k8s_api,"delete_namespaced_{}".format(kind)): | ||
# load namespace if provided in yml file | ||
if "namespace" in yml_document["metadata"]: | ||
namespace = yml_document["metadata"]["namespace"] | ||
kwargs["namespace"] = namespace | ||
# take name input of kubernetes object | ||
name = yml_document["metadata"]["name"] | ||
#call function to delete from namespace | ||
res = getattr(k8s_api,"delete_namespaced_{}".format(kind))( | ||
name=name,body=client.V1DeleteOptions(propagation_policy="Foreground", grace_period_seconds=5),**kwargs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we want to achieve parity with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have updated this to use background policy |
||
|
||
else: | ||
# get name of object to delete | ||
name = yml_document["metadata"]["name"] | ||
kwargs.pop('namespace', None) | ||
res = getattr(k8s_api,"delete_{}".format(kind))( | ||
name=name,body=client.V1DeleteOptions(propagation_policy="Foreground", grace_period_seconds=5),**kwargs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A 200 response from a delete request doesn't guarantee the resource being deleted. We should wait until the resource is no longer visible from the server. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How should the e2e tests work for objects being deleted , after deletion if they are search (the object) it gets timed out resulting in an error ,however in the create_from_yaml tests in the end all resources are being deleted using multiple separate commands could we delete those using the delete_from_yaml method and that would be sufficient? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /assign @yliaog There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in e2e, after delete, try listing the object again, if it does not exist anymore, it means the object is successfully deleted. |
||
if verbose: | ||
msg = "{0} deleted.".format(kind) | ||
if hasattr(res, 'status'): | ||
msg += " status='{0}'".format(str(res.status)) | ||
print(msg) | ||
|
||
|
||
class FailToDeleteError(Exception): | ||
""" | ||
An exception class for handling error if an error occurred when | ||
handling a yaml file during deletion of the resource. | ||
""" | ||
|
||
def __init__(self, api_exceptions): | ||
self.api_exceptions = api_exceptions | ||
|
||
def __str__(self): | ||
msg = "" | ||
for api_exception in self.api_exceptions: | ||
msg += "Error from server ({0}): {1}".format( | ||
api_exception.reason, api_exception.body) | ||
return msg | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add copyright boilerplate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure Ill add the boilerplate and try writing the tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added the boilerplate and added tests also modifying delete_from_dict function