diff options
author | Gao Weitao <victor.gao@huawei.com> | 2019-03-01 08:59:12 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-03-01 08:59:12 +0000 |
commit | 9b3ecdb005f87e2052e1f49c3c37211a3d3536af (patch) | |
tree | dfde5d3e331079cc3392cff743a76f36f7c9e82d /csarvalidation/src | |
parent | 3aafe6efed121e7f84c98470a5999c41c8e00427 (diff) | |
parent | 7f29a3ad89ca8ec1ea7cd20b5b28475854ea0670 (diff) |
Merge "CVC TOSCA CSAR Validation Test cases"
Diffstat (limited to 'csarvalidation/src')
41 files changed, 3914 insertions, 9 deletions
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java new file mode 100644 index 0000000..d14c14b --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java @@ -0,0 +1,1330 @@ +/** + * Copyright 2019 Huawei Technologies Co., Ltd. + * + * 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. + */ +package org.onap.cvc.csar; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Verify the CSAR package by following the SOL004 specifications and ONAP VNFREQS for TOSCA. + * + * @author Kanagaraj Manickam kanagaraj.manickam@huawei.com + * + */ +public class CSARArchive { + private static final Logger LOG = LoggerFactory.getLogger(CSARArchive.class); + + public static final String SOL0004_2_4_1 = "V2.4.1 (2018-02)"; + + public String getSOL004Version() { + return SOL0004_2_4_1; + } + + public Path tempDir; + + public static final String TEMP_DIR = "."; + + public static final String TOSCA_Metadata = "TOSCA-Metadata"; + + public static final String TOSCA_Metadata__TOSCA_Meta = "TOSCA.meta"; + + public static final String TOSCA_Metadata__TOSCA_Meta__TOSCA_Meta_File_Version = "TOSCA-Meta-File-Version"; + + public static final String TOSCA_Metadata__TOSCA_Meta__CSAR_Version = "CSAR-Version"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Created_by = "Created-by"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Definitions = "Entry-Definitions"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Manifest = "Entry-Manifest"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Change_Log = "Entry-Change-Log"; + + public static final String Change_Logs_Txt = "Change-Logs.txt"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Tests = "Entry-Tests"; + + public static final String Tests = "Tests"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Licenses = "Entry-Licenses"; + + public static final String Licenses = "Licenses"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Entry_Certificate = "Entry-Certificate"; + + public static final String Certificate = "Certificate"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Name = "Name"; + + public static final String TOSCA_Metadata__TOSCA_Meta__Content_Type = "Content-Type"; + + public static final String Entry_Definition__tosca_definitions_version = "tosca_definitions_version"; + + public static final String Entry_Definition__tosca_definitions_version__simple_1_0 = "tosca_simple_yaml_1_0"; + public static final String Entry_Definition__tosca_definitions_version__simple_1_1 = "tosca_simple_yaml_1_1"; + + public static final String[] Entry_Definition__tosca_definitions_versions = new String[] { + Entry_Definition__tosca_definitions_version__simple_1_0, + Entry_Definition__tosca_definitions_version__simple_1_1 + }; + public static final String Entry_Definition__metadata = "metadata"; + + public static final String Entry_Definition__template_name = "template_name"; + + public static final String Entry_Definition__template_author = "template_author"; + + public static final String Entry_Definition__template_version = "template_version"; + + public static final String Entry_Manifest__metadata = "metadata"; + + public static final String Entry_Manifest__metadata__vnf_provider_id = "vnf_provider_id"; + + public static final String Entry_Manifest__metadata__vnf_product_name = "vnf_product_name"; + + public static final String Entry_Manifest__metadata__vnf_release_data_time = "vnf_release_data_time"; + + public static final String Entry_Manifest__metadata__vnf_package_version = "vnf_package_version"; + + public static final String Entry_Manifest__non_mano_artifact_sets = "non_mano_artifact_sets"; + + public static final String CSAR_Archive = "CSAR Archive"; + + public enum Mode { + WITH_TOSCA_META_DIR, + WITHOUT_TOSCA_META_DIR + } + + public static class CSARError{ + + public CSARError(String code) { + this.code = code; + } + + private String code; + + private String subCode; + + protected String message = ""; + + protected String file = null; + + protected int lineNumber = -1; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + public int getLineNumber() { + return lineNumber; + } + + public void setLineNumber(int lineNumber) { + this.lineNumber = lineNumber; + } + + public String toString() { + try { + return new ObjectMapper().writeValueAsString(this); + } catch (JsonProcessingException e) { + //never occurs + return "{}"; + } + } + + public String getSubCode() { + return subCode; + } + + public void setSubCode(String subCode) { + this.subCode = subCode; + } + + public String getErrorCode() { + if (this.getSubCode() != null) { + return this.getSubCode(); + } + + return this.getCode(); + } + } + + public static class CSARErrorInvalidEntry extends CSARError { + public CSARErrorInvalidEntry(String entry, String file, int lineNo, String message) { + super("0x1000"); + this.message = "Invalid. Entry [" + entry + "]"; + if (message != null) { + this.message += ". " + message; + } + this.file = file; + this.lineNumber = lineNo; + } + } + + public static class CSARErrorInvalidEntryValue extends CSARError { + public CSARErrorInvalidEntryValue(String entry, String file, int lineNo, String message, String validValues) { + super("0x1001"); + this.message = "Invalid value. Entry [" + entry + "]"; + if (validValues != null) { + this.message += ". Valid values are [" + validValues + "]"; + } + + if (message != null) { + this.message += ". " + message; + } + + this.file = file; + this.lineNumber = lineNo; + } + } + + public static class CSARErrorEntryMissing extends CSARError { + public CSARErrorEntryMissing(String entry, String file, int lineNo, String message) { + super("0x1002"); + this.message = "Missing. Entry [" + entry + "]"; + if (message != null) { + this.message += ". " + message; + } + this.file = file; + this.lineNumber = lineNo; + } + } + + + public static class CSARErrorConflicts extends CSARError { + public CSARErrorConflicts(String entry, String file, int lineNo, String message, String conflicts) { + super("0x1003"); + this.message = "Conflicts. Entry [" + entry + "]"; + if (conflicts != null) { + this.message += ". Conflicting entries [" + conflicts + "]"; + } + if (message != null) { + this.message += ". " + message; + } + + this.lineNumber = lineNo; + this.file = file; + //this.message = "More than one file exists in the archive root for " + fileName + ", It should be only one. Files: " + files; + } + } + + public static class CSARErrorMismatch extends CSARError { + public CSARErrorMismatch(String entry, String file, int lineNo, String message, String expected, String acutal) { + super("0x1004"); + this.message = "Mismatch. Entry [" + entry + "]. expected: [" + expected + "] actual: ["+ acutal + "]"; + if (message != null) { + this.message += ". " + message; + } + this.file = file; + this.lineNumber = lineNo; + } + } + + public static class CSARErrorIgnored extends CSARError { + public CSARErrorIgnored(String entry, String file, int lineNo, String message) { + super("0x1005"); + this.message = "Ignored. Entry [" + entry + "]"; + if (message != null) { + this.message += ". " + message; + } + + this.file = file; + this.lineNumber = lineNo; + } + } + + public static class CSARErrorWarning extends CSARError { + public CSARErrorWarning(String entry, String file, int lineNo, String message) { + super("0x1006"); + this.file = file; + this.message = "Warning. Entry [" + entry + "]"; + if (message != null) { + this.message += ". " + message; + } + + this.file = file; + this.lineNumber = lineNo; + } + } + + public static class CSARErrorUnknown extends CSARError { + + public CSARErrorUnknown(String message) { + super("0x1007"); + this.message = message; + } + } + + + //Specific errors + public static class CSARErrorEntryMissingToscaDefinitionVersion extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaDefinitionVersion(String definitionYaml) { + super(Entry_Definition__tosca_definitions_version, + definitionYaml, + -1, + null); + this.setSubCode("0x001"); + } + } + + public static class CSARErrorInvalidEntryValueToscaDefinitionVersion extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueToscaDefinitionVersion(String definitionYaml) { + super(Entry_Definition__tosca_definitions_version, + definitionYaml, + -1, + null, + Entry_Definition__tosca_definitions_version__simple_1_1); + + this.setSubCode("0x0002"); + } + } + + //In non TOSCA-Meta mode, this is mandatory + public static class CSARErrorEntryMissingToscaDefinitionMetadataTemplateAuthor extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaDefinitionMetadataTemplateAuthor(String definitionYaml) { + super(Entry_Definition__template_author, + definitionYaml, + -1, + null); + + this.setSubCode("0x0003"); + } + } + + //In non TOSCA-Meta mode, this is mandatory + public static class CSARErrorEntryMissingToscaDefinitionMetadataTemplateName extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaDefinitionMetadataTemplateName(String definitionYaml) { + super(Entry_Definition__template_name, + definitionYaml, + -1, + null); + + this.setSubCode("0x0004"); + } + } + + //In non TOSCA-Meta mode, this is mandatory + public static class CSARErrorEntryMissingToscaDefinitionMetadataTemplateVersion extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaDefinitionMetadataTemplateVersion(String definitionYaml) { + super(Entry_Definition__template_version, + definitionYaml, + -1, + null); + + this.setSubCode("0x0005"); + } + } + + public static class CSARErrorInvalidEntryValueToscaDefinitionNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueToscaDefinitionNotFound(String definitionYaml, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Definitions, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + definitionYaml + " does not exist", + null); + + this.setSubCode("0x0006"); + } + } + + public static class CSARErrorInvalidEntryValueManifestNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueManifestNotFound(String manifest, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Manifest, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + manifest + " does not exist", + null); + + this.setSubCode("0x0007"); + } + } + + public static class CSARErrorInvalidEntryValueLogsNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueLogsNotFound(String logs, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Change_Log, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + logs + " does not exist", + null); + + this.setSubCode("0x0008"); + } + } + + public static class CSARErrorInvalidEntryValueTestsNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueTestsNotFound(String tests, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Tests, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + tests + " folder does not exist", + null); + + this.setSubCode("0x0009"); + } + } + + public static class CSARErrorInvalidEntryValueLicenseNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueLicenseNotFound(String license, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Licenses, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + license + " does not exist", + null); + + this.setSubCode("0x000a"); + } + } + + public static class CSARErrorInvalidEntryValueCertificatesNotFound extends CSARErrorInvalidEntryValue { + public CSARErrorInvalidEntryValueCertificatesNotFound(String certificate, int lineNo) { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Certificate, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + certificate + " does not exist", + null); + + this.setSubCode("0x000b"); + } + } + + public static class CSARErrorEntryMissingToscaMetaFileVersion extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaMetaFileVersion() { + super(TOSCA_Metadata__TOSCA_Meta__TOSCA_Meta_File_Version, + TOSCA_Metadata__TOSCA_Meta, + -1, + null); + + this.setSubCode("0x000c"); + } + } + + public static class CSARErrorEntryMissingToscaMetaDefinition extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaMetaDefinition() { + super(TOSCA_Metadata__TOSCA_Meta__Entry_Definitions, + TOSCA_Metadata__TOSCA_Meta, + -1, + null); + + this.setSubCode("0x000d"); + } + } + + public static class CSARErrorEntryMissingToscaMetaCSARVersion extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaMetaCSARVersion() { + super(TOSCA_Metadata__TOSCA_Meta__CSAR_Version, + TOSCA_Metadata__TOSCA_Meta, + -1, + null); + + this.setSubCode("0x000e"); + } + } + + public static class CSARErrorEntryMissingToscaMetaCreatedBy extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaMetaCreatedBy() { + super(TOSCA_Metadata__TOSCA_Meta__Created_by, + TOSCA_Metadata__TOSCA_Meta, + -1, + null); + + this.setSubCode("0x000f"); + } + } + + public static class CSARErrorEntryMissingToscaDefinitionNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingToscaDefinitionNotFound() { + super("Definition YAML", + CSAR_Archive, + -1, + null); + + this.setSubCode("0x0010"); + } + } + + public static class CSARErrorConflictsMultipleDefinitionYamls extends CSARErrorConflicts { + public CSARErrorConflictsMultipleDefinitionYamls(String fileNames) { + super("Definition YAML", + CSAR_Archive, + -1, + "Only one definition YAML should be provided at the root of the archive", + fileNames); + + this.setSubCode("0x0011"); + } + } + + + public static class CSARErrorConflictsMultipleManifests extends CSARErrorConflicts { + public CSARErrorConflictsMultipleManifests(String fileNames) { + super("Manifest MF", + CSAR_Archive, + -1, + "Only one manifest MF file should be provided at the root of the archive", + fileNames); + + this.setSubCode("0x0012"); + } + } + + public static class CSARErrorMismatchDefinitionYamlVsManifestMf extends CSARErrorMismatch { + public CSARErrorMismatchDefinitionYamlVsManifestMf(String definitionYaml, String manifest) { + super("Manifest MF", + CSAR_Archive, + -1, + "Manifest file name should match the definition YAML name", + definitionYaml + ".mf", //fix the name part + manifest); + + this.setSubCode("0x0013"); + } + } + + public static class CSARErrorConflictsMultipleCertificates extends CSARErrorConflicts { + public CSARErrorConflictsMultipleCertificates(String fileNames) { + super("Certificate CERT", + CSAR_Archive, + -1, + "Only one certificates file should be provided at the root of the archive", + fileNames); + + this.setSubCode("0x0014"); + } + } + + public static class CSARErrorMismatchDefinitionYamlVsCertificateCert extends CSARErrorMismatch { + public CSARErrorMismatchDefinitionYamlVsCertificateCert(String definitionYaml, String certificate) { + super("Certificate CERT", + CSAR_Archive, + -1, + "certificate file name should match the definition YAML name", + definitionYaml + ".cert", //fix the name part + certificate); + + this.setSubCode("0x0015"); + } + } + + /** + * Holds the CSAR meta data values in both Modes + * + */ + public static class TOSCAMeta { + private Mode mode; + + private String metaDataFileVersion; + + private String csarVersion; + + private String companyName; + + private String entryDefinitionYaml; + + private String entryManifestMf; + + private String entryChangeLog; + + private String entryTest; + + private String entryLicense; + + private String entryCertificate; + + public String getEntryCertificate() { + return entryCertificate; + } + + + public void setEntryCertificate(String entryCertificate) { + this.entryCertificate = entryCertificate; + } + + + public Mode getMode() { + return mode; + } + + + public void setMode(Mode mode) { + this.mode = mode; + } + + + public String getMetaDataFileVersion() { + return metaDataFileVersion; + } + + + public void setMetaDataFileVersion(String metaDataFileVersion) { + this.metaDataFileVersion = metaDataFileVersion; + } + + + public String getCsarVersion() { + return csarVersion; + } + + + public void setCsarVersion(String csarVersion) { + this.csarVersion = csarVersion; + } + + + public String getCompanyName() { + return companyName; + } + + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + + public String getEntryDefinitionYaml() { + return entryDefinitionYaml; + } + + + public void setEntryDefinitionYaml(String entryDefinitionYaml) { + this.entryDefinitionYaml = entryDefinitionYaml; + } + + + public String getEntryManifestMf() { + return entryManifestMf; + } + + + public void setEntryManifestMf(String entryManifestMf) { + this.entryManifestMf = entryManifestMf; + } + + + public String getEntryChangeLog() { + return entryChangeLog; + } + + + public void setEntryChangeLog(String entryChangeLog) { + this.entryChangeLog = entryChangeLog; + } + + + public String getEntryTest() { + return entryTest; + } + + + public void setEntryTest(String entryTest) { + this.entryTest = entryTest; + } + + + public String getEntryLicense() { + return entryLicense; + } + + + public void setEntryLicense(String entryLicense) { + this.entryLicense = entryLicense; + } + } + + public static class Definition { + private String toscaDefinitionVersion; + + public String getToscaDefinitionVersion() { + return toscaDefinitionVersion; + } + + public void setToscaDefinitionVersion(String toscaDefinitionVersion) { + this.toscaDefinitionVersion = toscaDefinitionVersion; + } + + public static class Metadata { + private String tempalteName; + + private String templateAuthor; + + private String templateVersion; + + public String getTempalteName() { + return tempalteName; + } + + public void setTempalteName(String tempalteName) { + this.tempalteName = tempalteName; + } + + public String getTemplateAuthor() { + return templateAuthor; + } + + public void setTemplateAuthor(String templateAuthor) { + this.templateAuthor = templateAuthor; + } + + public String getTemplateVersion() { + return templateVersion; + } + + public void setTemplateVersion(String templateVersion) { + this.templateVersion = templateVersion; + } + } + + private Definition.Metadata metadata = new Metadata(); + + public Definition.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(Definition.Metadata metadata) { + this.metadata = metadata; + } + } + + public static class Manifest{ + public static class Metadata { + private String providerId; + + private String productName; + + private String releaseDateTime; //IETF RFC 3339 + + private String packageVersion; + + public String getProviderId() { + return providerId; + } + + public void setProviderId(String providerId) { + this.providerId = providerId; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public String getReleaseDateTime() { + return releaseDateTime; + } + + public void setReleaseDateTime(String releaseDateTime) { + this.releaseDateTime = releaseDateTime; + } + + public String getPackageVersion() { + return packageVersion; + } + + public void setPackageVersion(String packageVersion) { + this.packageVersion = packageVersion; + } + } + + private Manifest.Metadata metadata = new Metadata(); + + private Map<String, Map<String, String>> nonMano = new HashMap<>(); + + public Manifest.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(Manifest.Metadata metadata) { + this.metadata = metadata; + } + + public Map<String, Map<String, String>> getNonMano() { + return nonMano; + } + + public void setNonMano(Map<String, Map<String, String>> nonMano) { + this.nonMano = nonMano; + } + } + + private TOSCAMeta toscaMeta = new TOSCAMeta(); + + private Definition definition = new Definition(); + + private Manifest manifest = new Manifest(); + + private File toscaMetaFile; + + private File definitionYamlFile; + + private File manifestMfFile; + + private File changeLogTxtFile; + + private File testsFolder; + + private File certificatesFile; + + private File licensesFolder; + + private List<CSARError> errors = new ArrayList<>(); + + public TOSCAMeta getToscaMeta() { + return toscaMeta; + } + + public Definition getDefinition() { + return definition; + } + + public Manifest getManifest() { + return manifest; + } + + public File getToscaMetaFile() { + return toscaMetaFile; + } + + public File getDefinitionYamlFile() { + return definitionYamlFile; + } + + public File getManifestMfFile() { + return manifestMfFile; + } + + public File getChangeLogTxtFile() { + return changeLogTxtFile; + } + + public File getTestsFolder() { + return testsFolder; + } + + public File getCertificatesFile() { + return certificatesFile; + } + + public File getLicensesFolder() { + return licensesFolder; + } + + public List<CSARError> getErrors() { + return errors; + } + + private void unzip(String csarPath) throws IOException { + File csarFile = new File(csarPath); + + if (!csarFile.exists()) { + throw new RuntimeException(csarPath + " does not exist"); + } + + ZipInputStream csar = new ZipInputStream(new BufferedInputStream(new FileInputStream(csarFile))); + + ZipEntry entry; + byte[] buffer = new byte[2048]; + while ((entry = csar.getNextEntry()) != null) { + + File filePath = new File(this.tempDir + File.separator + entry.getName()); + + if (!filePath.getParentFile().isDirectory()) { + filePath.getParentFile().delete(); + } + filePath.getParentFile().mkdirs(); + + try (FileOutputStream fos = new FileOutputStream(filePath); + BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length)) { + + int len; + while ((len = csar.read(buffer)) > 0) { + bos.write(buffer, 0, len); + } + } + } + } + + public String getVendorName() { + if (this.toscaMeta.getMode().equals(Mode.WITH_TOSCA_META_DIR)) { + return this.toscaMeta.getCompanyName(); + } else { + return this.definition.getMetadata().getTemplateAuthor(); + } + } + + public String getVersion() { + if (this.toscaMeta.getMode().equals(Mode.WITH_TOSCA_META_DIR)) { + return this.toscaMeta.getCsarVersion(); + } else { + return this.definition.getMetadata().getTemplateVersion(); + } + } + + private void setMode() { + if (new File(this.tempDir.toFile().getAbsolutePath() + File.separator + TOSCA_Metadata + File.separator + TOSCA_Metadata__TOSCA_Meta).exists()){ + this.toscaMeta.setMode(Mode.WITH_TOSCA_META_DIR); + } else { + this.toscaMeta.setMode(Mode.WITHOUT_TOSCA_META_DIR); + } + } + + private void parseManifest() throws IOException { + //manifest is optional, so check for it + if (this.manifestMfFile == null) { + return; + } + + int lineNo =0; + List<String>lines = FileUtils.readLines(this.manifestMfFile); + //first hit the metadata section + for (String line: lines) { + lineNo ++; + line = line.trim(); + + if (line.startsWith("#")) { + continue; + } + + //continue till it reaches the metadata section + if (line.equalsIgnoreCase(Entry_Manifest__metadata + ":")) { + break; + } + } + + if (lineNo < lines.size()) { + for (int i = lineNo; i< lines.size(); i++) { + String line = lines.get(i).trim(); + i ++; + + if (line.startsWith("#")) { + continue; + } + + String[] tokens = line.split(":"); + String key = tokens[0]; + String value = tokens[1]; + + //continue till it reaches the metadata section + if (key.equalsIgnoreCase(Entry_Manifest__metadata__vnf_package_version)) { + this.manifest.getMetadata().setPackageVersion(value); + } else if (key.equalsIgnoreCase(Entry_Manifest__metadata__vnf_product_name)) { + this.manifest.getMetadata().setProductName(value); + } else if (key.equalsIgnoreCase(Entry_Manifest__metadata__vnf_provider_id)) { + this.manifest.getMetadata().setProviderId(value); + } else if (key.equalsIgnoreCase(Entry_Manifest__metadata__vnf_release_data_time)) { + this.manifest.getMetadata().setReleaseDateTime(value); + } else { + //Non-Mano entries are not processed as of now... + errors.add( + new CSARErrorIgnored( + key, + this.manifestMfFile.getName(), + i, + null)); + } + } + } + } + + private void parseDefinitionMetadata() throws IOException { + try(FileInputStream ipStream = new FileInputStream(this.definitionYamlFile)) { + Map<String, ?> yaml = (Map<String, ?>) new Yaml().load(ipStream); + + //yaml is empty or version string missing + if (yaml == null || !yaml.keySet().contains(Entry_Definition__tosca_definitions_version)) { + errors.add( + new CSARErrorEntryMissingToscaDefinitionVersion( + this.definitionYamlFile.getName())); + } else { + String version = (String) yaml.get(Entry_Definition__tosca_definitions_version); + if (!Arrays.asList(Entry_Definition__tosca_definitions_versions).contains(version)) { + errors.add(new CSARErrorInvalidEntry(Entry_Definition__tosca_definitions_version, + this.definitionYamlFile.getName(), -1, "Should be " + Entry_Definition__tosca_definitions_version__simple_1_1)); + } else { + this.definition.setToscaDefinitionVersion(version); + + if (this.toscaMeta.getMode().equals(Mode.WITHOUT_TOSCA_META_DIR)) { + //metadata section should be there + if (!yaml.keySet().contains(Entry_Definition__metadata)) { + errors.add( + new CSARErrorInvalidEntryValueToscaDefinitionVersion( + this.definitionYamlFile.getName())); + } else { + Map<String, String> metadata = (Map<String, String>) yaml.get(Entry_Definition__metadata); + + for(Map.Entry<String, String> entry: metadata.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + + //continue till it reaches the metadata section + if (key.equalsIgnoreCase(Entry_Definition__template_author)) { + this.definition.getMetadata().setTemplateAuthor(value); + } else if (key.equalsIgnoreCase(Entry_Definition__template_name)) { + this.definition.getMetadata().setTempalteName(value); + } else if (key.equalsIgnoreCase(Entry_Definition__template_version)) { + this.definition.getMetadata().setTemplateVersion(value); + } else { + errors.add( + new CSARErrorIgnored( + key, + this.definitionYamlFile.getName(), + -1, + null)); + } + } + + if (this.definition.getMetadata().getTemplateAuthor() == null) { + this.errors.add( + new CSARErrorEntryMissingToscaDefinitionMetadataTemplateAuthor( + this.definitionYamlFile.getName())); + } + if (this.definition.getMetadata().getTempalteName() == null) { + this.errors.add(new CSARErrorEntryMissingToscaDefinitionMetadataTemplateName( + this.definitionYamlFile.getName())); + } + + if (this.definition.getMetadata().getTemplateVersion() == null) { + this.errors.add(new CSARErrorEntryMissingToscaDefinitionMetadataTemplateVersion( + this.definitionYamlFile.getName())); + } + } + } + } + } + } + } + + private void parseMeta() throws IOException { + if (this.toscaMeta.getMode().equals(Mode.WITH_TOSCA_META_DIR)) { + this.toscaMetaFile = this.tempDir.resolve(TOSCA_Metadata+ File.separator + TOSCA_Metadata__TOSCA_Meta).toFile(); + + int lineNo =0; + for (String line: FileUtils.readLines(this.toscaMetaFile)) { + lineNo ++; + line = line.trim(); + + if (line.startsWith("#")) { + continue; + } else if (line.trim().isEmpty()) { + continue; + } + + String []lineTokens = line.split(":"); + + if (lineTokens.length != 2) { + errors.add( + new CSARErrorIgnored( + line, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + null)); + continue; + } + + String key = lineTokens[0].trim(); + String value = lineTokens[1].trim(); + + if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__TOSCA_Meta_File_Version)) { + this.toscaMeta.setMetaDataFileVersion(value); + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__CSAR_Version)){ + this.toscaMeta.setCsarVersion(value); + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Created_by)) { + this.toscaMeta.setCompanyName(value); + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Definitions)) { + this.toscaMeta.setEntryDefinitionYaml(value); + this.definitionYamlFile = new File(this.tempDir.toFile().getAbsolutePath() + File.separator + (this.toscaMeta.getEntryDefinitionYaml())); + + if (!this.definitionYamlFile.exists()) { + errors.add( + new CSARErrorInvalidEntryValueToscaDefinitionNotFound( + this.toscaMeta.getEntryDefinitionYaml(), + lineNo)); + } + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Manifest)) { + this.toscaMeta.setEntryManifestMf(value); + this.manifestMfFile = this.tempDir.resolve(this.toscaMeta.getEntryManifestMf()).toFile(); + if (!this.manifestMfFile.exists()) { + errors.add(new CSARErrorInvalidEntryValueManifestNotFound( + this.toscaMeta.getEntryManifestMf(), + lineNo)); + } + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Change_Log)) { + this.toscaMeta.setEntryChangeLog(value); + this.changeLogTxtFile = this.tempDir.resolve(this.toscaMeta.getEntryChangeLog()).toFile(); + if (!this.changeLogTxtFile.exists()) { + errors.add(new CSARErrorInvalidEntryValueLogsNotFound( + this.toscaMeta.getEntryChangeLog(), + lineNo)); + } + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Tests)) { + this.toscaMeta.setEntryTest(value); + this.testsFolder= this.tempDir.resolve(this.toscaMeta.getEntryTest()).toFile(); + if (!this.testsFolder.exists() || !this.testsFolder.isDirectory()) { + errors.add(new CSARErrorInvalidEntryValueTestsNotFound( + this.toscaMeta.getEntryTest(), + lineNo)); + } + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Licenses)) { + this.toscaMeta.setEntryLicense(value); + this.licensesFolder= this.tempDir.resolve(this.toscaMeta.getEntryLicense()).toFile(); + if (!this.licensesFolder.exists() || !this.licensesFolder.isDirectory()) { + errors.add(new CSARErrorInvalidEntryValueLicenseNotFound( + this.toscaMeta.getEntryLicense(), + lineNo)); + } + } else if(key.equalsIgnoreCase(TOSCA_Metadata__TOSCA_Meta__Entry_Certificate)) { + this.toscaMeta.setEntryCertificate(value); + this.certificatesFile= this.tempDir.resolve(this.toscaMeta.getEntryCertificate()).toFile(); + if (!this.certificatesFile.exists()) { + errors.add(new CSARErrorInvalidEntryValueCertificatesNotFound( + this.toscaMeta.getEntryCertificate(), + lineNo)); + } + } else { + errors.add( + new CSARErrorIgnored( + key, + TOSCA_Metadata__TOSCA_Meta, + lineNo, + null)); + } + } + + if (this.toscaMeta.getMetaDataFileVersion() == null) { + errors.add(new CSARErrorEntryMissingToscaMetaFileVersion()); + + //should the file version value to be checked ?? + } + + if (this.toscaMeta.getEntryDefinitionYaml() == null) { + errors.add(new CSARErrorEntryMissingToscaMetaDefinition()); + } + + if (this.toscaMeta.getCsarVersion() == null) { + errors.add(new CSARErrorEntryMissingToscaMetaCSARVersion()); + } + + if (this.toscaMeta.getCompanyName() == null) { + errors.add(new CSARErrorEntryMissingToscaMetaCreatedBy()); + } + + } else { + //definition files + File []files = this.tempDir.toFile().listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".yaml"); + } + }); + + if (files.length == 0) { + errors.add( + new CSARErrorEntryMissingToscaDefinitionNotFound()); + }else if (files.length > 1) { + List<String> fileNames = new ArrayList<>(); + for (File f: files) { + fileNames.add(f.getName()); + } + errors.add( + new CSARErrorConflictsMultipleDefinitionYamls(fileNames.toString())); + } else { + this.definitionYamlFile = files[0]; + this.toscaMeta.setEntryDefinitionYaml(this.definitionYamlFile.getName()); + + //manifest + files = this.tempDir.toFile().listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".mf"); + } + }); + + if (files.length > 1) { + List<String> fileNames = new ArrayList<>(); + for (File f: files) { + fileNames.add(f.getName()); + } + errors.add(new CSARErrorConflictsMultipleManifests(fileNames.toString())); + } else { + this.manifestMfFile = files[0]; + this.toscaMeta.setEntryManifestMf(this.manifestMfFile.getName()); + + //name should match the definition yaml + String defYaml = this.toscaMeta.getEntryDefinitionYaml().substring( + 0, this.toscaMeta.getEntryDefinitionYaml().lastIndexOf(".yaml")); + String mfFile = this.toscaMeta.getEntryManifestMf().substring( + 0, this.toscaMeta.getEntryManifestMf().lastIndexOf(".mf")); + + if (!defYaml.equalsIgnoreCase(mfFile)) { + errors.add(new CSARErrorMismatchDefinitionYamlVsManifestMf( + defYaml, + mfFile)); + } + + } + + //certificate + files = this.tempDir.toFile().listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".cert"); + } + }); + + if (files.length > 1) { + List<String> fileNames = new ArrayList<>(); + for (File f: files) { + fileNames.add(f.getName()); + } + errors.add( + new CSARErrorConflictsMultipleCertificates(fileNames.toString())); + } else { + this.certificatesFile = files[0]; + this.toscaMeta.setEntryCertificate(this.certificatesFile.getName()); + + //name should match the definition yaml + String defYaml = this.toscaMeta.getEntryDefinitionYaml().substring( + 0, this.toscaMeta.getEntryDefinitionYaml().lastIndexOf(".yaml")); + String certFile = this.toscaMeta.getEntryCertificate().substring( + 0, this.toscaMeta.getEntryCertificate().lastIndexOf(".cert")); + + if (!defYaml.equalsIgnoreCase(certFile)) { + errors.add(new CSARErrorMismatchDefinitionYamlVsCertificateCert( + defYaml, + certFile )); + } + } + } + + + + for (File file: this.tempDir.toFile().listFiles()) { + if (file.getName().equalsIgnoreCase(Change_Logs_Txt)) { + this.changeLogTxtFile = file; + } + + else if (file.getName().equalsIgnoreCase(Tests)) { + this.testsFolder = file; + } + + else if (file.getName().equalsIgnoreCase(Licenses)) { + this.licensesFolder = file; + } + + else { + errors.add( + new CSARErrorIgnored( + file.getName(), + CSAR_Archive, + -1, + null)); + } + } + } + } + + public void init(String csarPath) throws IOException { + this.tempDir = Paths.get(TEMP_DIR + File.separator + System.currentTimeMillis()); + this.tempDir.toFile().mkdirs(); + + this.unzip(csarPath); + } + public void parse() throws IOException { + //Find out the mode of CSAR + this.setMode(); + + //process the TOSCA.meta + this.parseMeta(); + + //process manifest + this.parseManifest(); + + //process definition + this.parseDefinitionMetadata(); + } + + public void cleanup() throws IOException { + //remove temp dir + FileUtils.deleteDirectory(this.tempDir.toFile()); + } + + public File getFileFromCsar(String path) { + return new File(this.tempDir.toFile().getAbsolutePath() + File.separator + path); + } + + public static void main(String[] args) { + System.out.println(CSARArchive.SOL0004_2_4_1); + + for (String csarFileName: Arrays.asList(new String[] {"enterprise2DC", "VoLTE", "vEPC_NS", "vIMS_NS", "sample2"})) { + try { + CSARArchive csar = new CSARArchive(); + System.out.println(csarFileName); + csar.init("D:\\workspace\\onap\\1.1\\vnfsdk\\validation\\csarvalidation\\src\\test\\resources\\" + csarFileName + ".csar"); + csar.parse(); + csar.cleanup(); + System.out.println(csar.getErrors()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/VTPValidateCSAR.java b/csarvalidation/src/main/java/org/onap/cvc/csar/VTPValidateCSAR.java new file mode 100644 index 0000000..c3bab09 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/VTPValidateCSAR.java @@ -0,0 +1,289 @@ +/* + * Copyright 2019 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.output.OnapCommandResultType; +import org.onap.cli.fw.registrar.OnapCommandRegistrar; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Validates CSAR + */ +@OnapCommandSchema(schema = "vtp-validate-csar.yaml") +public class VTPValidateCSAR extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSAR.class); + + public static class CSARValidation { + public static class VNF { + private String name; + private String vendor; + private String version; + private String type; + private String mode; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getVendor() { + return vendor; + } + public void setVendor(String vendor) { + this.vendor = vendor; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getMode() { + return mode; + } + public void setMode(String mode) { + this.mode = mode; + } + } + + private VNF vnf = new VNF(); + private String date; + private String criteria; + + public static class Result { + private boolean passed; + private String vnfreqName; + private String description; + private List<CSARError> errors = new ArrayList<>(); + public boolean isPassed() { + return passed; + } + public void setPassed(boolean passed) { + this.passed = passed; + } + public String getVnfreqName() { + return vnfreqName; + } + public void setVnfreqName(String vnfreqName) { + this.vnfreqName = vnfreqName; + } + public List<CSARError> getErrors() { + return errors; + } + public void setErrors(List<CSARError> errors) { + this.errors = errors; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + } + + private List<Result> results = new ArrayList<>(); + + private String contact = "ONAP VTP Team onap-discuss@lists.onap.org"; + + private String platform = "VNF Test Platform (VTP) 1.0"; + + public VNF getVnf() { + return vnf; + } + + public void setVnf(VNF vnf) { + this.vnf = vnf; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getCriteria() { + return criteria; + } + + public void setCriteria(String criteria) { + this.criteria = criteria; + } + + public List<Result> getResults() { + return results; + } + + public void setResults(List<Result> results) { + this.results = results; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getContact() { + return contact; + } + + public void setContact(String contact) { + this.contact = contact; + } + } + + private static Properties prp = new Properties(); + static { + try { + prp.load(VTPValidateCSAR.class.getClass().getResourceAsStream("/vnfreqs.properties")); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + + boolean overallPass = true; + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + csar.cleanup(); + + //Fill up the basic details + CSARValidation validation = new CSARValidation(); + validation.getVnf().setVendor(csar.getVendorName()); + validation.getVnf().setVersion(csar.getVersion()); + validation.getVnf().setType("TOSCA"); + validation.getVnf().setMode(csar.getToscaMeta().getMode().name()); + + List <String> ignoreCodes = this.getIgnoreErrorCodes(); + + //Add SOL004 error codes + CSARValidation.Result resultSOL004 = new CSARValidation.Result(); + resultSOL004.setVnfreqName("SOL004"); + resultSOL004.setDescription(csar.getSOL004Version()); + resultSOL004.setErrors(csar.getErrors()); + resultSOL004.setPassed(true); + + for (CSARError error: resultSOL004.getErrors()) { + if (!ignoreCodes.contains(error.getErrorCode())) { + resultSOL004.setPassed(false); + overallPass = false; + break; + } + } + + validation.getResults().add(resultSOL004); + + //Run thru the vnfreqs requirement checks + for (String vnfreq: this.getEnabledReqs()) { + CSARValidation.Result result = new CSARValidation.Result(); + result.setVnfreqName(vnfreq); + + try { + String command = "csar-validate-" + vnfreq; + OnapCommand cmd = OnapCommandRegistrar.getRegistrar().get(command, this.getInfo().getProduct()); + cmd.getParametersMap().get("csar").setValue(path); + + result.setDescription(cmd.getDescription()); + cmd.execute(); + + result.setErrors( (List<CSARError>)cmd.getResult().getOutput()); + result.setPassed(true); + + for (CSARError error: result.getErrors()) { + if (!ignoreCodes.contains(error.getErrorCode())) { + result.setPassed(false); + overallPass = false; + break; + } + } + + validation.getResults().add(result); + } catch (Exception e) { + result.setPassed(false); + overallPass = false; + result.getErrors().add(new CSARArchive.CSARErrorUnknown(e.getMessage())); + } + } + + validation.setDate(new Date().toString()); + validation.setCriteria(overallPass ? "PASS" : "FAILED"); + + this.getResult().getRecordsMap().get("vnf").getValues().add( + new ObjectMapper().writeValueAsString(validation.getVnf())); + this.getResult().getRecordsMap().get("date").getValues().add(validation.getDate()); + this.getResult().getRecordsMap().get("criteria").getValues().add(validation.getCriteria()); + this.getResult().getRecordsMap().get("results").getValues().add( + new ObjectMapper().writeValueAsString(validation.getResults())); + + this.getResult().setOutput(new ObjectMapper().writeValueAsString(validation)); + this.getResult().setType(OnapCommandResultType.TEXT); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + } + + private List<String> getEnabledReqs() throws IOException { + String[] enabledReqs = prp.getProperty("vnfreqs.enabled", "").split(","); + List<String> list = new ArrayList<>(); + for(String req: enabledReqs) { + if (!req.isEmpty()) list.add(req); + } + return list; + } + + private List<String> getIgnoreErrorCodes() throws IOException { + String[] errorsToIgnore = prp.getProperty("errors.ignored", "").split(","); + List<String> list = new ArrayList<>(); + for(String req: errorsToIgnore) { + if (!req.isEmpty()) list.add(req); + } + return list; + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR02454.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR02454.java new file mode 100644 index 0000000..c77db76 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR02454.java @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +/** + * R-02454: The VNF MUST support the existence of multiple major/minor + * versions of the VNF software and/or sub-components and interfaces that + * support both forward and backward compatibility to be transparent to the + * Service Provider usage. + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r02454.yaml") +public class VTPValidateCSARR02454 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR02454.class); + + public static class CSARErrorEntryMissingSwImage extends CSARErrorEntryMissing { + public CSARErrorEntryMissingSwImage(String defYaml, String entry) { + super( + entry, + defYaml, + -1, + "The VNF MUST support the existence of multiple major/minor versions " + + "of the VNF software and/or sub-components and interfaces that support both " + + "forward and backward compatibility to be transparent to the Service Provider usage."); + this.setSubCode("r02454-0x1000"); + } + } + + private List<CSARError> validate(CSARArchive csar) throws FileNotFoundException, IOException { + List<CSARError> errors = new ArrayList<>(); + + try(FileInputStream ipStream = new FileInputStream(csar.getDefinitionYamlFile())) { + Map<String, ?> yaml = (Map<String, ?>) new Yaml().load(ipStream); + yaml = (Map<String, ?>) yaml.get("topology_template"); + Map<String, ?> nodeTmpls = (Map<String,?>) yaml.get("node_templates"); + + boolean vlExist = false; + + for (Object nodeO: nodeTmpls.values()) { + Map<String, ?> node = (Map<String, ?>) nodeO; + if (node.containsKey("type")) { + String type = (String)node.get("type"); + if (type.equalsIgnoreCase("tosca.artifacts.nfv.SwImage")) { + vlExist = true; + break; + } + } + } + + if (!vlExist) + errors.add(new CSARErrorEntryMissingSwImage( + csar.getDefinitionYamlFile().getName(), + "Software Image")); + } + + return errors; + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + errors = this.validate(csar); + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-02454: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR04298.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR04298.java new file mode 100644 index 0000000..3c2ffd5 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR04298.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-04298: VNF provider MUST provider their testing scripts to support testing. + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r04298.yaml") +public class VTPValidateCSARR04298 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR04298.class); + + public static class CSARErrorEntryMissingTestFolderNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingTestFolderNotFound() { + super( + "Tests", + CSARArchive.CSAR_Archive, + -1, + "The VNF provider MUST provide their testing scripts to support testing."); + this.setSubCode("r04298-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (csar.getTestsFolder() == null) { + errors.add(new CSARErrorEntryMissingTestFolderNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-04298: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR07879.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR07879.java new file mode 100644 index 0000000..8f975cc --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR07879.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-07879: playbooks directory + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r07879.yaml") +public class VTPValidateCSARR07879 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR07879.class); + + public static class CSARErrorEntryMissingAnsiblePlaybookNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingAnsiblePlaybookNotFound() { + super( + "playbooks", + CSARArchive.CSAR_Archive, + -1, + "The VNF Package MUST include all relevant playbooks to ONAP to be loaded on the Ansible Server."); + this.setSubCode("r07879-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("playbooks").exists()) { + errors.add(new CSARErrorEntryMissingAnsiblePlaybookNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-07879: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR09467.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR09467.java new file mode 100644 index 0000000..8ce3a23 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR09467.java @@ -0,0 +1,114 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +/** + * R-09467: The VNF MUST utilize only NCSP standard compute flavors. [5] - compute, virtual storage + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r09467.yaml") +public class VTPValidateCSARR09467 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR09467.class); + + public static class CSARErrorEntryMissingFlavor extends CSARErrorEntryMissing { + public CSARErrorEntryMissingFlavor(String defYaml, String entry) { + super( + entry, + defYaml, + -1, + "The VNF MUST utilize only NCSP standard compute flavors. [5] - compute, virtual storage"); + this.setSubCode("r09467-0x1000"); + } + } + + private List<CSARError> validate(CSARArchive csar) throws FileNotFoundException, IOException { + List<CSARError> errors = new ArrayList<>(); + + try(FileInputStream ipStream = new FileInputStream(csar.getDefinitionYamlFile())) { + Map<String, ?> yaml = (Map<String, ?>) new Yaml().load(ipStream); + yaml = (Map<String, ?>) yaml.get("topology_template"); + Map<String, ?> nodeTmpls = (Map<String,?>) yaml.get("node_templates"); + + boolean vlExist = false; + + for (Object nodeO: nodeTmpls.values()) { + Map<String, ?> node = (Map<String, ?>) nodeO; + if (node.containsKey("type")) { + String type = (String)node.get("type"); + if (type.equalsIgnoreCase("tosca.nodes.nfv.VDU.Compute")) { + vlExist = true; + break; + } + } + } + + if (!vlExist) + errors.add(new CSARErrorEntryMissingFlavor( + csar.getDefinitionYamlFile().getName(), + "Flavor")); + } + + return errors; + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + errors = this.validate(csar); + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-09467: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR13390.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR13390.java new file mode 100644 index 0000000..6c44ee6 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR13390.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-r13390: cookbooks directory + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r13390.yaml") +public class VTPValidateCSARR13390 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR13390.class); + + public static class CSARErrorEntryMissingAnsiblePlaybookNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingAnsiblePlaybookNotFound() { + super( + "cookbooks", + CSARArchive.CSAR_Archive, + -1, + "The VNF provider MUST provide cookbooks to be loaded on the appropriate Chef Server."); + this.setSubCode("r13390-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("playbooks").exists()) { + errors.add(new CSARErrorEntryMissingAnsiblePlaybookNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-13390: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR23823.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR23823.java new file mode 100644 index 0000000..f8a0385 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR23823.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-04298: VNF provider MUST provider their testing scripts to support testing. + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r23823.yaml") +public class VTPValidateCSARR23823 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR23823.class); + + public static class CSARErrorEntryMissingCertificatesNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingCertificatesNotFound() { + super( + "Certificates", + CSARArchive.CSAR_Archive, + -1, + "The VNF Package MUST include appropriate credentials so that ONAP can interact with the Chef Server"); + this.setSubCode("r23823-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (csar.getCertificatesFile() == null) { + errors.add(new CSARErrorEntryMissingCertificatesNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-23823: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR26881.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR26881.java new file mode 100644 index 0000000..e9efd38 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR26881.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-26881: VNF artifacts + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r26881.yaml") +public class VTPValidateCSARR26881 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR26881.class); + + public static class CSARErrorEntryMissingArtifactsNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingArtifactsNotFound() { + super( + "Artifacts", + CSARArchive.CSAR_Archive, + -1, + "The VNF provider MUST provide the binaries and images needed to instantiate the VNF (VNF and VNFC images)."); + this.setSubCode("r26881-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("artifacts").exists()) { + errors.add(new CSARErrorEntryMissingArtifactsNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-26881: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR27310.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR27310.java new file mode 100644 index 0000000..7b2e25a --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR27310.java @@ -0,0 +1,82 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-27310: Manifest file + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r27310.yaml") +public class VTPValidateCSARR27310 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR27310.class); + + public static class CSARErrorEntryMissingChefArtifactsNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingChefArtifactsNotFound() { + super( + "cookbooks", + CSARArchive.CSAR_Archive, + -1, + "The VNF Package MUST include all relevant Chef artifacts (roles/cookbooks/recipes) " + + "required to execute VNF actions requested by ONAP for loading on appropriate Chef Server."); + this.setSubCode("r27310-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("cookbooks").exists()) { + errors.add(new CSARErrorEntryMissingChefArtifactsNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-27310: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR35851.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR35851.java new file mode 100644 index 0000000..068b372 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR35851.java @@ -0,0 +1,120 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +/** + * R-35851: The VNF Package MUST include VNF topology that describes + * basic network and application connectivity internal and external to the VNF + * including Link type, KPIs, Bandwidth, latency, jitter, QoS + * (if applicable) for each interface + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r35851.yaml") +public class VTPValidateCSARR35851 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR35851.class); + + public static class CSARErrorEntryMissingDefinitionYamlTopology extends CSARErrorEntryMissing { + public CSARErrorEntryMissingDefinitionYamlTopology(String defYaml, String entry) { + super( + entry, + defYaml, + -1, + "The VNF Package MUST include VNF topology that describes basic " + + "network and application connectivity internal and external to " + + "the VNF including Link type, KPIs, Bandwidth, latency, jitter, " + + "QoS (if applicable) for each interface"); + this.setSubCode("r35851-0x1000"); + } + } + + private List<CSARError> validate(CSARArchive csar) throws FileNotFoundException, IOException { + List<CSARError> errors = new ArrayList<>(); + + try(FileInputStream ipStream = new FileInputStream(csar.getDefinitionYamlFile())) { + Map<String, ?> yaml = (Map<String, ?>) new Yaml().load(ipStream); + yaml = (Map<String, ?>) yaml.get("topology_template"); + Map<String, ?> nodeTmpls = (Map<String,?>) yaml.get("node_templates"); + + boolean vlExist = false; + + for (Object nodeO: nodeTmpls.values()) { + Map<String, ?> node = (Map<String, ?>) nodeO; + if (node.containsKey("type")) { + String type = (String)node.get("type"); + if (type.equalsIgnoreCase("tosca.nodes.nfv.VnfVirtualLink")) { + vlExist = true; + break; + } + } + } + + if (!vlExist) + errors.add(new CSARErrorEntryMissingDefinitionYamlTopology( + csar.getDefinitionYamlFile().getName(), + "Topology VL")); + } + + return errors; + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + errors = this.validate(csar); + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-35851: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR40293.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR40293.java new file mode 100644 index 0000000..eaf0710 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR40293.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-r40293: playbooks directory + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r40293.yaml") +public class VTPValidateCSARR40293 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR40293.class); + + public static class CSARErrorEntryMissingAnsiblePlaybookNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingAnsiblePlaybookNotFound() { + super( + "playbooks", + CSARArchive.CSAR_Archive, + -1, + "The VNF MUST make available (or load on VNF Ansible Server) playbooks that conform to the ONAP requirement."); + this.setSubCode("r40293-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("playbooks").exists()) { + errors.add(new CSARErrorEntryMissingAnsiblePlaybookNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-40293: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR43958.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR43958.java new file mode 100644 index 0000000..10ae1c0 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR43958.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-43958: Test reports + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r43958.yaml") +public class VTPValidateCSARR43958 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR43958.class); + + public static class CSARErrorEntryMissingTestReportNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingTestReportNotFound() { + super( + "Tests/report.txt", + CSARArchive.CSAR_Archive, + -1, + "The VNF Package MUST include documentation describing the tests that were conducted by the VNF provider and the test results."); + this.setSubCode("r43958-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("Tests/report.txt").exists()) { + errors.add(new CSARErrorEntryMissingTestReportNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-43958: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR66070.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR66070.java new file mode 100644 index 0000000..8d51c94 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR66070.java @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-66070: VNF provider details + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r66070.yaml") +public class VTPValidateCSARR66070 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR66070.class); + + public static class CSARErrorEntryVNFProviderDetailsNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryVNFProviderDetailsNotFound() { + super( + "VNF Vendor details", + CSARArchive.TOSCA_Metadata + " or " + CSARArchive.TOSCA_Metadata__TOSCA_Meta__Entry_Definitions + " file", + -1, + "The VNF Package MUST include VNF Identification Data to uniquely identify the" + + " resource for a given VNF provider. The identification data must include: " + + "an identifier for the VNF, the name of the VNF as was given by the VNF provider, " + + "VNF description, VNF provider, and version."); + this.setSubCode("r66070-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (csar.getVendorName() == null || + csar.getVersion() == null) { + errors.add(new CSARErrorEntryVNFProviderDetailsNotFound()); + } + //do the validation + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-66070: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77707.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77707.java new file mode 100644 index 0000000..9549e67 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77707.java @@ -0,0 +1,83 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-77707: Manifest file + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r77707.yaml") +public class VTPValidateCSARR77707 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR77707.class); + + public static class CSARErrorEntryMissingDefinitionNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingDefinitionNotFound() { + super( + "TOSCA definition or Tosca.Meata", + CSARArchive.CSAR_Archive, + -1, + "The VNF provider MUST include a Manifest File that contains a list " + + "of all the components in the VNF package."); + this.setSubCode("r77707-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (csar.getToscaMeta().getEntryDefinitionYaml() == null || + csar.getDefinitionYamlFile() == null || !csar.getDefinitionYamlFile().exists()) { + errors.add(new CSARErrorEntryMissingDefinitionNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-77707: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77786.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77786.java new file mode 100644 index 0000000..1fa5a1f --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidateCSARR77786.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar.cc; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.CSARArchive.CSARError; +import org.onap.cvc.csar.CSARArchive.CSARErrorEntryMissing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * R-77786: cookbooks directory + */ +@OnapCommandSchema(schema = "vtp-validate-csar-r77786.yaml") +public class VTPValidateCSARR77786 extends OnapCommand { + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR77786.class); + + public static class CSARErrorEntryMissingAnsiblePlaybookNotFound extends CSARErrorEntryMissing { + public CSARErrorEntryMissingAnsiblePlaybookNotFound() { + super( + "cookbooks", + CSARArchive.CSAR_Archive, + -1, + "The VNF Package MUST include all relevant cookbooks to be loaded on the ONAP Chef Server."); + this.setSubCode("r77786-0x1000"); + } + } + + @Override + protected void run() throws OnapCommandException { + //Read the input arguments + String path = (String) getParametersMap().get("csar").getValue(); + List<CSARError> errors = new ArrayList<>(); + //execute + try { + CSARArchive csar = new CSARArchive(); + csar.init(path); + csar.parse(); + + if (!csar.getFileFromCsar("playbooks").exists()) { + errors.add(new CSARErrorEntryMissingAnsiblePlaybookNotFound()); + } + + csar.cleanup(); + } catch (Exception e) { + LOG.error("R-77786: ", e); + throw new OnapCommandExecutionFailed(e.getMessage()); + } + + this.getResult().setOutput(errors); + + //set the result + for (CSARError e: errors) { + this.getResult().getRecordsMap().get("code").getValues().add(e.getCode()); + this.getResult().getRecordsMap().get("message").getValues().add(e.getMessage()); + this.getResult().getRecordsMap().get("file").getValues().add(e.getFile()); + this.getResult().getRecordsMap().get("line-no").getValues().add(Integer.toString(e.getLineNumber())); + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/package-info.java b/csarvalidation/src/main/java/org/onap/cvc/csar/package-info.java new file mode 100644 index 0000000..87b8611 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/package-info.java @@ -0,0 +1,25 @@ +/** + * Copyright 2019 Huawei Technologies Co., Ltd. + * + * 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. + */ + +/** + * CSAR Archive parse the given CSAR file and create the class CSARArchive. + * It validates the CSAR for ETSI SOL004 and also allows to add additional + * validating logic for entries in definitions files for the given ONAP + * VNFREQS defined for TOSCA standards. + * + * @author Kanagaraj Manickam kanagaraj.manickam@huawei.com + */ +package org.onap.cvc.csar;
\ No newline at end of file diff --git a/csarvalidation/src/main/java/org/onap/validation/csar/VTPValidateCSAR.java b/csarvalidation/src/main/java/org/onap/validation/csar/VTPValidateCSAR.java index 00d4b6d..b97b488 100644 --- a/csarvalidation/src/main/java/org/onap/validation/csar/VTPValidateCSAR.java +++ b/csarvalidation/src/main/java/org/onap/validation/csar/VTPValidateCSAR.java @@ -17,12 +17,10 @@ package org.onap.validation.csar; import java.io.IOException; -import java.util.Map; import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.error.OnapCommandExecutionFailed; -import org.onap.cli.fw.input.OnapCommandParameter; import org.onap.cli.fw.schema.OnapCommandSchema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +28,7 @@ import org.slf4j.LoggerFactory; /** * Validates CSAR */ -@OnapCommandSchema(schema = "vtp-validate-csar.yaml") +@OnapCommandSchema(schema = "vtp-validate-csar-casablanca.yaml") public class VTPValidateCSAR extends OnapCommand { private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSAR.class); @@ -43,7 +41,7 @@ public class VTPValidateCSAR extends OnapCommand { String error = this.test(csar); //set the result - this.getResult().getRecordsMap().get("error").getValues().add(error); + this.getResult().getRecordsMap().get("errors").getValues().add(error); } public String test(String csar) throws OnapCommandException { diff --git a/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand b/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand index 8db8929..5bcd3cc 100644 --- a/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand +++ b/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand @@ -12,4 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -org.onap.validation.csar.VTPValidateCSAR
\ No newline at end of file +org.onap.cvc.csar.VTPValidateCSAR +org.onap.cvc.csar.cc.VTPValidateCSARR02454 +org.onap.cvc.csar.cc.VTPValidateCSARR04298 +org.onap.cvc.csar.cc.VTPValidateCSARR07879 +org.onap.cvc.csar.cc.VTPValidateCSARR09467 +org.onap.cvc.csar.cc.VTPValidateCSARR13390 +org.onap.cvc.csar.cc.VTPValidateCSARR23823 +org.onap.cvc.csar.cc.VTPValidateCSARR26881 +org.onap.cvc.csar.cc.VTPValidateCSARR27310 +org.onap.cvc.csar.cc.VTPValidateCSARR35851 +org.onap.cvc.csar.cc.VTPValidateCSARR40293 +org.onap.cvc.csar.cc.VTPValidateCSARR43958 +org.onap.cvc.csar.cc.VTPValidateCSARR66070 +org.onap.cvc.csar.cc.VTPValidateCSARR77707 +org.onap.cvc.csar.cc.VTPValidateCSARR77786
\ No newline at end of file diff --git a/csarvalidation/src/main/resources/log4j.properties b/csarvalidation/src/main/resources/log4j.properties new file mode 100644 index 0000000..2f44a11 --- /dev/null +++ b/csarvalidation/src/main/resources/log4j.properties @@ -0,0 +1,31 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +log4j.rootLogger=ERROR, file + +log4j.logger.org.onap=ERROR, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +# Redirect log messages to a log file, support file rolling. +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=./csar-validate.log +log4j.appender.file.MaxFileSize=5MB +log4j.appender.file.MaxBackupIndex=10 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-casablanca.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-casablanca.yaml new file mode 100644 index 0000000..e87d428 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-casablanca.yaml @@ -0,0 +1,41 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-casablanca + +description: Validate CSAR package formats + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: error + description: Validation error details + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r02454.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r02454.yaml new file mode 100644 index 0000000..03d395d --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r02454.yaml @@ -0,0 +1,56 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r02454 + +description: | + The VNF MUST support the existence of multiple major/minor versions of the + VNF software and/or sub-components and interfaces that support both forward + and backward compatibility to be transparent to the Service Provider usage. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r04298.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r04298.yaml new file mode 100644 index 0000000..ecbdbcc --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r04298.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r04298 + +description: VNF provider MUST provider their testing scripts to support testing + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r07879.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r07879.yaml new file mode 100644 index 0000000..3118f89 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r07879.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r07879 + +description: The VNF Package MUST include all relevant playbooks to ONAP to be loaded on the Ansible Server. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r09467.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r09467.yaml new file mode 100644 index 0000000..c43fb6a --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r09467.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r09467 + +description: The VNF MUST utilize only NCSP standard compute flavors. [5] - compute, virtual storage. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r13390.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r13390.yaml new file mode 100644 index 0000000..de07c97 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r13390.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r13390 + +description: The VNF provider MUST provide cookbooks to be loaded on the appropriate Chef Server. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r23823.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r23823.yaml new file mode 100644 index 0000000..e504da1 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r23823.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r23823 + +description: The VNF Package MUST include appropriate credentials so that ONAP can interact with the Chef Server + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r26881.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r26881.yaml new file mode 100644 index 0000000..1a7a19b --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r26881.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r26881 + +description: The VNF provider MUST provide the binaries and images needed to instantiate the VNF (VNF and VNFC images). + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r27310.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r27310.yaml new file mode 100644 index 0000000..156c20d --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r27310.yaml @@ -0,0 +1,55 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r27310 + +description: | + The VNF Package MUST include all relevant Chef artifacts (roles/cookbooks/recipes) + required to execute VNF actions requested by ONAP for loading on appropriate Chef Server. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r35851.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r35851.yaml new file mode 100644 index 0000000..1e024c0 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r35851.yaml @@ -0,0 +1,56 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r35851 + +description: | + The VNF Package MUST include VNF topology that describes basic network and application + connectivity internal and external to the VNF including Link type, KPIs, Bandwidth, + latency, jitter, QoS (if applicable) for each interface. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r40293.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r40293.yaml new file mode 100644 index 0000000..2e0e652 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r40293.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r40293 + +description: The VNF MUST make available (or load on VNF Ansible Server) playbooks that conform to the ONAP requirement. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r43958.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r43958.yaml new file mode 100644 index 0000000..aaef65a --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r43958.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r43958 + +description: The VNF Package MUST include documentation describing the tests that were conducted by the VNF provider and the test results. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r66070.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r66070.yaml new file mode 100644 index 0000000..d5bd847 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r66070.yaml @@ -0,0 +1,57 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r66070 + +description: | + The VNF Package MUST include VNF Identification Data to uniquely identify the + resource for a given VNF provider. The identification data must include: an identifier + for the VNF, the name of the VNF as was given by the VNF provider, VNF description, + VNF provider, and version + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77707.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77707.yaml new file mode 100644 index 0000000..7f213d7 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77707.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r77707 + +description: VNF provider MUST include manifest file that contains a list of all the components in VNF package + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77786.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77786.yaml new file mode 100644 index 0000000..787225a --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar-r77786.yaml @@ -0,0 +1,53 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 + +name: csar-validate-r77786 + +description: The VNF Package MUST include all relevant cookbooks to be loaded on the ONAP Chef Server. + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar.yaml index 6c81980..329122a 100644 --- a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar.yaml +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-csar.yaml @@ -16,7 +16,7 @@ open_cli_schema_version: 1.0 name: csar-validate -description: Validate CSAR package formats +description: Validate CSAR package formats compliants to ETSI SOL004 and VNFREQS info: product: onap-vtp @@ -33,9 +33,31 @@ parameters: is_optional: false results: - direction: landscape + direction: portrait attributes: - - name: error - description: Validation error details + - name: vnf + description: VNF details such as vendor, type, model, name + scope: short + type: json + - name: date + description: Validation date + scope: short + type: string + - name: platform + description: Platform used to test the reqs + scope: short + type: string + default_value: VNF Test Platform (VTP) 1.0 + - name: contact + description: Owner for this test case + scope: short + type: string + default_value: ONAP VTP Team onap-discuss@lists.onap.org + - name: criteria + description: Overall test reqs passed? PASS or FAILED scope: short type: string + - name: results + description: All test cases results + scope: short + type: json
\ No newline at end of file diff --git a/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-hot.yaml b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-hot.yaml new file mode 100644 index 0000000..17bda93 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/vtp-validate-hot.yaml @@ -0,0 +1,79 @@ +# Copyright 2019 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 +name: hot-validate +description: | + Validates the OpenStack heat templates using ONAP VNFREQS with help of VVP scripts + Before using this command, please install the VVP by following guidelines from + https://github.com/onap/vvp-validation-scripts#installation + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + type: cmd + +parameters: + - name: hot-folder + description: HOT folder path where VNF package files are kept + long_option: hot-folder + short_option: b + type: string + is_optional: false + - name: script-folder + description: Pytest script folder path + long_option: script-folder + default_value: $s{env:ONAP_VVP_HOME} + short_option: n + type: string + is_optional: false + +results: + direction: landscape + attributes: + - name: vnfrqts + description: vnfrqts identifiers + scope: short + type: string + - name: test + description: test case + scope: short + type: string + - name: template + description: template file + scope: short + type: string + - name: message + description: error message + scope: short + type: string +cmd: + command: + - pytest ${script-folder} --template-directory=${hot-folder} + success_codes: + - 0 + - 1 + - 5 + pass_codes: + - 0 + - 5 + working_directory: . + output: $s{file:${script-folder}/output/failures} + result_map: + vnfrqts: $o{$.*.vnfrqts} + test: $o{$.*.test} + template: $o{$.*.file} + message: $o{$.*.message} diff --git a/csarvalidation/src/main/resources/vnfreqs.properties b/csarvalidation/src/main/resources/vnfreqs.properties new file mode 100644 index 0000000..878b7f0 --- /dev/null +++ b/csarvalidation/src/main/resources/vnfreqs.properties @@ -0,0 +1,3 @@ +vnfreqs.enabled=r02454,r04298,r07879,r09467,r13390,r23823,r26881,r27310,r35851,r40293,r43958,r66070,r77707,r77786 +# ignored all chef and ansible related tests +errors.ignored=0x1005,0x1006,r07879-0x1000,r13390-0x1000,r27310-0x1000,r40293-0x1000,r77786-0x1000
\ No newline at end of file diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/CsarValidatorTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/CsarValidatorTest.java new file mode 100644 index 0000000..6378c45 --- /dev/null +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/CsarValidatorTest.java @@ -0,0 +1,36 @@ +/** + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * 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. + */ + +package org.onap.cvc.csar; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; +import org.onap.cli.main.OnapCli; + +public class CsarValidatorTest { + + @Test + public void testAll() throws IOException, InterruptedException { + OnapCli cli = new OnapCli(new String [] {"csar-validate", "--format", "json", "--csar", "./src/test/resources/VoLTE.csar"}); + cli.setProduct("onap-vtp"); + cli.handle(); + assertEquals(0, cli.getExitCode()); + } + +} diff --git a/csarvalidation/src/test/resources/log4j.properties b/csarvalidation/src/test/resources/log4j.properties new file mode 100644 index 0000000..2f44a11 --- /dev/null +++ b/csarvalidation/src/test/resources/log4j.properties @@ -0,0 +1,31 @@ +# Copyright 2018 Huawei Technologies Co., Ltd. +# +# 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. + +log4j.rootLogger=ERROR, file + +log4j.logger.org.onap=ERROR, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +# Redirect log messages to a log file, support file rolling. +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=./csar-validate.log +log4j.appender.file.MaxFileSize=5MB +log4j.appender.file.MaxBackupIndex=10 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/csarvalidation/src/test/resources/sample-result.json b/csarvalidation/src/test/resources/sample-result.json new file mode 100644 index 0000000..5bfc69f --- /dev/null +++ b/csarvalidation/src/test/resources/sample-result.json @@ -0,0 +1 @@ +{"vnf":{"name":null,"vendor":"Winery 0.1.37-SNAPSHOT","version":"1.0","type":"TOSCA","mode":"WITH_TOSCA_META_DIR"},"date":"Mon Feb 25 16:49:26 IST 2019","criteria":"FAILED","results":[{"passed":true,"vnfreqName":"SOL004","description":"V2.4.1 (2018-02)","errors":[{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":6,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":7,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":9,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":10,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":12,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":13,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":15,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":16,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":18,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":19,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":21,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":22,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":24,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":25,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":27,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":28,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":30,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":31,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":33,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":34,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":36,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":37,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":39,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":40,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":42,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":43,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":45,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":46,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":48,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":49,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Name]","file":"TOSCA.meta","lineNumber":51,"errorCode":"0x1005"},{"code":"0x1005","subCode":null,"message":"Ignored. Entry [Content-Type]","file":"TOSCA.meta","lineNumber":52,"errorCode":"0x1005"}]},{"passed":false,"vnfreqName":"r02454","description":"The VNF MUST support the existence of multiple major/minor versions of the\n VNF software and/or sub-components and interfaces that support both forward \n and backward compatibility to be transparent to the Service Provider usage.\n","errors":[{"code":"0x1002","subCode":"r02454-0x1000","message":"Missing. Entry [Software Image]. The VNF MUST support the existence of multiple major/minor versions of the VNF software and/or sub-components and interfaces that support both forward and backward compatibility to be transparent to the Service Provider usage.","file":"ns2__VoLTE.yaml","lineNumber":-1,"errorCode":"r02454-0x1000"}]},{"passed":false,"vnfreqName":"r04298","description":"VNF provider MUST provider their testing scripts to support testing","errors":[{"code":"0x1002","subCode":"r04298-0x1000","message":"Missing. Entry [Tests]. The VNF provider MUST provide their testing scripts to support testing.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r04298-0x1000"}]},{"passed":true,"vnfreqName":"r07879","description":"The VNF Package MUST include all relevant playbooks to ONAP to be loaded on the Ansible Server.","errors":[{"code":"0x1002","subCode":"r07879-0x1000","message":"Missing. Entry [playbooks]. The VNF Package MUST include all relevant playbooks to ONAP to be loaded on the Ansible Server.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r07879-0x1000"}]},{"passed":false,"vnfreqName":"r09467","description":"The VNF MUST utilize only NCSP standard compute flavors. [5] - compute, virtual storage.","errors":[{"code":"0x1002","subCode":"r09467-0x1000","message":"Missing. Entry [Flavor]. The VNF MUST utilize only NCSP standard compute flavors. [5] - compute, virtual storage","file":"ns2__VoLTE.yaml","lineNumber":-1,"errorCode":"r09467-0x1000"}]},{"passed":true,"vnfreqName":"r13390","description":"The VNF provider MUST provide cookbooks to be loaded on the appropriate Chef Server.","errors":[{"code":"0x1002","subCode":"r13390-0x1000","message":"Missing. Entry [cookbooks]. The VNF provider MUST provide cookbooks to be loaded on the appropriate Chef Server.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r13390-0x1000"}]},{"passed":false,"vnfreqName":"r23823","description":"The VNF Package MUST include appropriate credentials so that ONAP can interact with the Chef Server","errors":[{"code":"0x1002","subCode":"r23823-0x1000","message":"Missing. Entry [Certificates]. The VNF Package MUST include appropriate credentials so that ONAP can interact with the Chef Server","file":"CSAR Archive","lineNumber":-1,"errorCode":"r23823-0x1000"}]},{"passed":false,"vnfreqName":"r26881","description":"The VNF provider MUST provide the binaries and images needed to instantiate the VNF (VNF and VNFC images).","errors":[{"code":"0x1002","subCode":"r26881-0x1000","message":"Missing. Entry [Artifacts]. The VNF provider MUST provide the binaries and images needed to instantiate the VNF (VNF and VNFC images).","file":"CSAR Archive","lineNumber":-1,"errorCode":"r26881-0x1000"}]},{"passed":true,"vnfreqName":"r27310","description":"The VNF Package MUST include all relevant Chef artifacts (roles/cookbooks/recipes) \nrequired to execute VNF actions requested by ONAP for loading on appropriate Chef Server.\n","errors":[{"code":"0x1002","subCode":"r27310-0x1000","message":"Missing. Entry [cookbooks]. The VNF Package MUST include all relevant Chef artifacts (roles/cookbooks/recipes) required to execute VNF actions requested by ONAP for loading on appropriate Chef Server.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r27310-0x1000"}]},{"passed":false,"vnfreqName":"r35851","description":"The VNF Package MUST include VNF topology that describes basic network and application\n connectivity internal and external to the VNF including Link type, KPIs, Bandwidth, \n latency, jitter, QoS (if applicable) for each interface.\n","errors":[{"code":"0x1002","subCode":"r35851-0x1000","message":"Missing. Entry [Topology VL]. The VNF Package MUST include VNF topology that describes basic network and application connectivity internal and external to the VNF including Link type, KPIs, Bandwidth, latency, jitter, QoS (if applicable) for each interface","file":"ns2__VoLTE.yaml","lineNumber":-1,"errorCode":"r35851-0x1000"}]},{"passed":true,"vnfreqName":"r40293","description":"The VNF MUST make available (or load on VNF Ansible Server) playbooks that conform to the ONAP requirement.","errors":[{"code":"0x1002","subCode":"r40293-0x1000","message":"Missing. Entry [playbooks]. The VNF MUST make available (or load on VNF Ansible Server) playbooks that conform to the ONAP requirement.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r40293-0x1000"}]},{"passed":false,"vnfreqName":"r43958","description":"The VNF Package MUST include documentation describing the tests that were conducted by the VNF provider and the test results.","errors":[{"code":"0x1002","subCode":"r43958-0x1000","message":"Missing. Entry [Tests/report.txt]. The VNF Package MUST include documentation describing the tests that were conducted by the VNF provider and the test results.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r43958-0x1000"}]},{"passed":true,"vnfreqName":"r66070","description":"The VNF Package MUST include VNF Identification Data to uniquely identify the \nresource for a given VNF provider. The identification data must include: an identifier \nfor the VNF, the name of the VNF as was given by the VNF provider, VNF description, \nVNF provider, and version\n","errors":[]},{"passed":true,"vnfreqName":"r77707","description":"VNF provider MUST include manifest file that contains a list of all the components in VNF package","errors":[]},{"passed":true,"vnfreqName":"r77786","description":"The VNF Package MUST include all relevant cookbooks to be loaded on the ONAP Chef Server.","errors":[{"code":"0x1002","subCode":"r77786-0x1000","message":"Missing. Entry [cookbooks]. The VNF Package MUST include all relevant cookbooks to be loaded on the ONAP Chef Server.","file":"CSAR Archive","lineNumber":-1,"errorCode":"r77786-0x1000"}]}],"contact":"ONAP VTP Team onap-discuss@lists.onap.org","platform":"VNF Test Platform (VTP) 1.0"}
\ No newline at end of file |