Helm charts values customization using files
Issue-ID: SO-4030
Signed-off-by: nadeeshani.jayathilake <nadeeshani.jayathilake@est.tech>
Change-Id: I1fea315e3f39179161a32762ca53763088426520
diff --git a/readme.md b/readme.md
index 93a5fce..65af3d9 100644
--- a/readme.md
+++ b/readme.md
@@ -15,3 +15,13 @@
Subscribe and post messages with SO tag in onap-discuss group at https://lists.onap.org/g/onap-discuss
+# Project Structure
+
+SO-CNFM is composed of a main pom.xml which is structured to build packages (docker image preparation file) and so-cnfm-lcm modules.
+Also, so-cnfm-lcm is structured to build all submodules and there is individual pom.xml for each submodule.
+so-cnfm-lcm is composed of
+ so-cnfm-lcm-api – generates the POJOs for REST APIs.
+ so-cnfm-lcm-application – creates Spring Boot application jar file.
+ so-cnfm-lcm-bpmn-flows - Camunda BPM engine code flow for step-by-step order flow execution.
+ so-cnfm-lcm-database-service – mariadb for storing metadata.
+ so-cnfm-lcm-service – contains the REST APIs.
diff --git a/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/helm/HelmClientImpl.java b/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/helm/HelmClientImpl.java
index 7eaf4af..7fa59d5 100644
--- a/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/helm/HelmClientImpl.java
+++ b/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/helm/HelmClientImpl.java
@@ -27,7 +27,10 @@
import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_REPLICA_SET;
import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_SERVICE;
import static org.onap.so.cnfm.lcm.bpmn.flows.Constants.KIND_STATEFUL_SET;
+import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -35,8 +38,10 @@
import java.util.Set;
import org.jvnet.jaxb2_commons.lang.StringUtils;
import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.HelmClientExecuteException;
+import org.onap.so.cnfm.lcm.bpmn.flows.service.PropertiesToYamlConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@@ -44,6 +49,12 @@
private static final String KIND_KEY = "kind: ";
private static final String ANY_UNICODE_NEWLINE = "\\R";
private static final Logger logger = LoggerFactory.getLogger(HelmClientImpl.class);
+ private final PropertiesToYamlConverter propertiesToYamlConverter;
+
+ @Autowired
+ public HelmClientImpl(final PropertiesToYamlConverter propertiesToYamlConverter) {
+ this.propertiesToYamlConverter = propertiesToYamlConverter;
+ }
private static final Set<String> SUPPORTED_KINDS = Set.of(KIND_JOB, KIND_POD, KIND_SERVICE, KIND_DEPLOYMENT,
KIND_REPLICA_SET, KIND_DAEMON_SET, KIND_STATEFUL_SET);
@@ -156,17 +167,27 @@
private ProcessBuilder prepareInstallCommand(final String releaseName, final Path kubeconfig, final Path helmChart,
final Map<String, String> lifeCycleParams) {
- final List<String> helmArguments = new ArrayList<String>(List.of("helm", "install", releaseName, "-n",
+ final List<String> commands = new ArrayList<String>(List.of("helm", "install", releaseName, "-n",
"default", helmChart.toString(), "--kubeconfig", kubeconfig.toString()));
if (lifeCycleParams != null && !lifeCycleParams.isEmpty()) {
- for (final Map.Entry<String, String> param : lifeCycleParams.entrySet()) {
- helmArguments
- .addAll(List.of("--set", param.getKey().concat("=").concat(String.valueOf(param.getValue()))));
- }
+ final String fileName = helmChart.getParent().resolve("values.yaml").toString();
+ createYamlFile(fileName, lifeCycleParams);
+ commands.add("-f ".concat(fileName));
}
+ final List<String> helmArguments = List.of("sh", "-c", toString(commands));
return new ProcessBuilder().command(helmArguments);
+ }
+ private void createYamlFile(final String fileName, final Map<String, String> lifeCycleParams){
+ logger.debug("Will create the runtime values.yaml file.");
+ String yamlContent = propertiesToYamlConverter.getValuesYamlFileContent(lifeCycleParams);
+ try {
+ Files.write(Paths.get(fileName), yamlContent.getBytes());
+ } catch (IOException e) {
+ logger.error("Failed to create the run time life cycle yaml file: {} " + e.getMessage());
+ throw new HelmClientExecuteException("Failed to create the run time life cycle yaml file: {} " + e.getMessage());
+ }
}
private ProcessBuilder prepareUnInstallCommand(final String releaseName, final Path kubeConfig) {
diff --git a/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/PropertiesToYamlConverter.java b/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/PropertiesToYamlConverter.java
new file mode 100644
index 0000000..07e16c2
--- /dev/null
+++ b/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/PropertiesToYamlConverter.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.bpmn.flows.service;
+import java.util.Map;
+import java.util.TreeMap;
+import org.springframework.stereotype.Service;
+import org.yaml.snakeyaml.Yaml;
+/**
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+
+@Service
+public class PropertiesToYamlConverter {
+ public String getValuesYamlFileContent(final Map<String, String> lifeCycleParams) {
+ final Map<String, Object> root = new TreeMap<>();
+ lifeCycleParams.entrySet().stream().forEach(entry -> processProperty(root, entry.getKey(), entry.getValue()));
+ final Yaml yaml = new Yaml();
+ return yaml.dumpAsMap(root);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void processProperty(final Map<String, Object> root, final String key, final String value) {
+ Map<String, Object> local = root;
+ final String[] keys = key.split("\\.");
+ final int lastIndex = keys.length - 1;
+ for (int index = 0; index < lastIndex; index++) {
+ final String currentKey = keys[index];
+ if (!local.containsKey(currentKey)) {
+ final Map<String, Object> subMap = new TreeMap<>();
+ local.put(currentKey, subMap);
+ local = subMap;
+ continue;
+ } else {
+ local = (Map<String, Object>) local.get(currentKey);
+ }
+ }
+ local.put(keys[lastIndex], value);
+ }
+}