text: # Copyright 2015 Intel Corporation..
  # All Rights Reserved.
  #
  #    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 abc
  
  from oslo_log import log as logging
  import six
  
  from tacker.api import extensions
  from tacker.api.v1 import attributes as attr
  from tacker.api.v1 import base
  from tacker.api.v1 import resource_helper
  from tacker.common import exceptions
  from tacker import manager
  from tacker.plugins.common import constants
  from tacker.services import service_base
  
  
  LOG = logging.getLogger(__name__)
  
  
  class MultipleMGMTDriversSpecified(exceptions.InvalidInput):
      message = _('More than one MGMT Driver per vnfd is not supported')
  
  
  class ServiceTypesNotSpecified(exceptions.InvalidInput):
      message = _('service types are not specified')
  
  
  class VNFDInUse(exceptions.InUse):
      message = _('VNFD %(vnfd_id)s is still in use')
  
  
  class VNFInUse(exceptions.InUse):
      message = _('VNF %(vnf_id)s is still in use')
  
  
  class InvalidMgmtDriver(exceptions.InvalidInput):
      message = _('Invalid Mgmt driver %(mgmt_driver_name)s.')
  
  
  class InvalidInfraDriver(exceptions.InvalidInput):
      message = _('VIM type %(vim_name)s is not supported as an infra driver')
  
  
  class InvalidServiceType(exceptions.InvalidInput):
      message = _('invalid service type %(service_type)s')
  
  
  class VNFCreateFailed(exceptions.TackerException):
      message = _('creating VNF based on %(vnfd_id)s failed')
  
  
  class VNFCreateWaitFailed(exceptions.TackerException):
      message = _('%(reason)s')
  
  
  class VNFScaleWaitFailed(exceptions.TackerException):
      message = _('%(reason)s')
  
  
  class VNFDeleteWaitFailed(exceptions.TackerException):
      message = _('%(reason)s')
  
  
  class VNFDeleteFailed(exceptions.TackerException):
      message = _('%(reason)s')
  
  
  class VNFDNotFound(exceptions.NotFound):
      message = _('VNFD %(vnfd_id)s could not be found')
  
  
  class ServiceTypeNotFound(exceptions.NotFound):
      message = _('service type %(service_type_id)s could not be found')
  
  
  class VNFNotFound(exceptions.NotFound):
      message = _('VNF %(vnf_id)s could not be found')
  
  
  class ParamYAMLNotWellFormed(exceptions.InvalidInput):
      message = _("Parameter YAML not well formed - %(error_msg_details)s")
  
  
  class ToscaParserFailed(exceptions.InvalidInput):
      message = _("tosca-parser failed: - %(error_msg_details)s")
  
  
  class HeatTranslatorFailed(exceptions.InvalidInput):
      message = _("heat-translator failed: - %(error_msg_details)s")
  
  
  class HeatClientException(exceptions.TackerException):
      message = _("%(msg)s")
  
  
  class UserDataFormatNotFound(exceptions.NotFound):
      message = _("user_data and/or user_data_format not provided")
  
  
  class IPAddrInvalidInput(exceptions.InvalidInput):
      message = _("IP Address input values should be in a list format")
  
  
  class HugePageSizeInvalidInput(exceptions.InvalidInput):
      message = _("Value specified for mem_page_size is invalid: "
                  "%(error_msg_details)s. The valid values are 'small', 'large',"
                  " 'any' or an integer value in MB")
  
  
  class CpuAllocationInvalidKeys(exceptions.InvalidInput):
      message = _("Invalid keys specified in VNFD - %(error_msg_details)s."
                  "Supported keys are: %(valid_keys)s")
  
  
  class NumaNodesInvalidKeys(exceptions.InvalidInput):
      message = _("Invalid keys specified in VNFD - %(error_msg_details)s."
                  "Supported keys are: %(valid_keys)s")
  
  
  class FilePathMissing(exceptions.InvalidInput):
      message = _("'file' attribute is missing for "
                  "tosca.artifacts.Deployment.Image.VM artifact type")
  
  
  class InfraDriverUnreachable(exceptions.ServiceUnavailable):
      message = _("Could not retrieve VNF resource IDs and"
                  " types. Please check %(service)s status.")
  
  
  class VNFInactive(exceptions.InvalidInput):
      message = _("VNF %(vnf_id)s is not in Active state: %(message)s")
  
  
  class MetadataNotMatched(exceptions.InvalidInput):
      message = _("Metadata for alarm policy is not matched")
  
  
  class InvalidResourceType(exceptions.InvalidInput):
      message = _("Resource type %(resource_type)s for alarm policy "
                  "is not supported")
  
  
  class InvalidSubstitutionMapping(exceptions.InvalidInput):
      message = _("Input for substitution mapping requirements are not"
                  " valid for %(requirement)s. They must be in the form"
                  " of list with two entries")
  
  
  class SMRequirementMissing(exceptions.InvalidInput):
      message = _("All the requirements for substitution_mappings are not"
                  " provided. Missing requirement for %(requirement)s")
  
  
  class InvalidParamsForSM(exceptions.InvalidInput):
      message = _("Please provide parameters for substitution mappings")
  
  
  class InvalidKubernetesScalingPolicyNumber(exceptions.InvalidInput):
      message = _("Please provide only one Scaling policy")
  
  
  class InvalidKubernetesNetworkNumber(exceptions.InvalidInput):
      message = _("Please provide one network for all vdus")
  
  
  class InvalidKubernetesInputParameter(exceptions.InvalidInput):
      message = _("Found unsupported keys for %(found_keys)s ")
  
  
  def _validate_service_type_list(data, valid_values=None):
      if not isinstance(data, list):
          msg = _("Invalid data format for service list: '%s'") % data
          LOG.debug(msg)
          return msg
      if not data:
          msg = _("Empty list is not allowed for service list. '%s'") % data
          LOG.debug(msg)
          return msg
      key_specs = {
          'service_type': {
              'type:string': None,
          }
      }
      for service in data:
          msg = attr._validate_dict(service, key_specs)
          if msg:
              LOG.debug(msg)
              return msg
  
  
  attr.validators['type:service_type_list'] = _validate_service_type_list
  
  NAME_MAX_LEN = 255
  
  RESOURCE_ATTRIBUTE_MAP = {
  
      'vnfds': {
          'id': {
              'allow_post': False,
              'allow_put': False,
              'validate': {'type:uuid': None},
              'is_visible': True,
              'primary_key': True,
          },
          'tenant_id': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:string': None},
              'required_by_policy': True,
              'is_visible': True,
          },
          'name': {
              'allow_post': True,
              'allow_put': True,
              'validate': {'type:string': NAME_MAX_LEN},
              'is_visible': True,
          },
          'description': {
              'allow_post': True,
              'allow_put': True,
              'validate': {'type:string': None},
              'is_visible': True,
              'default': '',
          },
          'service_types': {
              'allow_post': True,
              'allow_put': False,
              'convert_to': attr.convert_to_list,
              'validate': {'type:service_type_list': None},
              'is_visible': True,
              'default': attr.ATTR_NOT_SPECIFIED,
          },
          'attributes': {
              'allow_post': True,
              'allow_put': False,
              'convert_to': attr.convert_none_to_empty_dict,
              'validate': {'type:dict_or_nodata': None},
              'is_visible': True,
              'default': None,
          },
          'created_at': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'updated_at': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'template_source': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
              'default': 'onboarded'
          },
      },
  
      'vnfs': {
          'id': {
              'allow_post': False,
              'allow_put': False,
              'validate': {'type:uuid': None},
              'is_visible': True,
              'primary_key': True
          },
          'tenant_id': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:string': None},
              'required_by_policy': True,
              'is_visible': True
          },
          'vnfd_id': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:uuid': None},
              'is_visible': True,
              'default': None
          },
          'vim_id': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:string': None},
              'is_visible': True,
              'default': '',
          },
          'name': {
              'allow_post': True,
              'allow_put': True,
              'validate': {'type:string': NAME_MAX_LEN},
              'is_visible': True,
          },
          'description': {
              'allow_post': True,
              'allow_put': True,
              'validate': {'type:string': None},
              'is_visible': True,
              'default': '',
          },
          'instance_id': {
              'allow_post': False,
              'allow_put': False,
              'validate': {'type:string': None},
              'is_visible': True,
          },
          'mgmt_url': {
              'allow_post': False,
              'allow_put': False,
              'validate': {'type:string': None},
              'is_visible': True,
          },
          'attributes': {
              'allow_post': True,
              'allow_put': True,
              'validate': {'type:dict_or_none': None},
              'is_visible': True,
              'default': {},
          },
          'placement_attr': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:dict_or_none': None},
              'is_visible': True,
              'default': {},
          },
          'status': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'error_reason': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'created_at': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'updated_at': {
              'allow_post': False,
              'allow_put': False,
              'is_visible': True,
          },
          'vnfd_template': {
              'allow_post': True,
              'allow_put': False,
              'validate': {'type:dict_or_none': None},
              'is_visible': True,
              'default': None,
          },
      },
  }
  
  
  SUB_RESOURCE_ATTRIBUTE_MAP = {
      'actions': {
          'parent': {
              'collection_name': 'vnfs',
              'member_name': 'vnf'
          },
          'members': {
              'scale': {
                  'parameters': {
                      'policy': {
                          'allow_post': True,
                          'allow_put': False,
                          'is_visible': True,
                          'validate': {'type:string': None}
                      },
                      'type': {
                          'allow_post': True,
                          'allow_put': False,
                          'is_visible': True,
                          'validate': {'type:string': None}
                      },
                      'tenant_id': {
                          'allow_post': True,
                          'allow_put': False,
                          'validate': {'type:string': None},
                          'required_by_policy': False,
                          'is_visible': False
                      },
                  }
              },
          }
      },
      'triggers': {
          'parent': {
              'collection_name': 'vnfs',
              'member_name': 'vnf'
          },
          'members': {
              'trigger': {
                  'parameters': {
                      'policy_name': {
                          'allow_post': True,
                          'allow_put': False,
                          'is_visible': True,
                          'validate': {'type:string': None}
                      },
                      'action_name': {
                          'allow_post': True,
                          'allow_put': False,
                          'is_visible': True,
                          'validate': {'type:string': None}
                      },
                      'params': {
                          'allow_post': True,
                          'allow_put': False,
                          'is_visible': True,
                          'validate': {'type:dict_or_none': None}
                      },
                      'tenant_id': {
                          'allow_post': True,
                          'allow_put': False,
                          'validate': {'type:string': None},
                          'required_by_policy': False,
                          'is_visible': False
                      }
                  }
              },
          }
      },
      'resources': {
          'parent': {
              'collection_name': 'vnfs',
              'member_name': 'vnf'
          },
          'members': {
              'resource': {
                  'parameters': {
                      'name': {
                          'allow_post': False,
                          'allow_put': False,
                          'is_visible': True,
                      },
                      'type': {
                          'allow_post': False,
                          'allow_put': False,
                          'is_visible': True,
                      },
                      'id': {
                          'allow_post': False,
                          'allow_put': False,
                          'is_visible': True,
                      },
                  }
              }
          }
      }
  }
  
  
  class Vnfm(extensions.ExtensionDescriptor):
      @classmethod
      def get_name(cls):
          return 'VNF Manager'
  
      @classmethod
      def get_alias(cls):
          return 'VNFM'
  
      @classmethod
      def get_description(cls):
          return "Extension for VNF Manager"
  
      @classmethod
      def get_namespace(cls):
          return 'http://wiki.openstack.org/Tacker'
  
      @classmethod
      def get_updated(cls):
          return "2013-11-19T10:00:00-00:00"
  
      @classmethod
      def get_resources(cls):
          special_mappings = {}
          plural_mappings = resource_helper.build_plural_mappings(
              special_mappings, RESOURCE_ATTRIBUTE_MAP)
          plural_mappings['service_types'] = 'service_type'
          attr.PLURALS.update(plural_mappings)
          resources = resource_helper.build_resource_info(
              plural_mappings, RESOURCE_ATTRIBUTE_MAP, constants.VNFM,
              translate_name=True)
          plugin = manager.TackerManager.get_service_plugins()[
              constants.VNFM]
          for collection_name in SUB_RESOURCE_ATTRIBUTE_MAP:
              parent = SUB_RESOURCE_ATTRIBUTE_MAP[collection_name]['parent']
  
              for resource_name in SUB_RESOURCE_ATTRIBUTE_MAP[
                      collection_name]['members']:
                  params = SUB_RESOURCE_ATTRIBUTE_MAP[
                      collection_name]['members'][resource_name]['parameters']
  
                  controller = base.create_resource(collection_name,
                                                    resource_name,
                                                    plugin, params,
                                                    allow_bulk=True,
                                                    parent=parent)
  
                  resource = extensions.ResourceExtension(
                      collection_name,
                      controller, parent,
                      attr_map=params)
                  resources.append(resource)
          return resources
  
      @classmethod
      def get_plugin_interface(cls):
          return VNFMPluginBase
  
      def update_attributes_map(self, attributes):
          super(Vnfm, self).update_attributes_map(
              attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)
  
      def get_extended_resources(self, version):
          version_map = {'1.0': RESOURCE_ATTRIBUTE_MAP}
          return version_map.get(version, {})
  
  
  @six.add_metaclass(abc.ABCMeta)
  class VNFMPluginBase(service_base.NFVPluginBase):
      def get_plugin_name(self):
          return constants.VNFM
  
      def get_plugin_type(self):
          return constants.VNFM
  
      def get_plugin_description(self):
          return 'Tacker VNF Manager plugin'
  
      @abc.abstractmethod
      def create_vnfd(self, context, vnfd):
          pass
  
      @abc.abstractmethod
      def delete_vnfd(self, context, vnfd_id):
          pass
  
      @abc.abstractmethod
      def get_vnfd(self, context, vnfd_id, fields=None):
          pass
  
      @abc.abstractmethod
      def get_vnfds(self, context, filters=None, fields=None):
          pass
  
      @abc.abstractmethod
      def get_vnfs(self, context, filters=None, fields=None):
          pass
  
      @abc.abstractmethod
      def get_vnf(self, context, vnf_id, fields=None):
          pass
  
      @abc.abstractmethod
      def get_vnf_resources(self, context, vnf_id, fields=None, filters=None):
          pass
  
      @abc.abstractmethod
      def create_vnf(self, context, vnf):
          pass
  
      @abc.abstractmethod
      def update_vnf(
              self, context, vnf_id, vnf):
          pass
  
      @abc.abstractmethod
      def delete_vnf(self, context, vnf_id):
          pass
  
      @abc.abstractmethod
      def create_vnf_scale(
              self, context, vnf_id, scale):
          pass
  
      @abc.abstractmethod
      def create_vnf_trigger(
              self, context, vnf_id, trigger):
          pass
  