From e0437a4237c99a16955d5ec56ff5fe9996c76b57 Mon Sep 17 00:00:00 2001 From: Remigiusz Janeczek Date: Tue, 16 Mar 2021 16:00:26 +0100 Subject: Add helm validator sources Issue-ID: SDC-3185 Signed-off-by: Remigiusz Janeczek Change-Id: I32dea3b4294a90c4dfc75864fb4200f044e7a0b6 --- .../helmvalidator/HelmValidatorApplication.java | 33 +++ .../api/SupportedVersionsController.java | 52 +++++ .../helmvalidator/api/ValidationController.java | 68 +++++++ .../errorhandling/ValidationErrorHandler.java | 129 ++++++++++++ .../errorhandling/ValidationErrorResponse.java | 34 ++++ .../helm/validation/BashExecutor.java | 69 +++++++ .../helmvalidator/helm/validation/FileManager.java | 72 +++++++ .../helm/validation/ValidationService.java | 221 +++++++++++++++++++++ .../exception/BashExecutionException.java | 28 +++ .../exception/NotSupportedVersionException.java | 28 +++ .../validation/exception/SaveFileException.java | 28 +++ .../helm/validation/model/BashOutput.java | 43 ++++ .../validation/model/LintValidationResult.java | 55 +++++ .../validation/model/TemplateValidationResult.java | 48 +++++ .../helm/validation/model/ValidationResult.java | 98 +++++++++ .../helm/versions/ApiVersionsReader.java | 80 ++++++++ .../helm/versions/ChartBasedVersionProvider.java | 57 ++++++ .../helm/versions/SupportedVersionsProvider.java | 65 ++++++ .../helm/versions/SystemEnvVersionsReader.java | 47 +++++ .../exception/ApiVersionNotFoundException.java | 29 +++ .../exception/NotSupportedApiVersionException.java | 28 +++ .../helm/versions/exception/ReadFileException.java | 28 +++ src/main/resources/application.properties | 4 + 23 files changed, 1344 insertions(+) create mode 100644 src/main/java/org/onap/sdc/helmvalidator/HelmValidatorApplication.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/api/SupportedVersionsController.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/api/ValidationController.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorHandler.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorResponse.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/BashExecutor.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/FileManager.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/ValidationService.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/BashExecutionException.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/NotSupportedVersionException.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/SaveFileException.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/BashOutput.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/LintValidationResult.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/TemplateValidationResult.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/ValidationResult.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/ApiVersionsReader.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/ChartBasedVersionProvider.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/SupportedVersionsProvider.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/SystemEnvVersionsReader.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ApiVersionNotFoundException.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/NotSupportedApiVersionException.java create mode 100644 src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ReadFileException.java create mode 100644 src/main/resources/application.properties (limited to 'src/main') diff --git a/src/main/java/org/onap/sdc/helmvalidator/HelmValidatorApplication.java b/src/main/java/org/onap/sdc/helmvalidator/HelmValidatorApplication.java new file mode 100644 index 0000000..b8bed69 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/HelmValidatorApplication.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class HelmValidatorApplication { + + public static void main(String[] args) { + SpringApplication.run(HelmValidatorApplication.class, args); + } + +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/api/SupportedVersionsController.java b/src/main/java/org/onap/sdc/helmvalidator/api/SupportedVersionsController.java new file mode 100644 index 0000000..1a92624 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/api/SupportedVersionsController.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.api; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.onap.sdc.helmvalidator.helm.versions.SupportedVersionsProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SupportedVersionsController { + + private final SupportedVersionsProvider versionsProvider; + + @Autowired + public SupportedVersionsController(SupportedVersionsProvider provider) { + this.versionsProvider = provider; + } + + @GetMapping("/versions") + public ResponseEntity>> supportedVersions() { + return mapVersionsToResponseEntity(versionsProvider.getVersions()); + } + + private ResponseEntity>> mapVersionsToResponseEntity(List versions) { + + return new ResponseEntity<>(Collections.singletonMap("versions", versions), HttpStatus.OK); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/api/ValidationController.java b/src/main/java/org/onap/sdc/helmvalidator/api/ValidationController.java new file mode 100644 index 0000000..a4e476c --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/api/ValidationController.java @@ -0,0 +1,68 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.api; + +import org.onap.sdc.helmvalidator.helm.validation.ValidationService; +import org.onap.sdc.helmvalidator.helm.validation.model.ValidationResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController +public class ValidationController { + + private static final Logger LOGGER = LoggerFactory.getLogger(ValidationController.class); + + private final ValidationService validationService; + + @Autowired + public ValidationController(ValidationService validationService) { + this.validationService = validationService; + } + + /** + * Validates Helm chart. + * + * @param version requested version of Helm client to be used + * @param file packaged Helm chart file + * @param isLinted flag deciding if chart should be linted + * @param isStrictLinted flag deciding if chart should be linted with strict option turned on + * @return Response with result of validation + */ + @PostMapping("/validate") + public ResponseEntity validate( + @RequestParam(value = "versionDesired", required = false) String version, + @RequestParam("file") MultipartFile file, + @RequestParam(value = "isLinted", required = false, defaultValue = "false") boolean isLinted, + @RequestParam(value = "isStrictLinted", required = false, defaultValue = "false") boolean isStrictLinted) { + LOGGER.debug("Received file: {}, size: {}, helm version: {}", + file.getOriginalFilename(), file.getSize(), version); + ValidationResult result = validationService + .process(version, file, isLinted, isStrictLinted); + return new ResponseEntity<>(result, HttpStatus.OK); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorHandler.java b/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorHandler.java new file mode 100644 index 0000000..332a923 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorHandler.java @@ -0,0 +1,129 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.errorhandling; + +import org.onap.sdc.helmvalidator.api.ValidationController; +import org.onap.sdc.helmvalidator.helm.validation.exception.BashExecutionException; +import org.onap.sdc.helmvalidator.helm.validation.exception.NotSupportedVersionException; +import org.onap.sdc.helmvalidator.helm.validation.exception.SaveFileException; +import org.onap.sdc.helmvalidator.helm.versions.exception.ApiVersionNotFoundException; +import org.onap.sdc.helmvalidator.helm.versions.exception.NotSupportedApiVersionException; +import org.onap.sdc.helmvalidator.helm.versions.exception.ReadFileException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice(assignableTypes = ValidationController.class) +public class ValidationErrorHandler { + + /** + * BashExecutionException handler. + * + * @param exception Exception that occurs during execution of bash command + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = BashExecutionException.class) + public ResponseEntity handle(BashExecutionException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + /** + * SaveFileException handler. + * + * @param exception Exception that occurs during file saving + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = SaveFileException.class) + public ResponseEntity handle(SaveFileException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + /** + * NotSupportedVersionException handler. + * + * @param exception Exception that occurs when not supported Helm version is requested for validation + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = NotSupportedVersionException.class) + public ResponseEntity handle(NotSupportedVersionException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.BAD_REQUEST + ); + } + + /** + * ApiVersionNotFoundException handler. + * + * @param exception Exception that occurs when API version cannot be derived from Helm chart + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = ApiVersionNotFoundException.class) + public ResponseEntity handle(ApiVersionNotFoundException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.BAD_REQUEST + ); + } + + /** + * NotSupportedApiVersionException handler. + * + * @param exception Exception that occurs when API version from Helm chart is not supported + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = NotSupportedApiVersionException.class) + public ResponseEntity handle(NotSupportedApiVersionException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.BAD_REQUEST + ); + } + + /** + * ReadFileException handler. + * + * @param exception Exception that occurs during reading of Helm chart + * @return ResponseEntity with ValidationErrorResponse created from given exception + */ + @ExceptionHandler(value = ReadFileException.class) + public ResponseEntity handle(ReadFileException exception) { + return getErrorResponseEntity( + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + private ResponseEntity getErrorResponseEntity(String errorMessage, HttpStatus status) { + ValidationErrorResponse errorResponse = new ValidationErrorResponse(errorMessage); + return new ResponseEntity<>( + errorResponse, + status + ); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorResponse.java b/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorResponse.java new file mode 100644 index 0000000..0f1fded --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/errorhandling/ValidationErrorResponse.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.errorhandling; + +class ValidationErrorResponse { + + private final String message; + + ValidationErrorResponse(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/BashExecutor.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/BashExecutor.java new file mode 100644 index 0000000..0bebc0a --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/BashExecutor.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; +import java.util.stream.Collectors; +import org.onap.sdc.helmvalidator.helm.validation.exception.BashExecutionException; +import org.onap.sdc.helmvalidator.helm.validation.model.BashOutput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class BashExecutor { + + private static final Logger LOGGER = LoggerFactory.getLogger( + ValidationService.class); + + BashOutput execute(String helmCommand) { + + try { + ProcessBuilder pb = new ProcessBuilder("bash", "-c", helmCommand); + pb.redirectErrorStream(true); + LOGGER.debug("Start process"); + Process process = pb.start(); + + List processOutput = readOutputAndCloseProcess(process); + return new BashOutput(process.exitValue(), processOutput); + } catch (IOException | InterruptedException e) { + throw new BashExecutionException("Error during bash execution: ", e); + } + } + + private List readOutputAndCloseProcess(Process process) throws IOException, InterruptedException { + + final InputStream inputStream = process.getInputStream(); + final List lines = new BufferedReader(new InputStreamReader(inputStream)) + .lines().collect(Collectors.toList()); + + // For compatibility with Helm2 and Helm3 + process.waitFor(); + inputStream.close(); + process.destroy(); + + return lines; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/FileManager.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/FileManager.java new file mode 100644 index 0000000..3617df7 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/FileManager.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.time.Instant; +import org.onap.sdc.helmvalidator.helm.validation.exception.SaveFileException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +@Service +public class FileManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(FileManager.class); + private final String basePath; + + @Autowired + FileManager(@Value("${app.config.charts-base-path}") String basePath) { + this.basePath = basePath; + } + + String saveFile(MultipartFile file) { + LOGGER.debug("Base PATH: {}", basePath); + try { + String filePath = basePath + File.separator + generateFileName(file.getOriginalFilename()); + LOGGER.info("Attempt to save file : {}", filePath); + Files.copy(file.getInputStream(), Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING); + return filePath; + } catch (IOException e) { + throw new SaveFileException("Cannot save file: " + file.getOriginalFilename(), e); + } + } + + void removeFile(String path) { + try { + LOGGER.debug("Attempt to delete file : {}", path); + Files.deleteIfExists(Paths.get(path)); + } catch (IOException e) { + LOGGER.warn("Cannot delete file: {}, Exception: {}", path, e.getStackTrace()); + } + } + + private String generateFileName(String fileName) { + return Instant.now().toEpochMilli() + "_" + fileName; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/ValidationService.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/ValidationService.java new file mode 100644 index 0000000..1e6cedb --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/ValidationService.java @@ -0,0 +1,221 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.onap.sdc.helmvalidator.helm.validation.exception.BashExecutionException; +import org.onap.sdc.helmvalidator.helm.validation.exception.NotSupportedVersionException; +import org.onap.sdc.helmvalidator.helm.validation.model.BashOutput; +import org.onap.sdc.helmvalidator.helm.validation.model.LintValidationResult; +import org.onap.sdc.helmvalidator.helm.validation.model.TemplateValidationResult; +import org.onap.sdc.helmvalidator.helm.validation.model.ValidationResult; +import org.onap.sdc.helmvalidator.helm.versions.ChartBasedVersionProvider; +import org.onap.sdc.helmvalidator.helm.versions.SupportedVersionsProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +@Service +public class ValidationService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ValidationService.class); + private static final String TEMPLATE_OPTION = "template"; + private static final String LINT_OPTION = "lint"; + private static final String HELM_SUMMARY_MESSAGE_PATTERN = + "Error: \\d* chart\\(s\\) linted, \\d* chart\\(s\\) failed"; + private static final boolean INVALID_RESULT = false; + + private final FileManager fileManager; + + private final BashExecutor executor; + + private final SupportedVersionsProvider supportedVersionsProvider; + + private final ChartBasedVersionProvider chartBasedVersionProvider; + + + /** + * Constructor for ValidationService. + * + * @param fileManager object responsible for file manging + * @param executor object responsible for running shell commands + * @param supportedVersionsProvider object providing supported versions of Helm + * @param chartBasedVersionProvider object allowing to derive Helm version from a chart + */ + @Autowired + public ValidationService( + FileManager fileManager, BashExecutor executor, + SupportedVersionsProvider supportedVersionsProvider, + ChartBasedVersionProvider chartBasedVersionProvider) { + this.fileManager = fileManager; + this.executor = executor; + this.supportedVersionsProvider = supportedVersionsProvider; + this.chartBasedVersionProvider = chartBasedVersionProvider; + } + + /** + * Process Helm chart package with given options. + * + * @param desiredVersion requested version of Helm client to be used + * @param file packaged Helm chart file + * @param isLinted flag deciding if chart should be linted + * @param isStrictLinted flag deciding if chart should be linted with strict option turned on + * @return Result of Helm chart validation + */ + public ValidationResult process(String desiredVersion, MultipartFile file, boolean isLinted, + boolean isStrictLinted) { + String chartPath = fileManager.saveFile(file); + try { + String helmVersion = getSupportedHelmVersion(desiredVersion, chartPath); + return validateChart(helmVersion, file, isLinted, isStrictLinted, chartPath); + } finally { + LOGGER.info("File process finished"); + fileManager.removeFile(chartPath); + } + } + + private String getSupportedHelmVersion(String desiredVersion, String chartPath) { + String helmVersion = getHelmVersion(desiredVersion, chartPath); + + if (isNotSupportedVersion(helmVersion)) { + throw new NotSupportedVersionException(helmVersion); + } + + return helmVersion; + } + + private String getHelmVersion(String desiredVersion, String chartPath) { + if (desiredVersion == null) { + return chartBasedVersionProvider.getVersion(chartPath); + } + + if (desiredVersion.startsWith("v")) { + String helmMajorVersion = desiredVersion.substring(1); + return supportedVersionsProvider.getLatestVersion(helmMajorVersion); + } + + return desiredVersion; + } + + private ValidationResult validateChart(String version, MultipartFile file, boolean isLinted, boolean isStrictLinted, + String chartPath) { + LOGGER.info("Start validation of file: {}, with helm version: {}", + file.getOriginalFilename(), version); + + TemplateValidationResult templateValidationResult = runHelmTemplate( + buildHelmTemplateCommand(version, chartPath)); + LOGGER.info("Helm template finished"); + + if (isLinted) { + LOGGER.info("Start helm lint, strict: {}", isStrictLinted); + LintValidationResult lintValidationResult = runHelmLint( + buildHelmLintCommand(version, chartPath, isStrictLinted)); + LOGGER.info("Helm lint finished"); + return new ValidationResult(templateValidationResult, lintValidationResult, version); + } + + return new ValidationResult(templateValidationResult, version); + } + + private boolean isNotSupportedVersion(String version) { + return !supportedVersionsProvider.getVersions().contains(version); + } + + + private String buildHelmTemplateCommand(String version, String chartPath) { + return "helm-v" + version + " " + TEMPLATE_OPTION + " " + chartPath; + } + + private TemplateValidationResult runHelmTemplate(String helmCommand) + throws BashExecutionException { + + LOGGER.debug("Command executions: {} ", helmCommand); + BashOutput chartTemplateResult = executor.execute(helmCommand); + LOGGER.debug("Status code: " + chartTemplateResult.getExitValue()); + if (chartTemplateResult.getExitValue() != 0) { + List renderingErrors = parseTemplateError(chartTemplateResult.getOutputLines()); + return new TemplateValidationResult(false, renderingErrors); + } + return new TemplateValidationResult(true, Collections.emptyList()); + } + + private String buildHelmLintCommand(String version, String chartPath, boolean isStrictLint) { + String command = "helm-v" + version + " " + LINT_OPTION + " " + chartPath; + if (isStrictLint) { + return command + " --strict"; + } + return command; + } + + private LintValidationResult runHelmLint(String helmCommand) { + BashOutput chartLintResult = executor.execute(helmCommand); + + List lintErrors = parseLintError(chartLintResult.getOutputLines()); + List lintWarnings = parseWarningError(chartLintResult.getOutputLines()); + + boolean isSuccessExitStatus = isSuccessExitStatus(chartLintResult.getExitValue()); + + if (isInvalidWithoutStandardError(isSuccessExitStatus, lintErrors, lintWarnings)) { + return new LintValidationResult(INVALID_RESULT, chartLintResult.getOutputLines(), new ArrayList<>()); + } + + return new LintValidationResult(isSuccessExitStatus, lintErrors, lintWarnings); + } + + private boolean isInvalidWithoutStandardError(boolean isValid, List lintErrors, List lintWarnings) { + return !isValid && lintErrors.isEmpty() && lintWarnings.isEmpty(); + } + + private boolean isSuccessExitStatus(int exitValue) { + return exitValue == 0; + } + + private List parseTemplateError(List outputLines) { + + return outputLines.stream() + .filter(s -> s.startsWith("Error:")) + .collect(Collectors.toList()); + } + + private List parseWarningError(List outputLines) { + return outputLines.stream() + .filter(s -> s.startsWith("[WARNING]")) + .collect(Collectors.toList()); + } + + private List parseLintError(List outputLines) { + return outputLines.stream() + .filter(s -> s.startsWith("[ERROR]") || s.startsWith("Error")) + .filter(this::isNotHelmSummaryMessage) + .collect(Collectors.toList()); + } + + private boolean isNotHelmSummaryMessage(String line) { + Pattern pattern = Pattern.compile(HELM_SUMMARY_MESSAGE_PATTERN); + return !pattern.matcher(line).matches(); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/BashExecutionException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/BashExecutionException.java new file mode 100644 index 0000000..2d70d39 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/BashExecutionException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.exception; + +public class BashExecutionException extends RuntimeException { + + public BashExecutionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/NotSupportedVersionException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/NotSupportedVersionException.java new file mode 100644 index 0000000..753a08d --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/NotSupportedVersionException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.exception; + +public class NotSupportedVersionException extends RuntimeException { + + public NotSupportedVersionException(String version) { + super("Version: " + version + " is not supported"); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/SaveFileException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/SaveFileException.java new file mode 100644 index 0000000..cdb9079 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/exception/SaveFileException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.exception; + +public class SaveFileException extends RuntimeException { + + public SaveFileException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/BashOutput.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/BashOutput.java new file mode 100644 index 0000000..88942e5 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/BashOutput.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.model; + +import java.util.List; + +public class BashOutput { + + private final int exitValue; + + private final List outputLines; + + public BashOutput(int exitValue, List outputLines) { + this.exitValue = exitValue; + this.outputLines = outputLines; + } + + public int getExitValue() { + return exitValue; + } + + public List getOutputLines() { + return outputLines; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/LintValidationResult.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/LintValidationResult.java new file mode 100644 index 0000000..09cbe36 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/LintValidationResult.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.model; + +import java.util.List; + +public class LintValidationResult { + + private final boolean isValid; + + private final List lintErrors; + private final List lintWarnings; + + /** + * Validation result of linting a Helm chart. + * @param isValid flag indicating if chart is valid + * @param lintErrors list of errors occurred during linting + * @param lintWarnings list of warning occurred during linting + */ + public LintValidationResult(boolean isValid, List lintErrors, List lintWarnings) { + this.isValid = isValid; + this.lintErrors = lintErrors; + this.lintWarnings = lintWarnings; + } + + boolean isValid() { + return isValid; + } + + List getLintErrors() { + return lintErrors; + } + + List getLintWarnings() { + return lintWarnings; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/TemplateValidationResult.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/TemplateValidationResult.java new file mode 100644 index 0000000..1ba20f9 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/TemplateValidationResult.java @@ -0,0 +1,48 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.model; + +import java.util.List; + +public class TemplateValidationResult { + + private final boolean isDeployable; + + private final List renderErrors; + + /** + * Validation result of templating a Helm chart. + * @param isDeployable flag indicating if chart can be templated + * @param renderErrors list of errors occurred during templating + */ + public TemplateValidationResult(boolean isDeployable, List renderErrors) { + this.isDeployable = isDeployable; + this.renderErrors = renderErrors; + } + + boolean isDeployable() { + return isDeployable; + } + + List getRenderErrors() { + return renderErrors; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/ValidationResult.java b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/ValidationResult.java new file mode 100644 index 0000000..bb4fccc --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/validation/model/ValidationResult.java @@ -0,0 +1,98 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.validation.model; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class ValidationResult { + + private final Boolean isDeployable; + private final List renderErrors; + private final Boolean isValid; + private final List lintWarning; + private final List lintError; + private final String versionUsed; + + + /** + * ValidationResult constructor when linting is enabled. + * @param templateValidationResult result of helm chart templating + * @param lintValidationResult result of helm chart linting + * @param versionUsed version of helm client used + */ + public ValidationResult( + TemplateValidationResult templateValidationResult, + LintValidationResult lintValidationResult, + String versionUsed) { + this.isDeployable = templateValidationResult.isDeployable(); + this.renderErrors = templateValidationResult.getRenderErrors(); + + this.isValid = lintValidationResult.isValid(); + this.lintWarning = lintValidationResult.getLintWarnings(); + this.lintError = lintValidationResult.getLintErrors(); + this.versionUsed = versionUsed; + } + + /** + * ValidationResult constructor when linting is disabled. + * @param templateValidationResult result of helm chart templating + * @param versionUsed version of helm client used + */ + public ValidationResult( + TemplateValidationResult templateValidationResult, String versionUsed) { + this.isDeployable = templateValidationResult.isDeployable(); + this.renderErrors = templateValidationResult.getRenderErrors(); + + this.isValid = null; + this.lintWarning = null; + this.lintError = null; + this.versionUsed = versionUsed; + } + + public Boolean isDeployable() { + return isDeployable; + } + + public List getRenderErrors() { + return Optional.ofNullable(renderErrors) + .map(Collections::unmodifiableList).orElse(null); + } + + public Boolean isValid() { + return isValid; + } + + public List getLintWarning() { + return Optional.ofNullable(lintWarning) + .map(Collections::unmodifiableList).orElse(null); + } + + public List getLintError() { + return Optional.ofNullable(lintError) + .map(Collections::unmodifiableList).orElse(null); + } + + public String getVersionUsed() { + return versionUsed; + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ApiVersionsReader.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ApiVersionsReader.java new file mode 100644 index 0000000..e5c1a2e --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ApiVersionsReader.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.util.Optional; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; +import org.onap.sdc.helmvalidator.helm.versions.exception.ApiVersionNotFoundException; +import org.onap.sdc.helmvalidator.helm.versions.exception.ReadFileException; +import org.springframework.stereotype.Service; + +@Service +public class ApiVersionsReader { + + private static final int MAIN_CHART_DIR_DEPTH = 2; + private static final String API_VERSION_PREFIX = "apiVersion:"; + private static final Path CHART_FILE_NAME = Path.of("Chart.yaml"); + + String readVersion(String chartPath) { + return tryReadVersionFromChart(chartPath) + .orElseThrow(ApiVersionNotFoundException::new); + } + + private Optional tryReadVersionFromChart(String chartPath) { + try (TarArchiveInputStream tarInput = new TarArchiveInputStream( + new GzipCompressorInputStream(new FileInputStream(chartPath)))) { + return readVersionFromChart(tarInput); + } catch (IOException e) { + throw new ReadFileException("Cannot read tar from path: " + chartPath, e); + } + } + + private Optional readVersionFromChart(TarArchiveInputStream tarInput) throws IOException { + TarArchiveEntry currentEntry; + while ((currentEntry = tarInput.getNextTarEntry()) != null) { + if (isMainChartYaml(currentEntry)) { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(tarInput)); + return bufferedReader.lines() + .filter(chartLine -> chartLine.contains(API_VERSION_PREFIX)) + .map(apiVersionLine -> apiVersionLine.replaceAll(API_VERSION_PREFIX, "")) + .map(String::trim) + .findFirst(); + } + } + return Optional.empty(); + } + + private boolean isMainChartYaml(TarArchiveEntry currentEntry) { + Path entryPath = Path.of(currentEntry.getName()); + return currentEntry.isFile() + && CHART_FILE_NAME.equals(entryPath.getFileName()) + && (entryPath.getNameCount() == MAIN_CHART_DIR_DEPTH); + } + + +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ChartBasedVersionProvider.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ChartBasedVersionProvider.java new file mode 100644 index 0000000..b892a33 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/ChartBasedVersionProvider.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions; + +import org.onap.sdc.helmvalidator.helm.versions.exception.NotSupportedApiVersionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ChartBasedVersionProvider { + + private final SupportedVersionsProvider supportedVersionsProvider; + private final ApiVersionsReader apiVersionsReader; + + @Autowired + public ChartBasedVersionProvider( + SupportedVersionsProvider supportedVersionsProvider, + ApiVersionsReader apiVersionsReader) { + this.supportedVersionsProvider = supportedVersionsProvider; + this.apiVersionsReader = apiVersionsReader; + } + + public String getVersion(String chartPath) { + String apiVersion = apiVersionsReader.readVersion(chartPath); + return mapToChartVersion(apiVersion); + } + + private String mapToChartVersion(String apiVersion) { + switch (apiVersion) { + case "v1": + return supportedVersionsProvider.getLatestVersion("2"); + case "v2": + return supportedVersionsProvider.getLatestVersion("3"); + default: + throw new NotSupportedApiVersionException("Cannot obtain Helm version from API version: " + apiVersion); + } + } + +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SupportedVersionsProvider.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SupportedVersionsProvider.java new file mode 100644 index 0000000..ff1cdde --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SupportedVersionsProvider.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions; + +import java.util.Comparator; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.onap.sdc.helmvalidator.helm.validation.exception.NotSupportedVersionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SupportedVersionsProvider { + + private final SystemEnvVersionsReader versionsReader; + + @Autowired + public SupportedVersionsProvider(SystemEnvVersionsReader versionsReader) { + this.versionsReader = versionsReader; + } + + /** + * Retrieves list of available Helm client versions. + * + * @return list of available Helm client versions + */ + public List getVersions() { + return versionsReader.readVersions().stream() + .filter(Predicate.not(String::isBlank)) + .sorted(Comparator.reverseOrder()) + .collect(Collectors.toList()); + } + + /** + * Retrieves latest available Helm client with given major version. + * + * @param helmMajorVersion major version of Helm client + * @return latest available Helm client with given major version + */ + public String getLatestVersion(String helmMajorVersion) { + return getVersions().stream() + .filter(supportedVersion -> supportedVersion.startsWith(helmMajorVersion + ".")) + .findFirst() + .orElseThrow(() -> new NotSupportedVersionException(helmMajorVersion)); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SystemEnvVersionsReader.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SystemEnvVersionsReader.java new file mode 100644 index 0000000..8cccd2b --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/SystemEnvVersionsReader.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; + +@Service +public class SystemEnvVersionsReader { + + private static final String HELM_SUPPORTED_VERSIONS = "HELM_SUPPORTED_VERSIONS"; + private static final String DELIMITER = ","; + + List readVersions() { + return Arrays.stream(getSupportedVersionsFromEnv() + .split(DELIMITER)) + .filter(Predicate.not(String::isBlank)) + .collect(Collectors.toList()); + } + + String getSupportedVersionsFromEnv() { + return Optional.ofNullable(System.getenv(HELM_SUPPORTED_VERSIONS)) + .orElse(""); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ApiVersionNotFoundException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ApiVersionNotFoundException.java new file mode 100644 index 0000000..fadcc2a --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ApiVersionNotFoundException.java @@ -0,0 +1,29 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions.exception; + +public class ApiVersionNotFoundException extends RuntimeException { + + public ApiVersionNotFoundException() { + super("Cannot find apiVersion value in a main chart"); + } + +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/NotSupportedApiVersionException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/NotSupportedApiVersionException.java new file mode 100644 index 0000000..368f9f1 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/NotSupportedApiVersionException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions.exception; + +public class NotSupportedApiVersionException extends RuntimeException { + + public NotSupportedApiVersionException(String message) { + super(message); + } +} diff --git a/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ReadFileException.java b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ReadFileException.java new file mode 100644 index 0000000..a6a1ec4 --- /dev/null +++ b/src/main/java/org/onap/sdc/helmvalidator/helm/versions/exception/ReadFileException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * SDC-HELM-VALIDATOR + * ================================================================================ + * Copyright (C) 2021 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.helmvalidator.helm.versions.exception; + +public class ReadFileException extends RuntimeException { + + public ReadFileException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..3fef31f --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,4 @@ +logging.level.web="ERROR" +spring.mvc.log-request-details=false +app.config.charts-base-path=/charts +spring.jackson.default-property-inclusion=NON_NULL -- cgit 1.2.3-korg