Merge "Implement the 'gbp purge <tenant ID>' CLI" into stable/mitaka
This commit is contained in:
		
							
								
								
									
										112
									
								
								gbpclient/gbp/v2_0/purge.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								gbpclient/gbp/v2_0/purge.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | #    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 | ||||||
|  | import sys | ||||||
|  |  | ||||||
|  | from neutronclient.common import exceptions as nexc | ||||||
|  | from neutronclient.neutron.v2_0 import purge as n_purge | ||||||
|  |  | ||||||
|  | AUTO_PTG_REGEX = 'auto[0-9a-f]{32}\Z' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Purge(n_purge.Purge): | ||||||
|  |     """Delete all resources that belong to a given tenant.""" | ||||||
|  |  | ||||||
|  |     def _pluralize(self, string): | ||||||
|  |         if re.search('_policy$', string): | ||||||
|  |             return re.sub('_policy$', '_policies', string) | ||||||
|  |         return string + 's' | ||||||
|  |  | ||||||
|  |     def _get_resources(self, neutron_client, resource_types, tenant_id): | ||||||
|  |         resources = super(Purge, self)._get_resources(neutron_client, | ||||||
|  |                                                       resource_types, | ||||||
|  |                                                       tenant_id) | ||||||
|  |         # exclude auto_ptg as it was created by implicit workflow | ||||||
|  |         if 'policy_target_group' in resource_types: | ||||||
|  |             index = resource_types.index('policy_target_group') | ||||||
|  |             for resource in list(resources[index]): | ||||||
|  |                 if re.match(AUTO_PTG_REGEX, resource['id']): | ||||||
|  |                     resources[index].remove(resource) | ||||||
|  |                     self.total_resources -= 1 | ||||||
|  |         return resources | ||||||
|  |  | ||||||
|  |     def _purge_resources(self, neutron_client, resource_types, | ||||||
|  |                          tenant_resources): | ||||||
|  |         deleted = {} | ||||||
|  |         failed = {} | ||||||
|  |         failures = False | ||||||
|  |         for index, resources in enumerate(tenant_resources): | ||||||
|  |             resource_type = resource_types[index] | ||||||
|  |             failed[resource_type] = 0 | ||||||
|  |             deleted[resource_type] = 0 | ||||||
|  |             for resource in resources: | ||||||
|  |                 try: | ||||||
|  |                     self._delete_resource(neutron_client, resource_type, | ||||||
|  |                                           resource) | ||||||
|  |                     deleted[resource_type] += 1 | ||||||
|  |                     self.deleted_resources += 1 | ||||||
|  |                 except nexc.NotFound: | ||||||
|  |                     # this is for l2p/l3p created under the | ||||||
|  |                     # implicit workflow. | ||||||
|  |                     deleted[resource_type] += 1 | ||||||
|  |                     self.deleted_resources += 1 | ||||||
|  |                 except Exception: | ||||||
|  |                     failures = True | ||||||
|  |                     failed[resource_type] += 1 | ||||||
|  |                     self.total_resources -= 1 | ||||||
|  |                 percent_complete = 100 | ||||||
|  |                 if self.total_resources > 0: | ||||||
|  |                     percent_complete = (self.deleted_resources / | ||||||
|  |                                         float(self.total_resources)) * 100 | ||||||
|  |                 sys.stdout.write("\rPurging resources: %d%% complete." % | ||||||
|  |                                  percent_complete) | ||||||
|  |                 sys.stdout.flush() | ||||||
|  |         return (deleted, failed, failures) | ||||||
|  |  | ||||||
|  |     def take_action(self, parsed_args): | ||||||
|  |         neutron_client = self.get_client() | ||||||
|  |  | ||||||
|  |         self.any_failures = False | ||||||
|  |  | ||||||
|  |         # A list of the types of resources supported in the order in which | ||||||
|  |         # they should be deleted. | ||||||
|  |         resource_types = ['policy_target', 'policy_target_group', 'l2_policy', | ||||||
|  |                           'l3_policy', 'external_policy', 'nat_pool', | ||||||
|  |                           'external_segment', 'policy_rule_set', | ||||||
|  |                           'policy_rule', 'policy_classifier', | ||||||
|  |                           'policy_action', 'network_service_policy', | ||||||
|  |                           'servicechain_instance', 'servicechain_spec', | ||||||
|  |                           'servicechain_node', 'service_profile'] | ||||||
|  |         deleted = {} | ||||||
|  |         failed = {} | ||||||
|  |         self.total_resources = 0 | ||||||
|  |         self.deleted_resources = 0 | ||||||
|  |         resources = self._get_resources(neutron_client, resource_types, | ||||||
|  |                                         parsed_args.tenant) | ||||||
|  |         deleted, failed, failures = self._purge_resources(neutron_client, | ||||||
|  |                                                           resource_types, | ||||||
|  |                                                           resources) | ||||||
|  |         print('\n%s' % self._build_message(deleted, failed, failures)) | ||||||
|  |  | ||||||
|  |         # TODO(Kent): clean up Neutron resources also | ||||||
|  |         # super(Purge, self).take_action(parsed_args) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PurgeAPI(Purge): | ||||||
|  |     def __init__(self, app, app_args, gbp_client): | ||||||
|  |         self.gbp_client = gbp_client | ||||||
|  |         super(PurgeAPI, self).__init__(app, app_args) | ||||||
|  |  | ||||||
|  |     def get_client(self): | ||||||
|  |         return self.gbp_client | ||||||
| @@ -39,6 +39,7 @@ from neutronclient.i18n import _ | |||||||
| from neutronclient.version import __version__ | from neutronclient.version import __version__ | ||||||
|  |  | ||||||
| from gbpclient.gbp.v2_0 import groupbasedpolicy as gbp | from gbpclient.gbp.v2_0 import groupbasedpolicy as gbp | ||||||
|  | from gbpclient.gbp.v2_0 import purge | ||||||
| from gbpclient.gbp.v2_0 import servicechain | from gbpclient.gbp.v2_0 import servicechain | ||||||
|  |  | ||||||
| VERSION = '2.0' | VERSION = '2.0' | ||||||
| @@ -157,6 +158,7 @@ COMMAND_V2 = { | |||||||
|     'policy-rule-set-update': gbp.UpdatePolicyRuleSet, |     'policy-rule-set-update': gbp.UpdatePolicyRuleSet, | ||||||
|     'policy-rule-set-list': gbp.ListPolicyRuleSet, |     'policy-rule-set-list': gbp.ListPolicyRuleSet, | ||||||
|     'policy-rule-set-show': gbp.ShowPolicyRuleSet, |     'policy-rule-set-show': gbp.ShowPolicyRuleSet, | ||||||
|  |     'purge': purge.Purge, | ||||||
|     'service-profile-list': servicechain.ListServiceProfile, |     'service-profile-list': servicechain.ListServiceProfile, | ||||||
|     'service-profile-show': servicechain.ShowServiceProfile, |     'service-profile-show': servicechain.ShowServiceProfile, | ||||||
|     'service-profile-create': servicechain.CreateServiceProfile, |     'service-profile-create': servicechain.CreateServiceProfile, | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								gbpclient/tests/unit/test_cli20_purge.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								gbpclient/tests/unit/test_cli20_purge.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | #    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. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | from neutronclient.tests.unit import test_cli20_purge | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CLITestV20Purge(test_cli20_purge.CLITestV20Purge): | ||||||
|  |     def setUp(self): | ||||||
|  |         super(CLITestV20Purge, self).setUp() | ||||||
|  |         self.resource_types = ['policy_target', 'policy_target_group', | ||||||
|  |                                'l2_policy', 'l3_policy', 'external_policy', | ||||||
|  |                                'nat_pool', 'external_segment', | ||||||
|  |                                'policy_rule_set', 'policy_rule', | ||||||
|  |                                'policy_classifier', 'policy_action', | ||||||
|  |                                'network_service_policy', | ||||||
|  |                                'servicechain_instance', 'servicechain_spec', | ||||||
|  |                                'servicechain_node', 'service_profile'] | ||||||
| @@ -14,6 +14,7 @@ | |||||||
| import logging | import logging | ||||||
| import time | import time | ||||||
|  |  | ||||||
|  | from gbpclient.gbp.v2_0 import purge as gbpclient_purge | ||||||
| from neutronclient import client | from neutronclient import client | ||||||
| from neutronclient.common import exceptions | from neutronclient.common import exceptions | ||||||
| from neutronclient.common import serializer | from neutronclient.common import serializer | ||||||
| @@ -722,6 +723,10 @@ class Client(object): | |||||||
|         return self.delete(self.servicechain_instance_path % |         return self.delete(self.servicechain_instance_path % | ||||||
|                            (servicechain_instance)) |                            (servicechain_instance)) | ||||||
|  |  | ||||||
|  |     def purge(self, tenant_id): | ||||||
|  |         purge_obj = gbpclient_purge.PurgeAPI(None, None, self) | ||||||
|  |         purge_obj.take_action(tenant_id) | ||||||
|  |  | ||||||
|     def __init__(self, **kwargs): |     def __init__(self, **kwargs): | ||||||
|         """Initialize a new client for the GBP v2.0 API.""" |         """Initialize a new client for the GBP v2.0 API.""" | ||||||
|         super(Client, self).__init__() |         super(Client, self).__init__() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jenkins
					Jenkins