def handle_expansion(self):
        # If the network resource should not be output (they are hidden),
        # there is no need to generate subnet resource
        if self.hide_resource:
            return

        tosca_props = self._get_tosca_props(
            self.nodetemplate.get_properties_objects())

        subnet_props = {}

        ip_pool_start = None
        ip_pool_end = None

        for key, value in tosca_props.items():
            if key in self.SUBNET_PROPS:
                if key == 'start_ip':
                    ip_pool_start = value
                elif key == 'end_ip':
                    ip_pool_end = value
                elif key == 'dhcp_enabled':
                    subnet_props['enable_dhcp'] = value
                else:
                    subnet_props[key] = value

        if 'network_id' in tosca_props:
            subnet_props['network'] = tosca_props['network_id']
        else:
            subnet_props['network'] = '{ get_resource: %s }' % (self.name)

        # Handle allocation pools
        # Do this only if both start_ip and end_ip are provided
        # If one of them is missing throw an exception.
        if ip_pool_start and ip_pool_end:
            allocation_pool = {}
            allocation_pool['start'] = ip_pool_start
            allocation_pool['end'] = ip_pool_end
            allocation_pools = [allocation_pool]
            subnet_props['allocation_pools'] = allocation_pools
        elif ip_pool_start:
            raise InvalidPropertyValueError(what=_('start_ip'))
        elif ip_pool_end:
            raise InvalidPropertyValueError(what=_('end_ip'))

        subnet_resource_name = self.name + self.SUBNET_SUFFIX

        hot_resources = [
            HotResource(self.nodetemplate,
                        type='OS::Neutron::Subnet',
                        name=subnet_resource_name,
                        properties=subnet_props)
        ]
        return hot_resources
 def handle_properties(self):
     tosca_props = {}
     for prop in self.nodetemplate.get_properties_objects():
         if isinstance(prop.value, GetInput):
             tosca_props[prop.name] = {'get_param': prop.value.input_name}
         else:
             if prop.name == "size":
                 size_value = (ScalarUnit_Size(
                     prop.value).get_num_from_scalar_unit('GiB'))
                 if size_value == 0:
                     # OpenStack Heat expects size in GB
                     msg = _('Cinder Volume Size unit should be in GB.')
                     log.error(msg)
                     raise InvalidPropertyValueError(what=msg)
                 elif int(size_value) < size_value:
                     size_value = int(size_value) + 1
                     log.warning(
                         _("Cinder unit value should be in "
                           "multiples of GBs. so corrected "
                           " %(prop_val)s to %(size_value)s GB.") % {
                               'prop_val': prop.value,
                               'size_value': size_value
                           })
                 tosca_props[prop.name] = int(size_value)
             else:
                 tosca_props[prop.name] = prop.value
     self.properties = tosca_props
Beispiel #3
0
 def _validate_occurrences(self, occurrences):
     DataEntity.validate_datatype('list', occurrences)
     for value in occurrences:
         DataEntity.validate_datatype('integer', value)
     if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \
             or occurrences[1] == 0:
         ExceptionCollector.appendException(
             InvalidPropertyValueError(what=(occurrences)))
 def _get_monitoring_prop(self, trigger):
     sample = trigger.get('condition')
     prop = dict()
     prop["description"] = sample.get('constraint')
     prop["meter_name"] = trigger.get('meter_name')
     if sample.get('method') not in ALARM_STATISTIC:
         msg = _('method should be one of given statistics')
         log.error(msg)
         raise InvalidPropertyValueError(what=msg)
     prop["statistic"] = ALARM_STATISTIC[sample["method"]]
     prop["period"] = sample.get("period")
     prop["threshold"] = sample.get("threshold")
     prop["comparison_operator"] = sample.get('comparison_operator')
     prop['evaluation_periods'] = sample.get('evaluations')
     return prop
    def _validate_requirements(self):
        type_requires = self.type_definition.get_all_requirements()
        allowed_reqs = ["template"]
        if type_requires:
            for treq in type_requires:
                for key, value in treq.items():
                    allowed_reqs.append(key)
                    if isinstance(value, dict):
                        for key in value:
                            allowed_reqs.append(key)

        requires = self.requirements

        if requires:
            if not isinstance(requires, list):
                ExceptionCollector.appendException(
                    TypeMismatchError(what='"requirements" of template "%s"' %
                                      self.name,
                                      type='list'))
            else:
                for req in requires:
                    if not isinstance(req, dict):
                        ExceptionCollector.appendException(
                            TypeMismatchError(
                                what='a "requirement" in template "%s"' %
                                self.name,
                                type='dict'))
                        continue
                    if len(req) != 1:
                        what = 'requirement "%s" in template "%s"' % (
                            req, self.name)
                        ExceptionCollector.appendException(
                            InvalidPropertyValueError(what=what))
                        continue

                    for r1, value in req.items():
                        if isinstance(value, dict):
                            self._validate_requirements_keys(value)
                            self._validate_requirements_properties(value)
                            node_filter = value.get('node_filter')
                            if node_filter:
                                self._validate_nodefilter(node_filter)
                        elif not isinstance(value, str):
                            msg = 'bad value "%s" for requirement "%s" in template "%s"' % (
                                value, r1, self.name)
                            ExceptionCollector.appendException(
                                ValidationError(message=msg))
 def _get_monitoring_prop(self, trigger):
     sample = trigger.get('condition')
     prop = dict()
     prop["description"] = sample.get('constraint')
     prop["metric"] = trigger.get('metric')
     if sample.get('aggregation_method') not in ALARM_STATISTIC:
         msg = _('method should be one of given statistics')
         log.error(msg)
         raise InvalidPropertyValueError(what=msg)
     prop["aggregation_method"] = \
         ALARM_STATISTIC[sample["aggregation_method"]]
     prop["granularity"] = sample.get("granularity")
     prop["threshold"] = sample.get("threshold")
     prop["resource_type"] = sample.get("resource_type", "instance")
     prop["comparison_operator"] = sample.get('comparison_operator')
     prop['evaluation_periods'] = sample.get('evaluations')
     return prop
Beispiel #7
0
    def _load_import_template(self, import_name, import_uri_def):
        """Handle custom types defined in imported template files

        This method loads the custom type definitions referenced in "imports"
        section of the TOSCA YAML template by determining whether each import
        is specified via a file reference (by relative or absolute path) or a
        URL reference.

        Possibilities:
        +----------+--------+------------------------------+
        | template | import | comment                      |
        +----------+--------+------------------------------+
        | file     | file   | OK                           |
        | file     | URL    | OK                           |
        | preparsed| file   | file must be a full path     |
        | preparsed| URL    | OK                           |
        | URL      | file   | file must be a relative path |
        | URL      | URL    | OK                           |
        +----------+--------+------------------------------+
        """
        short_import_notation = False
        if isinstance(import_uri_def, dict):
            self._validate_import_keys(import_name, import_uri_def)
            file_name = import_uri_def.get(self.FILE)
            repository = import_uri_def.get(self.REPOSITORY)
            repos = self.repositories.keys()
            if repository is not None:
                if repository not in repos:
                    ExceptionCollector.appendException(
                        InvalidPropertyValueError(
                            what=_('Repository is not found in "%s"') % repos))
        else:
            file_name = import_uri_def
            repository = None
            short_import_notation = True

        if not file_name:
            msg = (_('A template file name is not provided with import '
                     'definition "%(import_name)s".') % {
                         'import_name': import_name
                     })
            log.error(msg)
            ExceptionCollector.appendException(ValidationError(message=msg))
            return None, None

        if toscaparser.utils.urlutils.UrlUtils.validate_url(file_name):
            return file_name, YAML_LOADER(file_name, False)
        elif not repository:
            import_template = None
            if self.path:
                if toscaparser.utils.urlutils.UrlUtils.validate_url(self.path):
                    if os.path.isabs(file_name):
                        msg = (_('Absolute file name "%(name)s" cannot be '
                                 'used in a URL-based input template '
                                 '"%(template)s".') % {
                                     'name': file_name,
                                     'template': self.path
                                 })
                        log.error(msg)
                        ExceptionCollector.appendException(ImportError(msg))
                        return None, None
                    import_template = toscaparser.utils.urlutils.UrlUtils.\
                        join_url(self.path, file_name)
                    a_file = False
                else:
                    a_file = True
                    main_a_file = os.path.isfile(self.path)

                    if main_a_file:
                        if os.path.isfile(file_name):
                            import_template = file_name
                        else:
                            full_path = os.path.join(
                                os.path.dirname(os.path.abspath(self.path)),
                                file_name)
                            if os.path.isfile(full_path):
                                import_template = full_path
                            else:
                                file_path = file_name.rpartition("/")
                                dir_path = os.path.dirname(
                                    os.path.abspath(self.path))
                                if file_path[0] != '' and dir_path.endswith(
                                        file_path[0]):
                                    import_template = dir_path + "/" +\
                                        file_path[2]
                                    if not os.path.isfile(import_template):
                                        msg = (_('"%(import_template)s" is '
                                                 'not a valid file') % {
                                                     'import_template':
                                                     import_template
                                                 })
                                        log.error(msg)
                                        ExceptionCollector.appendException
                                        (ValueError(msg))
            else:  # template is pre-parsed
                if os.path.isabs(file_name) and os.path.isfile(file_name):
                    a_file = True
                    import_template = file_name
                else:
                    msg = (_('Relative file name "%(name)s" cannot be used '
                             'in a pre-parsed input template.') % {
                                 'name': file_name
                             })
                    log.error(msg)
                    ExceptionCollector.appendException(ImportError(msg))
                    return None, None

            if not import_template:
                log.error(
                    _('Import "%(name)s" is not valid.') %
                    {'name': import_uri_def})
                ExceptionCollector.appendException(
                    ImportError(
                        _('Import "%s" is not valid.') % import_uri_def))
                return None, None
            return import_template, YAML_LOADER(import_template, a_file)

        if short_import_notation:
            log.error(_('Import "%(name)s" is not valid.') % import_uri_def)
            ExceptionCollector.appendException(
                ImportError(_('Import "%s" is not valid.') % import_uri_def))
            return None, None

        full_url = ""
        if repository:
            if self.repositories:
                for repo_name, repo_def in self.repositories.items():
                    if repo_name == repository:
                        # Remove leading, ending spaces and strip
                        # the last character if "/"
                        repo_url = ((repo_def['url']).strip()).rstrip("//")
                        full_url = repo_url + "/" + file_name

            if not full_url:
                msg = (_('referenced repository "%(n_uri)s" in import '
                         'definition "%(tpl)s" not found.') % {
                             'n_uri': repository,
                             'tpl': import_name
                         })
                log.error(msg)
                ExceptionCollector.appendException(ImportError(msg))
                return None, None

        if toscaparser.utils.urlutils.UrlUtils.validate_url(full_url):
            return full_url, YAML_LOADER(full_url, False)
        else:
            msg = (_('repository url "%(n_uri)s" is not valid in import '
                     'definition "%(tpl)s".') % {
                         'n_uri': repo_url,
                         'tpl': import_name
                     })
            log.error(msg)
            ExceptionCollector.appendException(ImportError(msg))