diff options
Diffstat (limited to 'csarvalidation/src/main/java')
18 files changed, 2897 insertions, 4 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 { |