From b67f6263e48bfcf51c157a9cd7fe774353cc5f38 Mon Sep 17 00:00:00 2001 From: Bogumil Zebek Date: Wed, 3 Jul 2019 13:48:25 +0200 Subject: Option 1 - pnf only Change-Id: I9af3bb9b0682d7babed16042c5cac948db5dd822 Issue-ID: VNFSDK-396 Signed-off-by: Zebek Bogumil --- .../java/org/onap/cvc/csar/PnfCSARArchive.java | 22 ++- .../java/org/onap/cvc/csar/PnfManifestParser.java | 209 +++------------------ .../cvc/csar/cc/sol004/VTPValidateCSARR787966.java | 157 ++++++++++++++++ .../java/org/onap/cvc/csar/parser/CmsParser.java | 89 +++++++++ .../org/onap/cvc/csar/parser/ManifestConsts.java | 38 ++++ .../org/onap/cvc/csar/parser/ManifestLine.java | 57 ++++++ .../org/onap/cvc/csar/parser/MetadataParser.java | 135 +++++++++++++ .../cvc/csar/parser/NonManoArtifactsParser.java | 85 +++++++++ .../org/onap/cvc/csar/parser/SourcesParser.java | 165 ++++++++++++++++ .../cvc/csar/security/ShaHashCodeGenerator.java | 43 +++++ .../services/org.onap.cli.fw.cmd.OnapCommand | 1 + .../sol004/vtp-validate-csar-r787966.yaml | 60 ++++++ .../src/main/resources/vnfreqs.properties | 2 +- .../java/org/onap/cvc/csar/PnfCSARArchiveTest.java | 19 +- .../org/onap/cvc/csar/PnfManifestParserTest.java | 86 ++++++++- .../org/onap/cvc/csar/PnfMetadataParserTest.java | 46 ++++- .../cvc/csar/PnfNonManoArtifactsParserTest.java | 22 ++- .../VTPValidateCSARR787966IntegrationTest.java | 79 ++++++++ .../csar/security/ShaHashCodeGeneratorTest.java | 54 ++++++ .../src/test/resources/pnf/MainServiceTemplate.mf | 18 +- .../MainServiceTemplateBrokenCMSNoBeginMarker.mf | 41 ++++ .../pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf | 41 ++++ .../MainServiceTemplateCMSSectionNotAtTheEnd.mf | 41 ++++ .../MainServiceTemplateWithBrokenSourcesSection.mf | 37 ++++ .../src/test/resources/pnf/dummyPnfv2.csar | Bin 4038 -> 4451 bytes .../pnf/r787966/csar-option1-invalid.csar | Bin 0 -> 5737 bytes .../resources/pnf/r787966/csar-option1-valid.csar | Bin 0 -> 6571 bytes 27 files changed, 1337 insertions(+), 210 deletions(-) create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/CmsParser.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestConsts.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestLine.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/MetadataParser.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/NonManoArtifactsParser.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/parser/SourcesParser.java create mode 100644 csarvalidation/src/main/java/org/onap/cvc/csar/security/ShaHashCodeGenerator.java create mode 100644 csarvalidation/src/main/resources/open-cli-schema/sol004/vtp-validate-csar-r787966.yaml create mode 100644 csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966IntegrationTest.java create mode 100644 csarvalidation/src/test/java/org/onap/cvc/csar/security/ShaHashCodeGeneratorTest.java create mode 100644 csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoBeginMarker.mf create mode 100644 csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf create mode 100644 csarvalidation/src/test/resources/pnf/MainServiceTemplateCMSSectionNotAtTheEnd.mf create mode 100644 csarvalidation/src/test/resources/pnf/MainServiceTemplateWithBrokenSourcesSection.mf create mode 100644 csarvalidation/src/test/resources/pnf/r787966/csar-option1-invalid.csar create mode 100644 csarvalidation/src/test/resources/pnf/r787966/csar-option1-valid.csar (limited to 'csarvalidation/src') diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java index 6438306..f8e36d1 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java @@ -16,6 +16,7 @@ package org.onap.cvc.csar; import org.apache.commons.lang3.tuple.Pair; +import org.onap.cvc.csar.parser.SourcesParser; import java.io.IOException; import java.util.ArrayList; @@ -37,7 +38,8 @@ public class PnfCSARArchive extends CSARArchive { ); Pair> metadataData = pnfManifestParser.fetchMetadata(); - Pair, List> sourcesSectionData = pnfManifestParser.fetchSourcesSection(); + Pair, List> sourcesSectionData = pnfManifestParser.fetchSourcesSection(); + Pair> cmsSectionData = pnfManifestParser.fetchCMS(); Optional>>, List>> nonManoArtifactsData = pnfManifestParser.fetchNonManoArtifacts(); PnfManifest manifest = (PnfManifest) this.getManifest(); @@ -47,6 +49,9 @@ public class PnfCSARArchive extends CSARArchive { manifest.setSources(sourcesSectionData.getKey()); this.getErrors().addAll(sourcesSectionData.getValue()); + manifest.setCms(cmsSectionData.getKey()); + this.getErrors().addAll(cmsSectionData.getValue()); + if(nonManoArtifactsData.isPresent()){ manifest.setNonMano(nonManoArtifactsData.get().getKey()); this.getErrors().addAll(nonManoArtifactsData.get().getValue()); @@ -65,14 +70,23 @@ public class PnfCSARArchive extends CSARArchive { } public static class PnfManifest extends Manifest { - private List sources = new ArrayList<>(); + private List sources = new ArrayList<>(); + private String cms; - public List getSources() { + public List getSources() { return Collections.unmodifiableList(sources); } - public void setSources(List sources) { + void setSources(List sources) { this.sources.addAll(sources); } + + public String getCms() { + return this.cms; + } + + public void setCms(String cms) { + this.cms = cms; + } } } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java index 8831082..250aa4f 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java @@ -15,18 +15,16 @@ */ package org.onap.cvc.csar; -import com.google.common.collect.Lists; import org.apache.commons.lang3.tuple.Pair; -import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing; -import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorInvalidEntry; -import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorWarning; +import org.onap.cvc.csar.parser.CmsParser; +import org.onap.cvc.csar.parser.MetadataParser; +import org.onap.cvc.csar.parser.NonManoArtifactsParser; +import org.onap.cvc.csar.parser.SourcesParser; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -35,21 +33,20 @@ import java.util.stream.Stream; class PnfManifestParser { + private final List lines; - private static final String METADATA_SECTION_TAG_SECTION = "metadata"; - private static final String SOURCE_TAG_SECTION = "source"; - private static final String NON_MANO_ARTIFACT_SETS_TAG_SECTION = "non_mano_artifact_sets"; - private static final String PRODUCT_NAME = "pnfd_name"; - private static final String PROVIDER_ID = "pnfd_provider"; - private static final String VERSION = "pnfd_archive_version"; - private static final String RELEASE_DATE_TIME = "pnfd_release_date_time"; + private final MetadataParser metadataParser; + private final SourcesParser sourcesParser; + private final NonManoArtifactsParser nonManoArtifactsParser; + private final CmsParser cmsParser; - private final List lines; - private final String fileName; - PnfManifestParser(List lines, String fileName) { + PnfManifestParser(List lines, MetadataParser metadataParser, SourcesParser sourcesParser, NonManoArtifactsParser nonManoArtifactsParser, CmsParser cmsParser) { this.lines = lines; - this.fileName = fileName; + this.metadataParser = metadataParser; + this.sourcesParser = sourcesParser; + this.nonManoArtifactsParser = nonManoArtifactsParser; + this.cmsParser = cmsParser; } static PnfManifestParser getInstance(File pnfManifestFile) throws IOException { @@ -59,188 +56,28 @@ class PnfManifestParser { .map(String::trim) .collect(Collectors.toList()); - return new PnfManifestParser(lines, pnfManifestFile.getName()); + final String pnfManifestFileName = pnfManifestFile.getName(); + return new PnfManifestParser(lines, new MetadataParser(pnfManifestFileName), new SourcesParser(pnfManifestFileName), new NonManoArtifactsParser(), new CmsParser(pnfManifestFileName)); } } Pair> fetchMetadata() { - CSARArchive.Manifest.Metadata metadata = new CSARArchive.Manifest.Metadata(); - List errors = new ArrayList<>(); - - boolean isMetadataSectionAvailable = false; - - for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - String line = lines.get(lineNumber); - Pair data = parseLine(line); - - if(data.getKey().toLowerCase().equals(METADATA_SECTION_TAG_SECTION)) { - isMetadataSectionAvailable = true; - }else if (isMetadataSectionAvailable && !isLineExcluded(line)) { - - if (shouldStopProcessing(data, errors, lineNumber)) { - break; - } - - handleMetadataLine(metadata, errors, lineNumber, data); - } - } - - if (!isMetadataSectionAvailable) { - errors.add(new PnfCSARErrorEntryMissing(METADATA_SECTION_TAG_SECTION, this.fileName, -1)); - } - - return Pair.of(metadata, errors); - - } - - Pair, List> fetchSourcesSection() { - List sources = new ArrayList<>(); - List errors = new ArrayList<>(); - boolean isSpecialTagReached = false; - boolean sourceSectionParsing = false; - for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - String line = lines.get(lineNumber); - if (sourceSectionParsing && (startsWith(line, METADATA_SECTION_TAG_SECTION) || startsWith(line, NON_MANO_ARTIFACT_SETS_TAG_SECTION))) { - isSpecialTagReached = true; - }else if (!isSpecialTagReached && startsWith(line, SOURCE_TAG_SECTION)) { - sourceSectionParsing = true; - Pair data = parseLine(line); - - String value = data.getValue(); - if (value.isEmpty()) { - errors.add(new PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); - break; - } else { - sources.add(value); - } - } - } - - return Pair.of(sources, errors); - } - - Optional>>, List>> fetchNonManoArtifacts() { - Map>> nonManoArtifacts = new HashMap<>(); - List errors = new ArrayList<>(); - - boolean isNonManoArtifactsSectionAvailable = false; - String attributeName = null; - - for (String line : lines) { - - if (startsWith(line, NON_MANO_ARTIFACT_SETS_TAG_SECTION)) { - isNonManoArtifactsSectionAvailable = true; - } else if (isNonManoArtifactsSectionAvailable) { - Pair data = parseLine(line); + return this.metadataParser.parse(this.lines); - if (isNewSection(data)) { - attributeName = data.getKey(); - nonManoArtifacts.put(attributeName, new HashMap<>()); - continue; - } - - handleNonManoArtifactLine(nonManoArtifacts, attributeName, data); - } - } - - if (!isNonManoArtifactsSectionAvailable) { - return Optional.empty(); - } - - return Optional.of(Pair.of(nonManoArtifacts, errors)); - } - - private boolean isLineExcluded(String line) { - return line.trim().isEmpty() - || startsWith(line, "#") - || startsWith(line,SOURCE_TAG_SECTION); - } - - private boolean shouldStopProcessing(Pair data, List errors, int lineNumber) { - if (isNewSection(data) || data.getKey().toLowerCase().equals(SOURCE_TAG_SECTION)) { - if(!isSectionSupported(data.getKey())) { - errors.add(new PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); - } - return true; - } - return false; - } - - private boolean startsWith(String line, String word){ - return line.trim().toLowerCase().startsWith(word); } - private void handleMetadataLine( - CSARArchive.Manifest.Metadata metadata, - List errors, - int lineNumber, - Pair data) { - - String paramName = data.getKey(); - String value = data.getValue(); - - switch (paramName) { - case PRODUCT_NAME: - metadata.setProductName(value); - break; - case PROVIDER_ID: - metadata.setProviderId(value); - break; - case VERSION: - metadata.setPackageVersion(value); - break; - case RELEASE_DATE_TIME: - metadata.setReleaseDateTime(value); - break; - default: - errors.add(new PnfCSARErrorInvalidEntry( - paramName, - this.fileName, - lineNumber)); - break; - } + Pair, List> fetchSourcesSection() { + return this.sourcesParser.parse(this.lines); } - private void handleNonManoArtifactLine( - Map>> nonManoArtifacts, - String attributeName, - Pair data) { - - String key = data.getKey(); - String value = data.getValue(); - Map> attributeWithValues = nonManoArtifacts.getOrDefault(attributeName, new HashMap<>()); - List values = attributeWithValues.getOrDefault(key, new ArrayList<>()); - values.add(value); - attributeWithValues.put(key, values); - nonManoArtifacts.put(attributeName, attributeWithValues); - } - - private boolean isSectionSupported(String key) { - return Lists.newArrayList( - METADATA_SECTION_TAG_SECTION, - SOURCE_TAG_SECTION, - NON_MANO_ARTIFACT_SETS_TAG_SECTION).contains(key.toLowerCase()); + Optional>>, List>> fetchNonManoArtifacts() { + return this.nonManoArtifactsParser.parse(this.lines); } - private boolean isNewSection(Pair data) { - String key = data.getKey().trim(); - String value = data.getValue().trim(); - return key.matches("[a-zA-z_0-9]+") && (value.isEmpty() || startsWith(value,"#")); + Pair> fetchCMS() { + return this.cmsParser.parse(this.lines); } - - private Pair parseLine(String line) { - String[] elements = line.split(": "); - if (elements.length == 2) - return Pair.of(elements[0], elements[1]); - - if (line.endsWith(":")) - return Pair.of(line.substring(0, line.length() - 1), ""); - else - return Pair.of(line, ""); - - - } } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966.java new file mode 100644 index 0000000..2be0db8 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966.java @@ -0,0 +1,157 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.sol004; + + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.FileArchive; +import org.onap.cvc.csar.PnfCSARArchive; +import org.onap.cvc.csar.cc.VTPValidateCSARBase; +import org.onap.cvc.csar.parser.SourcesParser; +import org.onap.cvc.csar.security.ShaHashCodeGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Optional; + +@OnapCommandSchema(schema = "vtp-validate-csar-r787966.yaml") +public class VTPValidateCSARR787966 extends VTPValidateCSARBase { + + private static final Logger LOG = LoggerFactory.getLogger(VTPValidateCSARR787966.class); + private static final String SHA_256 = "SHA-256"; + private static final String SHA_512 = "SHA-512"; + + private final ShaHashCodeGenerator shaHashCodeGenerator = new ShaHashCodeGenerator(); + + + public static class CSARErrorUnableToFindCertificate extends CSARArchive.CSARError { + CSARErrorUnableToFindCertificate() { + super("0x4001"); + this.message = "Unable to find cert file defined by Entry-Certificate!"; + } + } + + public static class CSARErrorUnableToFindCmsSection extends CSARArchive.CSARError { + CSARErrorUnableToFindCmsSection() { + super("0x4002"); + this.message = "Unable to find CMS section in manifest!"; + } + } + + public static class CSARErrorUnableToFindCsarContent extends CSARArchive.CSARError { + CSARErrorUnableToFindCsarContent() { + super("0x4003"); + this.message = "Unable to find csar content!"; + } + } + + public static class CSARErrorWrongHashCode extends CSARArchive.CSARError { + CSARErrorWrongHashCode(String path) { + super("0x4004"); + this.message = String.format("Source '%s' has wrong hash!", path); + } + } + + public static class CSARErrorUnableToFindAlgorithm extends CSARArchive.CSARError { + CSARErrorUnableToFindAlgorithm(String path) { + super("0x4005"); + this.message = String.format("Source '%s' has hash, but unable to find algorithm tag!", path); + } + } + + @Override + protected void validateCSAR(CSARArchive csar) throws OnapCommandException { + + try { + FileArchive.Workspace workspace = csar.getWorkspace(); + final Optional pathToCsarFolder = workspace.getPathToCsarFolder(); + if(pathToCsarFolder.isPresent()) { + validate(csar, pathToCsarFolder.get()); + } else { + this.errors.add(new CSARErrorUnableToFindCsarContent()); + } + } catch (Exception e) { + LOG.error("Internal VTPValidateCSARR787966 command error", e); + throw new OnapCommandException("0x3000", "Internal VTPValidateCSARR787966 command error. See logs."); + } + + } + + private void validate(CSARArchive csar, Path csarRootDirectory ) throws IOException, NoSuchAlgorithmException { + + final PnfCSARArchive.PnfManifest manifest = (PnfCSARArchive.PnfManifest) csar.getManifest(); + final CSARArchive.TOSCAMeta toscaMeta = csar.getToscaMeta(); + validateSecurityStructure(toscaMeta, csarRootDirectory, manifest); + validateSources(csarRootDirectory, manifest); + } + + private void validateSecurityStructure(CSARArchive.TOSCAMeta toscaMeta , Path csarRootDirectory, PnfCSARArchive.PnfManifest manifest) { + final File entryCertificate = csarRootDirectory.resolve(toscaMeta.getEntryCertificate()).toFile(); + if (!entryCertificate.exists() && !manifest.getCms().isEmpty()) { + this.errors.add(new CSARErrorUnableToFindCertificate()); + } else if (entryCertificate.exists() && manifest.getCms().isEmpty()) { + this.errors.add(new CSARErrorUnableToFindCmsSection()); + } + } + + private void validateSources(Path csarRootDirectory, PnfCSARArchive.PnfManifest manifest) throws NoSuchAlgorithmException, IOException { + final List sources = manifest.getSources(); + for (SourcesParser.Source source: sources){ + if(!source.getAlgorithm().isEmpty()) { + validateSourceHashCode(csarRootDirectory, source); + } else if(source.getAlgorithm().isEmpty() && !source.getHash().isEmpty()){ + this.errors.add(new CSARErrorUnableToFindAlgorithm(source.getValue())); + } + } + } + + private void validateSourceHashCode(Path csarRootDirectory, SourcesParser.Source source) throws NoSuchAlgorithmException, IOException { + String hashCode = generateHashCode(csarRootDirectory, source); + if (!hashCode.equals(source.getHash())) { + this.errors.add(new CSARErrorWrongHashCode(source.getValue())); + } + } + + private String generateHashCode(Path csarRootDirectory, SourcesParser.Source source) throws NoSuchAlgorithmException, IOException { + final byte[] sourceData = Files.readAllBytes(csarRootDirectory.resolve(source.getValue())); + final String algorithm = source.getAlgorithm(); + + if(algorithm.equalsIgnoreCase(SHA_256)) { + return this.shaHashCodeGenerator.generateSha256(sourceData); + } else if(algorithm.equalsIgnoreCase(SHA_512)){ + return this.shaHashCodeGenerator.generateSha512(sourceData); + } + + throw new UnsupportedOperationException(String.format("Algorithm '%s' is not supported!", algorithm)); + } + + @Override + protected String getVnfReqsNo() { + return "R787966"; + } + + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/CmsParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/CmsParser.java new file mode 100644 index 0000000..b1bf4b4 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/CmsParser.java @@ -0,0 +1,89 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + +import org.apache.commons.lang3.tuple.Pair; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.PnfCSARError; + +import java.util.ArrayList; +import java.util.List; + +import static org.onap.cvc.csar.parser.ManifestConsts.*; + + +public class CmsParser { + + + private final String fileName; + + public CmsParser(String fileName) { + this.fileName = fileName; + } + + public Pair> parse(List lines){ + StringBuilder buf = new StringBuilder(); + List errors = new ArrayList<>(); + + boolean isSpecialTagReached = false; + boolean cmsSectionParsing = false; + boolean endCmsMarkerReached = false; + boolean atEndFile = true; + + + for (String line : lines) { + ManifestLine manifestLine = ManifestLine.of(line); + if (cmsSectionParsing && (manifestLine.startsWith(METADATA_SECTION_TAG_SECTION) + || manifestLine.startsWith(NON_MANO_ARTIFACT_SETS_TAG_SECTION) + || manifestLine.startsWith(SOURCE_TAG_SECTION))) { + isSpecialTagReached = true; + } else if (!isSpecialTagReached && line.contains(BEGIN_CMS_SECTION)) { + cmsSectionParsing = true; + } else if (!isSpecialTagReached && line.contains(END_CMS_SECTION)) { + if(!cmsSectionParsing){ + errors.add(new PnfCSARError.PnfCSARErrorInvalidEntry("Unable to find BEGIN CMS marker!", this.fileName, -1)); + break; + } + cmsSectionParsing = false; + endCmsMarkerReached = true; + } else if (cmsSectionParsing){ + buf.append(line); + } else if(endCmsMarkerReached) { + atEndFile = false; + } + } + + if(!atEndFile){ + errors.add(new PnfCSARError.PnfCSARErrorInvalidEntry("CMS section is not at the end of file!", this.fileName, -1)); + } + + return constructResponse(buf, errors, cmsSectionParsing, endCmsMarkerReached); + } + + private Pair> constructResponse(StringBuilder buf, List errors, boolean cmsSectionParsing, boolean endCmsMarkerReached) { + if(endCmsMarkerReached) { + return Pair.of(buf.toString(), errors); + } else if(cmsSectionParsing) { + errors.add(new PnfCSARError.PnfCSARErrorInvalidEntry("Unable to find END CMS marker!", this.fileName, -1)); + return Pair.of("",errors); + } else { + return Pair.of("",errors); + } + } + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestConsts.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestConsts.java new file mode 100644 index 0000000..da17317 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestConsts.java @@ -0,0 +1,38 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + + +final class ManifestConsts { + + private ManifestConsts(){} + + static final String METADATA_SECTION_TAG_SECTION = "metadata"; + static final String SOURCE_TAG_SECTION = "source"; + static final String ALGORITHM = "algorithm"; + static final String HASH = "hash"; + static final String NON_MANO_ARTIFACT_SETS_TAG_SECTION = "non_mano_artifact_sets"; + static final String PRODUCT_NAME = "pnfd_name"; + static final String PROVIDER_ID = "pnfd_provider"; + static final String VERSION = "pnfd_archive_version"; + static final String RELEASE_DATE_TIME = "pnfd_release_date_time"; + static final String CMS = "CMS"; + static final String BEGIN_CMS_SECTION = "BEGIN CMS"; + static final String END_CMS_SECTION = "END CMS"; + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestLine.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestLine.java new file mode 100644 index 0000000..390c534 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestLine.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + +import org.apache.commons.lang3.tuple.Pair; + +public class ManifestLine { + + private final String line; + + private ManifestLine(String line) { + this.line = line; + } + + public static ManifestLine of(String line) { + return new ManifestLine(line); + } + + public Pair parse() { + String[] elements = line.split(": "); + if (elements.length == 2) { + return Pair.of(elements[0], elements[1]); + } + + if (line.endsWith(":")) { + return Pair.of(line.substring(0, line.length() - 1), ""); + } else { + return Pair.of(line, ""); + } + + + } + + boolean startsWith(String word) { + return line.trim().toLowerCase().startsWith(word); + } + + boolean isEmpty() { + return line.trim().isEmpty(); + } + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/MetadataParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/MetadataParser.java new file mode 100644 index 0000000..b0c06ee --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/MetadataParser.java @@ -0,0 +1,135 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + +import com.google.common.collect.Lists; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.PnfCSARError; + +import java.util.ArrayList; +import java.util.List; + +import static org.onap.cvc.csar.parser.ManifestConsts.*; + +public class MetadataParser { + + private final String fileName; + + public MetadataParser(String fileName) { + this.fileName = fileName; + } + + public Pair> parse(List lines) { + CSARArchive.Manifest.Metadata metadata = new CSARArchive.Manifest.Metadata(); + List errors = new ArrayList<>(); + + boolean isMetadataSectionAvailable = false; + + for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + ManifestLine manifestLine = ManifestLine.of(line); + Pair data = manifestLine.parse(); + + if (data.getKey().equalsIgnoreCase(METADATA_SECTION_TAG_SECTION)) { + isMetadataSectionAvailable = true; + } else if (isMetadataSectionAvailable && !isLineExcluded(manifestLine)) { + + if (shouldStopProcessing(data, errors, lineNumber)) { + break; + } + + handleMetadataLine(metadata, errors, lineNumber, data); + } + } + + if (!isMetadataSectionAvailable) { + errors.add(new PnfCSARError.PnfCSARErrorEntryMissing(METADATA_SECTION_TAG_SECTION, this.fileName, -1)); + } + + return Pair.of(metadata, errors); + + } + + private boolean isLineExcluded(ManifestLine line) { + return line.isEmpty() + || line.startsWith("#") + || line.startsWith(SOURCE_TAG_SECTION); + } + + private boolean shouldStopProcessing(Pair data, List errors, int lineNumber) { + if (isNewSection(data) || isSourceSection(data)) { + if (!isSectionSupported(data.getKey())) { + errors.add(new PnfCSARError.PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); + } + return true; + } + return false; + } + + private boolean isNewSection(Pair data) { + String key = data.getKey().trim(); + String value = data.getValue().trim(); + return key.matches("[a-zA-z_0-9]+") && (value.isEmpty() || ManifestLine.of(value).startsWith("#")); + } + + private boolean isSourceSection(Pair data) { + return data.getKey().equalsIgnoreCase(SOURCE_TAG_SECTION) + || data.getKey().equalsIgnoreCase(ALGORITHM) + || data.getKey().equalsIgnoreCase(HASH); + } + + private boolean isSectionSupported(String key) { + return Lists.newArrayList( + METADATA_SECTION_TAG_SECTION, + SOURCE_TAG_SECTION, ALGORITHM, HASH, + NON_MANO_ARTIFACT_SETS_TAG_SECTION).contains(key.toLowerCase()); + } + + private void handleMetadataLine( + CSARArchive.Manifest.Metadata metadata, + List errors, + int lineNumber, + Pair data) { + + String paramName = data.getKey(); + String value = data.getValue(); + + switch (paramName) { + case PRODUCT_NAME: + metadata.setProductName(value); + break; + case PROVIDER_ID: + metadata.setProviderId(value); + break; + case VERSION: + metadata.setPackageVersion(value); + break; + case RELEASE_DATE_TIME: + metadata.setReleaseDateTime(value); + break; + default: + errors.add(new PnfCSARError.PnfCSARErrorInvalidEntry( + paramName, + this.fileName, + lineNumber)); + break; + } + } + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/NonManoArtifactsParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/NonManoArtifactsParser.java new file mode 100644 index 0000000..d27ef68 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/NonManoArtifactsParser.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + +import org.apache.commons.lang3.tuple.Pair; +import org.onap.cvc.csar.CSARArchive; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.onap.cvc.csar.parser.ManifestConsts.NON_MANO_ARTIFACT_SETS_TAG_SECTION; + +public class NonManoArtifactsParser { + + public Optional>>, List>> parse(List lines) { + Map>> nonManoArtifacts = new HashMap<>(); + List errors = new ArrayList<>(); + + boolean isNonManoArtifactsSectionAvailable = false; + String attributeName = null; + + for (String line : lines) { + ManifestLine manifestLine = ManifestLine.of(line); + if (manifestLine.startsWith(NON_MANO_ARTIFACT_SETS_TAG_SECTION)) { + isNonManoArtifactsSectionAvailable = true; + } else if (isNonManoArtifactsSectionAvailable) { + Pair data = manifestLine.parse(); + + if (isNewSection(data)) { + attributeName = data.getKey(); + nonManoArtifacts.put(attributeName, new HashMap<>()); + continue; + } + + handleNonManoArtifactLine(nonManoArtifacts, attributeName, data); + } + } + + if (!isNonManoArtifactsSectionAvailable) { + return Optional.empty(); + } + + return Optional.of(Pair.of(nonManoArtifacts, errors)); + } + + private boolean isNewSection(Pair data) { + String key = data.getKey().trim(); + String value = data.getValue().trim(); + return key.matches("[a-zA-z_0-9]+") && (value.isEmpty() || ManifestLine.of(value).startsWith("#")); + } + + private void handleNonManoArtifactLine( + Map>> nonManoArtifacts, + String attributeName, + Pair data) { + + String key = data.getKey(); + String value = data.getValue(); + + Map> attributeWithValues = nonManoArtifacts.getOrDefault(attributeName, new HashMap<>()); + List values = attributeWithValues.getOrDefault(key, new ArrayList<>()); + values.add(value); + attributeWithValues.put(key, values); + nonManoArtifacts.put(attributeName, attributeWithValues); + } + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/SourcesParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/SourcesParser.java new file mode 100644 index 0000000..5f3f0d7 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/SourcesParser.java @@ -0,0 +1,165 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.parser; + +import org.apache.commons.lang3.tuple.Pair; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.PnfCSARError; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static org.onap.cvc.csar.parser.ManifestConsts.*; + +public class SourcesParser { + + private final String fileName; + + public SourcesParser(String fileName) { + this.fileName = fileName; + } + + public Pair, List> parse(List lines) { + List sources = new ArrayList<>(); + List errors = new ArrayList<>(); + boolean isSpecialTagReached = false; + boolean sourceSectionParsing = false; + Source source = null; + + for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + ManifestLine manifestLine = ManifestLine.of(line); + if (sourceSectionParsing && (manifestLine.startsWith(METADATA_SECTION_TAG_SECTION) + || manifestLine.startsWith(NON_MANO_ARTIFACT_SETS_TAG_SECTION) + || line.contains(CMS))) { + isSpecialTagReached = true; + } else if (!isSpecialTagReached && manifestLine.startsWith(SOURCE_TAG_SECTION)) { + sourceSectionParsing = true; + source = handleSourceLine(sources, errors, lineNumber, manifestLine); + } else if (!isSpecialTagReached && manifestLine.startsWith(ALGORITHM)) { + handleAlgorithmLine(errors, source, lineNumber, manifestLine); + } else if (!isSpecialTagReached && manifestLine.startsWith(HASH)) { + handleHashLine(errors, source, lineNumber, manifestLine); + } + } + + return Pair.of(sources, errors); + } + + private Source handleSourceLine(List sources, List errors, int lineNumber, ManifestLine manifestLine) { + Source source; + String value = parseSourceSectionLine(manifestLine, lineNumber, errors); + if (!value.isEmpty()) { + source = new Source(value); + sources.add(source); + } else { + source = null; + } + return source; + } + + private void handleAlgorithmLine(List errors, Source source, int lineNumber, ManifestLine manifestLine) { + String algorithm = parseSourceSectionLine(manifestLine, lineNumber, errors); + if (source != null) + source.setAlgorithm(algorithm); + } + + private void handleHashLine(List errors, Source source, int lineNumber, ManifestLine manifestLine) { + String hash = parseSourceSectionLine(manifestLine, lineNumber, errors); + if (source != null) + source.setHash(hash); + } + + private String parseSourceSectionLine(ManifestLine line, int lineNumber, List errors) { + String retVal = ""; + Pair data = line.parse(); + + String value = data.getValue(); + if (value.isEmpty()) { + errors.add(new PnfCSARError.PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); + } else { + retVal = value; + } + + return retVal; + } + + public static class Source { + + + private final String value; + private String algorithm; + private String hash; + + public Source(String value, String algorithm, String hash) { + + this.value = value; + this.algorithm = algorithm; + this.hash = hash; + } + + public Source(String source) { + this(source, "", ""); + } + + public String getValue() { + return value; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Source source1 = (Source) o; + return Objects.equals(value, source1.value) && + Objects.equals(algorithm, source1.algorithm) && + Objects.equals(hash, source1.hash); + } + + @Override + public int hashCode() { + return Objects.hash(value, algorithm, hash); + } + + @Override + public String toString() { + return "Source{" + + "value='" + value + '\'' + + ", algorithm='" + algorithm + '\'' + + ", hash='" + hash + '\'' + + '}'; + } + } +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/security/ShaHashCodeGenerator.java b/csarvalidation/src/main/java/org/onap/cvc/csar/security/ShaHashCodeGenerator.java new file mode 100644 index 0000000..5b6b474 --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/security/ShaHashCodeGenerator.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.security; + +import org.bouncycastle.util.encoders.Hex; + + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class ShaHashCodeGenerator { + + public String generateSha256(byte[] source) throws NoSuchAlgorithmException { + final String algorithm = "SHA-256"; + return generateHashCode(source, algorithm); + } + + public String generateSha512(byte[] source) throws NoSuchAlgorithmException { + final String algorithm = "SHA-512"; + return generateHashCode(source, algorithm); + } + + private String generateHashCode(byte[] source, String algorithm) throws NoSuchAlgorithmException { + MessageDigest digest = MessageDigest.getInstance(algorithm); + byte[] hash = digest.digest(source); + return new String(Hex.encode(hash)); + } +} diff --git a/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand b/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand index 21c6af1..c6f2934 100644 --- a/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand +++ b/csarvalidation/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand @@ -47,4 +47,5 @@ org.onap.cvc.csar.cc.sol004.VTPValidateCSARR293901 org.onap.cvc.csar.cc.sol004.VTPValidateCSARR146092 org.onap.cvc.csar.cc.sol004.VTPValidateCSARR57019 org.onap.cvc.csar.cc.sol004.VTPValidateCSARR787965 +org.onap.cvc.csar.cc.sol004.VTPValidateCSARR787966 diff --git a/csarvalidation/src/main/resources/open-cli-schema/sol004/vtp-validate-csar-r787966.yaml b/csarvalidation/src/main/resources/open-cli-schema/sol004/vtp-validate-csar-r787966.yaml new file mode 100644 index 0000000..3b039a1 --- /dev/null +++ b/csarvalidation/src/main/resources/open-cli-schema/sol004/vtp-validate-csar-r787966.yaml @@ -0,0 +1,60 @@ +# Copyright 2019 Nokia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +open_cli_schema_version: 1.0 + +name: csar-validate-r787966 + +description: | + The VNF/PNF package shall contain a Digest (a.k.a. hash) for each of the components of the VNF/PNF package. The table of hashes is included in the manifest file, which is signed with the VNF provider private key. In addition, the VNF provider shall include a signing certificate that includes the VNF provider public key, following a pre-defined naming convention and located either at the root of the archive or in a predefined location (e.g. directory). + +info: + product: onap-vtp + version: 1.0 + service: validation + author: ONAP VTP Team onap-discuss@lists.onap.org + +parameters: + - name: csar + description: CSAR file path + long_option: csar + short_option: b + type: binary + is_optional: false + - name: pnf + description: CSAR file contains PNF + long_option: pnf + short_option: p + type: bool + is_optional: true + default_value: true +results: + direction: landscape + attributes: + - name: code + description: Error code + scope: short + type: string + - name: message + description: Error message + scope: short + type: string + - name: file + description: File in which error occured + scope: short + type: string + - name: line-no + description: Line no at which error occured + scope: short + type: string diff --git a/csarvalidation/src/main/resources/vnfreqs.properties b/csarvalidation/src/main/resources/vnfreqs.properties index cbb681d..b2ae957 100644 --- a/csarvalidation/src/main/resources/vnfreqs.properties +++ b/csarvalidation/src/main/resources/vnfreqs.properties @@ -1,5 +1,5 @@ vnfreqs.enabled=r02454,r04298,r07879,r09467,r13390,r23823,r26881,r27310,r35851,r40293,r43958,r66070,r77707,r77786,r87234,r10087,r21322,r26885,r40820,r35854,r65486,r17852,r46527,r15837,r54356,r67895,r95321,r32155,r01123,r51347,r787965 -pnfreqs.enabled=r10087,r87234,r35854,r15837,r17852,r293901,r146092,r57019,r787965 +pnfreqs.enabled=r10087,r87234,r35854,r15837,r17852,r293901,r146092,r57019,r787965,r787966 # ignored all chef and ansible related tests vnferrors.ignored=0x1005,0x1006,r07879-0x1000,r13390-0x1000,r27310-0x1000,r40293-0x1000,r77786-0x1000,r04298-0x1000,r07879-0x1000,r10087-0x1000,r13390-0x1000,r23823-0x1000,r26881-0x1000,r40820-0x1000,r35851-0x1000,r32155-0x1000,r54356-0x1000,r67895-0x1000,r95321-0x1000,r46527-0x1000,r02454-0x1000 pnferrors.ignored= \ No newline at end of file diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfCSARArchiveTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfCSARArchiveTest.java index 810ef0f..bc27ed1 100644 --- a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfCSARArchiveTest.java +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfCSARArchiveTest.java @@ -18,6 +18,7 @@ package org.onap.cvc.csar; import com.google.common.collect.Lists; import org.junit.Test; +import org.onap.cvc.csar.parser.SourcesParser; import java.util.List; import java.util.Map; @@ -26,7 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class PnfCSARArchiveTest { - public static final String SOURCE_TAG = "Source"; + private static final String SOURCE_TAG = "Source"; @Test public void shouldUseDataStoredInManifestMfFileToConfigurePnfCSARArchive() throws Exception { @@ -41,8 +42,10 @@ public class PnfCSARArchiveTest { // then PnfCSARArchive.PnfManifest manifest = (PnfCSARArchive.PnfManifest) pnfCSARArchive.getManifest(); verifyThatMetadataWasSet(manifest); + verifyThatCmsSectionWasSet(manifest); verifyThatSourcesSectionWasSet(manifest); verifyThatNonManoArtifactsWereSet(manifest); + assertThat(pnfCSARArchive.getErrors().size()).isEqualTo(0); } } @@ -57,8 +60,18 @@ public class PnfCSARArchiveTest { private void verifyThatSourcesSectionWasSet(PnfCSARArchive.PnfManifest manifest) { - List sources = manifest.getSources(); - assertThat(sources).contains("Definitions/MainServiceTemplate.yaml", "Definitions/etsi_nfv_sol001_vnfd_2_5_1_types.yaml"); + List sources = manifest.getSources(); + assertThat(sources).contains( + new SourcesParser.Source("MRF.yaml", "SHA-256", "09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943"), + new SourcesParser.Source("scripts/install.sh", "SHA-256", "d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b"), + new SourcesParser.Source("https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh", "SHA-256", "36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165") + ); + } + + private void verifyThatCmsSectionWasSet(PnfCSARArchive.PnfManifest manifest) { + + String cms = manifest.getCms(); + assertThat(cms).isEqualTo("MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcNAQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUMdvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0="); } private void verifyThatNonManoArtifactsWereSet(PnfCSARArchive.PnfManifest manifest) { diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfManifestParserTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfManifestParserTest.java index 09a2706..3ba37aa 100644 --- a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfManifestParserTest.java +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfManifestParserTest.java @@ -19,10 +19,10 @@ import com.google.common.collect.Lists; import org.apache.commons.lang3.tuple.Pair; import org.junit.Before; import org.junit.Test; +import org.onap.cvc.csar.parser.SourcesParser; import java.io.File; import java.io.IOException; -import java.net.URISyntaxException; import java.util.List; import java.util.Map; @@ -34,7 +34,7 @@ public class PnfManifestParserTest { private PnfManifestParser pnfManifestParser; @Before - public void setUp() throws URISyntaxException, IOException { + public void setUp() throws IOException { pnfManifestParser = PnfManifestParser.getInstance(new File("./src/test/resources/pnf/MainServiceTemplate.mf")); } @@ -42,7 +42,7 @@ public class PnfManifestParserTest { public void shouldFetchMetadataFromFile() { Pair> metadataListPair = pnfManifestParser.fetchMetadata(); CSARArchive.Manifest.Metadata metadata = metadataListPair.getKey(); - List errors= metadataListPair.getValue(); + List errors = metadataListPair.getValue(); assertThat(metadata.getProductName()).isEqualTo("RadioNode"); assertThat(metadata.getProviderId()).isEqualTo("Ericsson"); @@ -55,21 +55,41 @@ public class PnfManifestParserTest { @Test public void shouldFetchSourcesSectionFromFile() { - Pair, List> sourcesPair = pnfManifestParser.fetchSourcesSection(); - List sources = sourcesPair.getKey(); + Pair, List> sourcesPair = pnfManifestParser.fetchSourcesSection(); + List sources = sourcesPair.getKey(); List errors = sourcesPair.getValue(); - assertThat(sources).contains("Definitions/MainServiceTemplate.yaml", "Definitions/etsi_nfv_sol001_vnfd_2_5_1_types.yaml"); + assertThat(sources).contains( + new SourcesParser.Source("MRF.yaml", "SHA-256", "09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943"), + new SourcesParser.Source("scripts/install.sh", "SHA-256", "d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b"), + new SourcesParser.Source("https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh", "SHA-256", "36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165") + ); assertThat(errors.size()).isEqualTo(0); } + @Test + public void shouldFetchSourcesFromBrokenFile() throws IOException { + + pnfManifestParser = PnfManifestParser.getInstance(new File("./src/test/resources/pnf/MainServiceTemplateWithBrokenSourcesSection.mf")); + Pair, List> sourcesPair = pnfManifestParser.fetchSourcesSection(); + List sources = sourcesPair.getKey(); + List errors = sourcesPair.getValue(); + + assertThat(sources).contains( + new SourcesParser.Source("MRF.yaml", "SHA-256", "09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943"), + new SourcesParser.Source("some_file.sh", "", ""), + new SourcesParser.Source("scripts/install.sh", "", "d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b"), + new SourcesParser.Source("https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh", "SHA-256", "")); + assertThat(errors.size()).isEqualTo(0); + } + @Test public void shouldFetchNonManoArtifactsFromFile() { Pair>>, List> mapListPair = pnfManifestParser.fetchNonManoArtifacts().get(); Map>> nonManoArtifacts = mapListPair.getKey(); - List errors= mapListPair.getValue(); + List errors = mapListPair.getValue(); assertThat(nonManoArtifacts.get("onap_ves_events").get("source")) .isEqualTo(Lists.newArrayList("Artifacts/Events/VES_registration.yml") @@ -90,4 +110,56 @@ public class PnfManifestParserTest { ); assertThat(errors.size()).isEqualTo(0); } + + + @Test + public void shouldFetchCMS() { + + Pair> sourcesPair = pnfManifestParser.fetchCMS(); + String cms = sourcesPair.getKey(); + List errors = sourcesPair.getValue(); + + assertThat(cms).isEqualTo( + "MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN" + + "AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM" + + "dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0=" + ); + assertThat(errors.size()).isEqualTo(0); + } + + @Test + public void shouldReportAnErrorWhenCMSSectionDoesNotHaveEndingMarker() throws IOException { + pnfManifestParser = PnfManifestParser.getInstance(new File("./src/test/resources/pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf")); + Pair> sourcesPair = pnfManifestParser.fetchCMS(); + String cms = sourcesPair.getKey(); + List errors = sourcesPair.getValue(); + + assertThat(cms).isEmpty(); + assertThat(errors.size()).isEqualTo(1); + assertThat(errors.get(0).getMessage()).isEqualTo("Invalid. Entry [Unable to find END CMS marker!]"); + } + + @Test + public void shouldReturnEmptyCmsWhenBeginMarkerDoesNotExist() throws IOException { + pnfManifestParser = PnfManifestParser.getInstance(new File("./src/test/resources/pnf/MainServiceTemplateBrokenCMSNoBeginMarker.mf")); + Pair> sourcesPair = pnfManifestParser.fetchCMS(); + String cms = sourcesPair.getKey(); + List errors = sourcesPair.getValue(); + + assertThat(cms).isEmpty(); + assertThat(errors.size()).isEqualTo(1); + assertThat(errors.get(0).getMessage()).isEqualTo("Invalid. Entry [Unable to find BEGIN CMS marker!]"); + } + + + @Test + public void shouldReportAnErrorWhenCMSIsNotAtTheEndOfFile() throws IOException { + pnfManifestParser = PnfManifestParser.getInstance(new File("./src/test/resources/pnf/MainServiceTemplateCMSSectionNotAtTheEnd.mf")); + Pair> sourcesPair = pnfManifestParser.fetchCMS(); + + List errors = sourcesPair.getValue(); + + assertThat(errors.size()).isEqualTo(1); + assertThat(errors.get(0).getMessage()).isEqualTo("Invalid. Entry [CMS section is not at the end of file!]"); + } } \ No newline at end of file diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfMetadataParserTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfMetadataParserTest.java index 3d46334..c409efc 100644 --- a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfMetadataParserTest.java +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfMetadataParserTest.java @@ -18,6 +18,10 @@ package org.onap.cvc.csar; import com.google.common.collect.Lists; import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; +import org.onap.cvc.csar.parser.CmsParser; +import org.onap.cvc.csar.parser.MetadataParser; +import org.onap.cvc.csar.parser.NonManoArtifactsParser; +import org.onap.cvc.csar.parser.SourcesParser; import java.util.List; import java.util.stream.Collectors; @@ -26,6 +30,8 @@ import static org.assertj.core.api.Assertions.assertThat; public class PnfMetadataParserTest { + private static final String FILE_NAME = "fileName"; + @Test public void shouldReportAnErrorWhenMetadataSectionIsNotAvailable() { // given @@ -38,7 +44,13 @@ public class PnfMetadataParserTest { // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair> data = pnfManifestParser.fetchMetadata(); //then @@ -64,7 +76,13 @@ public class PnfMetadataParserTest { ); // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair> data = pnfManifestParser.fetchMetadata(); //then @@ -93,7 +111,13 @@ public class PnfMetadataParserTest { ); // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair> data = pnfManifestParser.fetchMetadata(); //then @@ -118,7 +142,13 @@ public class PnfMetadataParserTest { ); // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair> data = pnfManifestParser.fetchMetadata(); //then @@ -142,7 +172,13 @@ public class PnfMetadataParserTest { ); // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair> data = pnfManifestParser.fetchMetadata(); //then diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfNonManoArtifactsParserTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfNonManoArtifactsParserTest.java index 92733bb..388a98f 100644 --- a/csarvalidation/src/test/java/org/onap/cvc/csar/PnfNonManoArtifactsParserTest.java +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/PnfNonManoArtifactsParserTest.java @@ -18,6 +18,10 @@ package org.onap.cvc.csar; import com.google.common.collect.Lists; import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; +import org.onap.cvc.csar.parser.CmsParser; +import org.onap.cvc.csar.parser.MetadataParser; +import org.onap.cvc.csar.parser.NonManoArtifactsParser; +import org.onap.cvc.csar.parser.SourcesParser; import java.util.List; import java.util.Map; @@ -27,6 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat; public class PnfNonManoArtifactsParserTest { + private static final String FILE_NAME = "fileName"; + @Test public void shouldDoNotReportAnErrorWhenNonManoArtifactSectionIsNotAvailable() { // given @@ -39,7 +45,13 @@ public class PnfNonManoArtifactsParserTest { // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Optional>>, List>> nonManoArtifacts = pnfManifestParser.fetchNonManoArtifacts(); @@ -65,7 +77,13 @@ public class PnfNonManoArtifactsParserTest { ); // when - PnfManifestParser pnfManifestParser = new PnfManifestParser(lines, "fileName"); + PnfManifestParser pnfManifestParser = new PnfManifestParser( + lines, + new MetadataParser(FILE_NAME), + new SourcesParser(FILE_NAME), + new NonManoArtifactsParser(), + new CmsParser(FILE_NAME) + ); Pair>>, List> data = pnfManifestParser.fetchNonManoArtifacts().get(); //then diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966IntegrationTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966IntegrationTest.java new file mode 100644 index 0000000..eccfe4b --- /dev/null +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR787966IntegrationTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.sol004; + +import org.junit.Before; +import org.junit.Test; +import org.onap.cvc.csar.CSARArchive; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.onap.cvc.csar.cc.sol004.IntegrationTestUtils.configureTestCase; +import static org.onap.cvc.csar.cc.sol004.IntegrationTestUtils.convertToMessagesList; + + +public class VTPValidateCSARR787966IntegrationTest { + + private VTPValidateCSARR787966 testCase; + + @Before + public void setUp() { + testCase = new VTPValidateCSARR787966(); + } + + @Test + public void shouldReturnProperRequestNumber() { + assertThat(testCase.getVnfReqsNo()).isEqualTo("R787966"); + } + + @Test + public void shouldValidateProperCsar() throws Exception { + + // given + configureTestCase(testCase, "pnf/r787966/csar-option1-valid.csar"); + + // when + testCase.execute(); + + // then + List errors = testCase.getErrors(); + assertThat(errors.size()).isEqualTo(0); + } + + @Test + public void shouldReportErrorsForInvalidCsar() throws Exception { + + // given + configureTestCase(testCase, "pnf/r787966/csar-option1-invalid.csar"); + + // when + testCase.execute(); + + // then + List errors = testCase.getErrors(); + assertThat(errors.size()).isEqualTo(3); + assertThat(convertToMessagesList(errors)).contains( + "Unable to find CMS section in manifest!", + "Source 'Definitions/MainServiceTemplate.yaml' has wrong hash!", + "Source 'Artifacts/Other/my_script.csh' has hash, but unable to find algorithm tag!" + ); + } + + +} \ No newline at end of file diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/security/ShaHashCodeGeneratorTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/security/ShaHashCodeGeneratorTest.java new file mode 100644 index 0000000..1ea5dd5 --- /dev/null +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/security/ShaHashCodeGeneratorTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 Nokia + *

+ * 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.security; + + +import org.junit.Before; +import org.junit.Test; + +import java.security.NoSuchAlgorithmException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ShaHashCodeGeneratorTest { + + private ShaHashCodeGenerator shaHashCodeGenerator; + + @Before + public void setUp(){ + shaHashCodeGenerator = new ShaHashCodeGenerator(); + } + + @Test + public void shouldGenerateHashCodeSHA256() throws NoSuchAlgorithmException { + + final String hashCode = shaHashCodeGenerator.generateSha256("test".getBytes()); + + assertThat(hashCode).isEqualTo(shaHashCodeGenerator.generateSha256("test".getBytes())); + assertThat(hashCode).isNotEqualTo(shaHashCodeGenerator.generateSha256("Test".getBytes())); + } + + @Test + public void shouldGenerateHashCodeSHA512() throws NoSuchAlgorithmException { + + final String hashCode = shaHashCodeGenerator.generateSha512("test".getBytes()); + + assertThat(hashCode).isEqualTo(shaHashCodeGenerator.generateSha512("test".getBytes())); + assertThat(hashCode).isNotEqualTo(shaHashCodeGenerator.generateSha512("Test".getBytes())); + } +} \ No newline at end of file diff --git a/csarvalidation/src/test/resources/pnf/MainServiceTemplate.mf b/csarvalidation/src/test/resources/pnf/MainServiceTemplate.mf index 4ffa857..6987eb1 100644 --- a/csarvalidation/src/test/resources/pnf/MainServiceTemplate.mf +++ b/csarvalidation/src/test/resources/pnf/MainServiceTemplate.mf @@ -5,8 +5,17 @@ metadata: pnfd_release_date_time: 2019-01-14T11:25:00+00:00 #The manifest file shall include a list of all files contained in or referenced from the VNF package with their location -source: Definitions/MainServiceTemplate.yaml -source: Definitions/etsi_nfv_sol001_vnfd_2_5_1_types.yaml +Source: MRF.yaml +Algorithm: SHA-256 +Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943 + +Source: scripts/install.sh +Algorithm: SHA-256 +Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b + +Source: https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh +Algorithm: SHA-256 +Hash: 36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165 non_mano_artifact_sets: @@ -25,3 +34,8 @@ non_mano_artifact_sets: source: Artifacts/Other/installation_guide.txt source: Artifacts/Other/review_log.txt +-----BEGIN CMS----- +MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN +AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM +dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0= +-----END CMS----- \ No newline at end of file diff --git a/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoBeginMarker.mf b/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoBeginMarker.mf new file mode 100644 index 0000000..071588b --- /dev/null +++ b/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoBeginMarker.mf @@ -0,0 +1,41 @@ +metadata: + pnfd_name: RadioNode + pnfd_provider: Ericsson + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2019-01-14T11:25:00+00:00 + +#The manifest file shall include a list of all files contained in or referenced from the VNF package with their location +Source: MRF.yaml +Algorithm: SHA-256 +Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943 + +Source: scripts/install.sh +Algorithm: SHA-256 +Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b + +Source: https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh +Algorithm: SHA-256 +Hash: 36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165 + +MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN +AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM +dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0= +-----END CMS----- + +non_mano_artifact_sets: + + onap_ves_events: + source: Artifacts/Events/VES_registration.yml + + onap_pm_dictionary: + source: Artifacts/Measurements/PM_Dictionary.yaml + + onap_yang_module: + source: Artifacts/Yang_module/Yang_module.yaml + + onap_others: + source: Artifacts/scripts/install.sh + source: Artifacts/Informational/user_guide.txt + source: Artifacts/Other/installation_guide.txt + source: Artifacts/Other/review_log.txt + diff --git a/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf b/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf new file mode 100644 index 0000000..66f93b8 --- /dev/null +++ b/csarvalidation/src/test/resources/pnf/MainServiceTemplateBrokenCMSNoEndMarker.mf @@ -0,0 +1,41 @@ +metadata: + pnfd_name: RadioNode + pnfd_provider: Ericsson + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2019-01-14T11:25:00+00:00 + +#The manifest file shall include a list of all files contained in or referenced from the VNF package with their location +Source: MRF.yaml +Algorithm: SHA-256 +Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943 + +Source: scripts/install.sh +Algorithm: SHA-256 +Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b + +Source: https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh +Algorithm: SHA-256 +Hash: 36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165 + +-----BEGIN CMS----- +MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN +AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM +dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0= + +non_mano_artifact_sets: + + onap_ves_events: + source: Artifacts/Events/VES_registration.yml + + onap_pm_dictionary: + source: Artifacts/Measurements/PM_Dictionary.yaml + + onap_yang_module: + source: Artifacts/Yang_module/Yang_module.yaml + + onap_others: + source: Artifacts/scripts/install.sh + source: Artifacts/Informational/user_guide.txt + source: Artifacts/Other/installation_guide.txt + source: Artifacts/Other/review_log.txt + diff --git a/csarvalidation/src/test/resources/pnf/MainServiceTemplateCMSSectionNotAtTheEnd.mf b/csarvalidation/src/test/resources/pnf/MainServiceTemplateCMSSectionNotAtTheEnd.mf new file mode 100644 index 0000000..95890ae --- /dev/null +++ b/csarvalidation/src/test/resources/pnf/MainServiceTemplateCMSSectionNotAtTheEnd.mf @@ -0,0 +1,41 @@ +metadata: + pnfd_name: RadioNode + pnfd_provider: Ericsson + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2019-01-14T11:25:00+00:00 + +#The manifest file shall include a list of all files contained in or referenced from the VNF package with their location +Source: MRF.yaml +Algorithm: SHA-256 +Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943 + +Source: scripts/install.sh +Algorithm: SHA-256 +Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b + +Source: https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh +Algorithm: SHA-256 +Hash: 36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165 + +-----BEGIN CMS----- +MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN +AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM +dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0= +-----END CMS----- + +non_mano_artifact_sets: + + onap_ves_events: + source: Artifacts/Events/VES_registration.yml + + onap_pm_dictionary: + source: Artifacts/Measurements/PM_Dictionary.yaml + + onap_yang_module: + source: Artifacts/Yang_module/Yang_module.yaml + + onap_others: + source: Artifacts/scripts/install.sh + source: Artifacts/Informational/user_guide.txt + source: Artifacts/Other/installation_guide.txt + source: Artifacts/Other/review_log.txt diff --git a/csarvalidation/src/test/resources/pnf/MainServiceTemplateWithBrokenSourcesSection.mf b/csarvalidation/src/test/resources/pnf/MainServiceTemplateWithBrokenSourcesSection.mf new file mode 100644 index 0000000..c649d11 --- /dev/null +++ b/csarvalidation/src/test/resources/pnf/MainServiceTemplateWithBrokenSourcesSection.mf @@ -0,0 +1,37 @@ +metadata: + pnfd_name: RadioNode + pnfd_provider: Ericsson + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2019-01-14T11:25:00+00:00 + +#The manifest file shall include a list of all files contained in or referenced from the VNF package with their location +Source: MRF.yaml +Algorithm: SHA-256 +Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943 + +Source: scripts/install.sh +Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b + +Source: https://www.vendor_org.com/MRF/v4.1/scripts/scale/scale.sh +Algorithm: SHA-256 + +Source: some_file.sh + + +non_mano_artifact_sets: + + onap_ves_events: + source: Artifacts/Events/VES_registration.yml + + onap_pm_dictionary: + source: Artifacts/Measurements/PM_Dictionary.yaml + + onap_yang_module: + source: Artifacts/Yang_module/Yang_module.yaml + + onap_others: + source: Artifacts/scripts/install.sh + source: Artifacts/Informational/user_guide.txt + source: Artifacts/Other/installation_guide.txt + source: Artifacts/Other/review_log.txt + diff --git a/csarvalidation/src/test/resources/pnf/dummyPnfv2.csar b/csarvalidation/src/test/resources/pnf/dummyPnfv2.csar index bf2d912..b4afde4 100644 Binary files a/csarvalidation/src/test/resources/pnf/dummyPnfv2.csar and b/csarvalidation/src/test/resources/pnf/dummyPnfv2.csar differ diff --git a/csarvalidation/src/test/resources/pnf/r787966/csar-option1-invalid.csar b/csarvalidation/src/test/resources/pnf/r787966/csar-option1-invalid.csar new file mode 100644 index 0000000..8433043 Binary files /dev/null and b/csarvalidation/src/test/resources/pnf/r787966/csar-option1-invalid.csar differ diff --git a/csarvalidation/src/test/resources/pnf/r787966/csar-option1-valid.csar b/csarvalidation/src/test/resources/pnf/r787966/csar-option1-valid.csar new file mode 100644 index 0000000..385595d Binary files /dev/null and b/csarvalidation/src/test/resources/pnf/r787966/csar-option1-valid.csar differ -- cgit 1.2.3-korg