blob: fc51f3caacf54e6b5753889effa18853f6b719a3 [file] [log] [blame]
# Copyright (c) 2019 Intel Corp. All rights reserved.
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 logging
import os
import pprint
from ruamel import yaml # @UnresolvedImport
import six
from vnfsdk_pkgtools.packager import utils
LOG = logging.getLogger(__name__)
META_FILE = 'TOSCA-Metadata/TOSCA.meta'
META_FILE_VERSION_KEY = 'TOSCA-Meta-File-Version'
META_FILE_VERSION_VALUE = '1.0'
META_CSAR_VERSION_KEY = 'CSAR-Version'
META_CSAR_VERSION_VALUE = '1.1'
META_CREATED_BY_KEY = 'Created-By'
META_CREATED_BY_VALUE = 'ONAP VNFSDK pkgtools'
META_ENTRY_DEFINITIONS_KEY = 'Entry-Definitions'
BASE_META = {
META_FILE_VERSION_KEY: META_FILE_VERSION_VALUE,
META_CSAR_VERSION_KEY: META_CSAR_VERSION_VALUE,
}
class ToscaMeta(object):
META_ENTRY_MANIFEST_FILE_KEY = 'ETSI-Entry-Manifest'
META_ENTRY_HISTORY_FILE_KEY = 'ETSI-Entry-Change-Log'
META_ENTRY_TESTS_DIR_KEY = 'ETSI-Entry-Tests'
META_ENTRY_LICENSES_DIR_KEY = 'ETSI-Entry-Licenses'
META_ENTRY_CERT_FILE_KEY = 'ETSI-Entry-Certificate'
REQUIRED_KEYS = [ META_FILE_VERSION_KEY, META_CSAR_VERSION_KEY,
META_CREATED_BY_KEY, META_ENTRY_DEFINITIONS_KEY,
META_ENTRY_MANIFEST_FILE_KEY, META_ENTRY_HISTORY_FILE_KEY,
META_ENTRY_LICENSES_DIR_KEY,
]
OPTIONAL_KEYS = [META_ENTRY_TESTS_DIR_KEY, META_ENTRY_CERT_FILE_KEY]
def __init__(self, base_dir, entry, manifest=None, changelog=None,
licenses=None, tests=None, certificate=None,
meta_file_version=META_FILE_VERSION_VALUE,
meta_csar_version=META_CSAR_VERSION_VALUE,
meta_created_by=META_CREATED_BY_VALUE):
self.base_dir = base_dir
metadata = {}
metadata[META_FILE_VERSION_KEY] = str(meta_file_version)
metadata[META_CSAR_VERSION_KEY] = str(meta_csar_version)
metadata[META_CREATED_BY_KEY] = meta_created_by
metadata[META_ENTRY_DEFINITIONS_KEY] = entry
if manifest:
metadata[self.META_ENTRY_MANIFEST_FILE_KEY] = manifest
if changelog:
metadata[self.META_ENTRY_HISTORY_FILE_KEY] = changelog
if licenses:
metadata[self.META_ENTRY_LICENSES_DIR_KEY] = licenses
if tests:
metadata[self.META_ENTRY_TESTS_DIR_KEY] = tests
if certificate:
metadata[self.META_ENTRY_CERT_FILE_KEY] = certificate
self.metadata = self._validate(metadata)
def _validate(self, metadata):
for (key, value) in six.iteritems(BASE_META):
if metadata.get(key) != value:
raise ValueError('TOSCA.meta: {} must be {}'.format(key, value))
utils.check_file_dir(root=self.base_dir,
entry=metadata.get(META_ENTRY_DEFINITIONS_KEY),
msg='Please specify a valid entry point.',
check_dir=False)
entry_file = os.path.join(self.base_dir,
metadata.get(META_ENTRY_DEFINITIONS_KEY))
try:
with open(entry_file) as f:
v = yaml.safe_load(f)['tosca_definitions_version']
except:
raise ValueError('Entry file {} is not a valid tosca simple yaml file'.format(entry_file))
if metadata.get(self.META_ENTRY_MANIFEST_FILE_KEY):
utils.check_file_dir(root=self.base_dir,
entry=metadata[self.META_ENTRY_MANIFEST_FILE_KEY],
msg='Please specify a valid manifest file.',
check_dir=False)
if metadata.get(self.META_ENTRY_HISTORY_FILE_KEY):
utils.check_file_dir(root=self.base_dir,
entry=metadata[self.META_ENTRY_HISTORY_FILE_KEY],
msg='Please specify a valid change history file.',
check_dir=False)
if metadata.get(self.META_ENTRY_LICENSES_DIR_KEY):
utils.check_file_dir(root=self.base_dir,
entry=metadata[self.META_ENTRY_LICENSES_DIR_KEY],
msg='Please specify a valid license directory.',
check_dir=True)
if metadata.get(self.META_ENTRY_TESTS_DIR_KEY):
utils.check_file_dir(root=self.base_dir,
entry=metadata[self.META_ENTRY_TESTS_DIR_KEY],
msg='Please specify a valid test directory.',
check_dir=True)
if metadata.get(self.META_ENTRY_CERT_FILE_KEY):
utils.check_file_dir(root=self.base_dir,
entry=metadata[self.META_ENTRY_CERT_FILE_KEY],
msg='Please specify a valid certificate file.',
check_dir=False)
missing_keys = [key for key in self.REQUIRED_KEYS if key not in metadata]
if missing_keys:
raise ValueError('TOSCA.meta: missing keys: {}'.format(','.join(missing_keys)))
return metadata
def dump_as_string(self):
s = ""
for key in self.REQUIRED_KEYS + self.OPTIONAL_KEYS:
if self.metadata.get(key):
s += "{}: {}\n".format(key, self.metadata.get(key))
return s
@property
def created_by(self):
return self.metadata.get(META_CREATED_BY_KEY)
@property
def csar_version(self):
return self.metadata.get(META_CSAR_VERSION_KEY)
@property
def meta_file_version(self):
return self.metadata.get(META_FILE_VERSION_KEY)
@property
def entry_definitions(self):
return self.metadata.get(META_ENTRY_DEFINITIONS_KEY)
@property
def entry_manifest_file(self):
return self.metadata.get(self.META_ENTRY_MANIFEST_FILE_KEY)
@property
def entry_history_file(self):
return self.metadata.get(self.META_ENTRY_HISTORY_FILE_KEY)
@property
def entry_tests_dir(self):
return self.metadata.get(self.META_ENTRY_TESTS_DIR_KEY)
@property
def entry_licenses_dir(self):
return self.metadata.get(self.META_ENTRY_LICENSES_DIR_KEY)
@property
def entry_certificate_file(self):
return self.metadata.get(self.META_ENTRY_CERT_FILE_KEY)
class ToscaMeta241(ToscaMeta):
# SOL004 v2.4.1
META_ENTRY_MANIFEST_FILE_KEY = 'Entry-Manifest'
META_ENTRY_HISTORY_FILE_KEY = 'Entry-Change-Log'
META_ENTRY_TESTS_DIR_KEY = 'Entry-Tests'
META_ENTRY_LICENSES_DIR_KEY = 'Entry-Licenses'
META_ENTRY_CERT_FILE_KEY = 'Entry-Certificate'
REQUIRED_KEYS = [ META_FILE_VERSION_KEY, META_CSAR_VERSION_KEY,
META_CREATED_BY_KEY, META_ENTRY_DEFINITIONS_KEY,
]
OPTIONAL_KEYS = [ META_ENTRY_MANIFEST_FILE_KEY, META_ENTRY_HISTORY_FILE_KEY,
META_ENTRY_LICENSES_DIR_KEY, META_ENTRY_TESTS_DIR_KEY,
META_ENTRY_CERT_FILE_KEY,
]
class ToscaMeta261(ToscaMeta):
# SOL004 v2.6.1
pass
def create_from_file(base_dir):
csar_metafile = os.path.join(base_dir, META_FILE)
if not os.path.exists(csar_metafile):
raise ValueError('Metadata file {0} is missing from the CSAR'.format(csar_metafile))
LOG.debug('CSAR metadata file: {0}'.format(csar_metafile))
LOG.debug('Attempting to parse CSAR metadata YAML')
with open(csar_metafile) as f:
metadata = yaml.safe_load(f)
LOG.debug('CSAR metadata:\n{0}'.format(pprint.pformat(metadata)))
# By default we assume it's SOL004 2.4.1
cls = ToscaMeta241
for key in metadata.keys():
if key.startswith('ETSI-'):
cls = ToscaMeta261
break
return cls(base_dir,
entry=metadata.get(META_ENTRY_DEFINITIONS_KEY),
manifest=metadata.get(cls.META_ENTRY_MANIFEST_FILE_KEY),
changelog=metadata.get(cls.META_ENTRY_HISTORY_FILE_KEY),
licenses=metadata.get(cls.META_ENTRY_LICENSES_DIR_KEY),
tests=metadata.get(cls.META_ENTRY_TESTS_DIR_KEY),
certificate=metadata.get(cls.META_ENTRY_CERT_FILE_KEY),
meta_file_version=metadata.get(META_FILE_VERSION_KEY),
meta_csar_version=metadata.get(META_CSAR_VERSION_KEY),
meta_created_by=metadata.get(META_CREATED_BY_KEY))