-
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 15 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,180 @@ | ||
# Copyright 2018 The Kubernetes Authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
|
||
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 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. | ||
yml_document: dictonary holding valid kubernetes object | ||
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 = [] | ||
|
||
if "List" in yml_document["kind"]: | ||
#For cases where it is List Pod/Service... | ||
# For such cases iterate over the items | ||
kind = yml_document["kind"].replace("List","") | ||
for yml_doc in yml_document["items"]: | ||
if kind!="": | ||
yml_doc["apiVersion"]=yml_document["apiVersion"] | ||
yml_doc["kind"]= kind | ||
try: | ||
# call function delete_from_yaml_single_item | ||
delete_from_yaml_single_item( | ||
k8s_client, yml_doc, verbose, namespace=namespace, **kwargs | ||
) | ||
except client.rest.ApiException as api_exception: | ||
api_exceptions.append(api_exception) | ||
|
||
else: | ||
|
||
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="Background", grace_period_seconds=5),**kwargs) | ||
|
||
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="Background", grace_period_seconds=5),**kwargs) | ||
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