# # 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 heat.common import exception from heat.engine import resource from heat.engine import scheduler from oslo_log import log as logging LOG = logging.getLogger(__name__) class GBPResource(resource.Resource): default_client_name = 'grouppolicy' def grouppolicy(self): return self.client('grouppolicy') def validate(self): '''Validate any of the provided params''' res = super(GBPResource, self).validate() if res: return res return self.validate_properties(self.properties) @staticmethod def validate_properties(properties): '''Validates update parameters. Validates to ensure nothing in value_specs overwrites any key that exists in the schema. Also ensures that shared and tenant_id is not specified in value_specs. ''' if 'value_specs' in properties.keys(): vs = properties.get('value_specs') banned_keys = set(['shared', 'tenant_id']).union( properties.keys()) for k in banned_keys.intersection(vs.keys()): return '%s not allowed in value_specs' % k @staticmethod def _validate_depr_property_required(properties, prop_key, depr_prop_key): prop_value = properties.get(prop_key) depr_prop_value = properties.get(depr_prop_key) if prop_value and depr_prop_value: raise exception.ResourcePropertyConflict(prop_key, depr_prop_key) if not prop_value and not depr_prop_value: msg = _('Either %(prop_key)s or %(depr_prop_key)s' ' should be specified.' ) % {'prop_key': prop_key, 'depr_prop_key': depr_prop_key} raise exception.StackValidationFailed(message=msg) @staticmethod def prepare_properties(properties, name): '''Prepare allowed property keys. Prepares the property values so that they can be passed directly to the Neutron create call. Removes None values and value_specs, merges value_specs with the main values. ''' props = dict((k, v) for k, v in properties.items() if v is not None and k != 'value_specs') if 'name' in properties.keys(): props.setdefault('name', name) if 'value_specs' in properties.keys(): props.update(properties.get('value_specs')) return props def prepare_update_properties(self, definition): '''Prepare allowed keys for property update. Prepares the property values so that they can be passed directly to the Neutron update call. Removes any properties which are not update_allowed, then processes as for prepare_properties. ''' p = definition.properties(self.properties_schema, self.context) update_props = dict((k, v) for k, v in p.items() if p.props.get(k).schema.update_allowed) props = self.prepare_properties( update_props, self.physical_resource_name()) return props @staticmethod def is_built(attributes): status = attributes['status'] if status == 'BUILD': return False if status in ('ACTIVE', 'DOWN'): return True elif status == 'ERROR': raise resource.ResourceInError( resource_status=status) else: raise resource.ResourceUnknownStatus( resource_status=status, result=_('Resource is not built')) def _resolve_attribute(self, name): try: attributes = self._show_resource() except Exception as ex: self.client_plugin().ignore_not_found(ex) return None if name == 'show': return attributes return attributes[name] def _confirm_delete(self): while True: try: yield self._show_resource() except Exception as ex: self.client_plugin().ignore_not_found(ex) return def _delete_task(self): delete_task = scheduler.TaskRunner(self._confirm_delete) delete_task.start() return delete_task def check_delete_complete(self, delete_task): # if the resource was already deleted, delete_task will be None return delete_task is None or delete_task.step()