aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java45
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java32
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java4
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java90
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java2
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java39
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java23
-rw-r--r--participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml6
8 files changed, 204 insertions, 37 deletions
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java
new file mode 100644
index 000000000..09a497705
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 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.policy.clamp.controlloop.participant.kubernetes.configurations;
+
+import org.onap.policy.clamp.controlloop.participant.kubernetes.controller.ChartController;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+@Configuration
+public class SpringFoxConfig {
+
+ /**
+ * Docket Spring Fox Config.
+ *
+ * @return Docket
+ */
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2).select()
+ .apis(RequestHandlerSelectors.basePackage(ChartController.class.getPackageName()))
+ .paths(PathSelectors.any()).build();
+ }
+}
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java
index 23605e641..d041300a8 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList;
+import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository;
import org.onap.policy.clamp.controlloop.participant.kubernetes.models.InstallationInfo;
import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService;
import org.onap.policy.common.utils.coder.CoderException;
@@ -48,7 +49,7 @@ import org.springframework.web.multipart.MultipartFile;
@RestController("chartController")
@RequestMapping("helm")
-@Api(tags = {"chart"})
+@Api(tags = {"k8s-participant"})
public class ChartController {
@Autowired
@@ -124,7 +125,7 @@ public class ChartController {
* @throws ServiceException in case of error
* @throws IOException in case of IO error
*/
- @PostMapping(path = "/charts", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
+ @PostMapping(path = "/onboard/chart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "Onboard the Chart")
@ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")})
@@ -150,7 +151,7 @@ public class ChartController {
* @param version version of the chart
* @return Status of operation
*/
- @DeleteMapping(path = "/charts/{name}/{version}")
+ @DeleteMapping(path = "/chart/{name}/{version}")
@ApiOperation(value = "Delete the chart")
@ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")})
public ResponseEntity<Object> deleteChart(@PathVariable("name") String name,
@@ -164,4 +165,29 @@ public class ChartController {
chartService.deleteChart(chart);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
+
+ /**
+ * REST endpoint to configure a helm Repository.
+ *
+ * @param repo Helm repository to be configured
+ * @return Status of the operation
+ * @throws ServiceException in case of error
+ * @throws IOException in case of IO error
+ */
+ @PostMapping(path = "/repo", consumes = MediaType.APPLICATION_JSON_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE)
+ @ApiOperation(value = "Configure helm repository")
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Repository added")})
+ public ResponseEntity<Object> configureRepo(@RequestBody String repo)
+ throws ServiceException, IOException {
+ HelmRepository repository;
+ try {
+ repository = CODER.decode(repo, HelmRepository.class);
+ } catch (CoderException e) {
+ throw new ServiceException("Error parsing the repository information", e);
+ }
+ chartService.configureRepository(repository);
+
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ }
}
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java
index 3f59c0822..8aa74f30f 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java
@@ -134,10 +134,6 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
LOGGER.info("Installation request received for the Helm Chart {} ", chartData);
try {
var chartInfo = CODER.convert(chartData, ChartInfo.class);
- var repositoryValue = chartData.get("repository");
- if (repositoryValue != null) {
- chartInfo.setRepository(repositoryValue.toString());
- }
chartService.installChart(chartInfo);
chartMap.put(element.getId(), chartInfo);
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java
index 6a1b98654..7954dbbb9 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java
@@ -20,10 +20,8 @@
package org.onap.policy.clamp.controlloop.participant.kubernetes.helm;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -32,6 +30,7 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo;
+import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository;
import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,20 +55,35 @@ public class HelmClient {
* @throws ServiceException incase of error
*/
public void installChart(ChartInfo chart) throws ServiceException {
- var processBuilder = prepareCreateNamespaceCommand(chart.getNamespace());
- try {
+ if (! checkNamespaceExists(chart.getNamespace())) {
+ var processBuilder = prepareCreateNamespaceCommand(chart.getNamespace());
executeCommand(processBuilder);
- } catch (ServiceException e) {
- logger.warn("Namespace not created", e);
}
- processBuilder = prepareInstallCommand(chart);
+ var processBuilder = prepareInstallCommand(chart);
logger.info("Installing helm chart {} from the repository {} ", chart.getChartId().getName(),
- chart.getRepository());
+ chart.getRepository().getRepoName());
executeCommand(processBuilder);
logger.info("Chart {} installed successfully", chart.getChartId().getName());
}
/**
+ * Add repository if doesn't exist.
+ * @param repo HelmRepository
+ * @throws ServiceException incase of error
+ */
+ public void addRepository(HelmRepository repo) throws ServiceException {
+ String output = executeCommand(prepareVerifyRepoCommand(repo));
+ if (output.isEmpty()) {
+ logger.info("Adding repository to helm client");
+ executeCommand(prepareRepoAddCommand(repo));
+ logger.debug("Added repository {} to the helm client", repo.getRepoName());
+ } else {
+ logger.info("Repository already exists");
+ }
+ }
+
+
+ /**
* Finds helm chart repository for the chart.
*
* @param chart ChartInfo.
@@ -81,6 +95,7 @@ public class HelmClient {
updateHelmRepo();
String repository = verifyConfiguredRepo(chart);
if (repository != null) {
+ logger.info("Helm chart located in the repository {} ", repository);
return repository;
}
var localHelmChartDir = chartStore.getAppPath(chart.getChartId()).toString();
@@ -88,7 +103,6 @@ public class HelmClient {
if (verifyLocalHelmRepo(new File(localHelmChartDir + "/" + chart.getChartId().getName()))) {
repository = localHelmChartDir;
}
-
return repository;
}
@@ -104,18 +118,7 @@ public class HelmClient {
String repository = null;
var builder = helmRepoVerifyCommand(chart.getChartId().getName());
String output = executeCommand(builder);
- try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output,
- StandardCharsets.UTF_8)))) {
- String line = reader.readLine();
- while (line != null) {
- if (line.contains(chart.getChartId().getName())) {
- repository = line.split("/")[0];
- logger.info("Helm chart located in the repository {} ", repository);
- return repository;
- }
- line = reader.readLine();
- }
- }
+ repository = verifyOutput(output, chart.getChartId().getName());
return repository;
}
@@ -164,17 +167,56 @@ public class HelmClient {
}
}
+ private boolean checkNamespaceExists(String namespace) throws ServiceException {
+ logger.info("Check if namespace {} exists on the cluster", namespace);
+ String output = executeCommand(prepareVerifyNamespaceCommand(namespace));
+ return !output.isEmpty();
+ }
+
+ private String verifyOutput(String output, String value) {
+ for (var line: output.split("\\R")) {
+ if (line.contains(value)) {
+ return line.split("/")[0];
+ }
+ }
+ return null;
+ }
+
+ private ProcessBuilder prepareRepoAddCommand(HelmRepository repo) {
+ // @formatter:off
+ List<String> helmArguments = new ArrayList<>(
+ List.of(
+ "helm",
+ "repo",
+ "add", repo.getRepoName(), repo.getProtocol() + "://" + repo.getAddress() + ":" + repo.getPort()
+ ));
+ if (repo.getUserName() != null && repo.getPassword() != null) {
+ helmArguments.addAll(List.of("--username", repo.getUserName(), "--password", repo.getPassword()));
+ }
+ return new ProcessBuilder().command(helmArguments);
+ }
+
+ private ProcessBuilder prepareVerifyRepoCommand(HelmRepository repo) {
+ List<String> helmArguments = List.of("sh", "-c", "helm repo ls | grep " + repo.getRepoName());
+ return new ProcessBuilder().command(helmArguments);
+ }
+
+ private ProcessBuilder prepareVerifyNamespaceCommand(String namespace) {
+ List<String> helmArguments = List.of("sh", "-c", "kubectl get ns | grep " + namespace);
+ return new ProcessBuilder().command(helmArguments);
+ }
+
private ProcessBuilder prepareInstallCommand(ChartInfo chart) {
// @formatter:off
List<String> helmArguments = new ArrayList<>(
List.of(
"helm",
- "install", chart.getReleaseName(), chart.getRepository() + "/" + chart.getChartId().getName(),
+ "install", chart.getReleaseName(), chart.getRepository().getRepoName() + "/"
+ + chart.getChartId().getName(),
"--version", chart.getChartId().getVersion(),
"--namespace", chart.getNamespace()
- )
- );
+ ));
// @formatter:on
// Verify if values.yaml/override parameters available for the chart
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java
index b53f2075a..5cbc203ec 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java
@@ -37,7 +37,7 @@ public class ChartInfo {
@NonNull
private String namespace;
- private String repository;
+ private HelmRepository repository;
private Map<String, String> overrideParams;
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java
new file mode 100644
index 000000000..a495c7b5c
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java
@@ -0,0 +1,39 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.policy.clamp.controlloop.participant.kubernetes.models;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class HelmRepository {
+
+ private String repoName;
+
+ private String protocol;
+
+ private String address;
+
+ private String port;
+
+ private String userName;
+
+ private String password;
+}
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java
index a1522188d..770bbb291 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java
@@ -24,6 +24,7 @@ import java.util.Collection;
import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.HelmClient;
import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo;
+import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -88,18 +89,34 @@ public class ChartService {
*/
public void installChart(ChartInfo chart) throws ServiceException, IOException {
if (chart.getRepository() == null) {
- String repository = findChartRepo(chart);
- if (repository == null) {
+ String repoName = findChartRepo(chart);
+ if (repoName == null) {
logger.error("Chart repository could not be found. Skipping chart Installation "
+ "for the chart {} ", chart.getChartId().getName());
return;
} else {
- chart.setRepository(repository);
+ HelmRepository repo = HelmRepository.builder().repoName(repoName).build();
+ chart.setRepository(repo);
}
+ } else {
+ // Add remote repository if passed via TOSCA
+ configureRepository(chart.getRepository());
}
helmClient.installChart(chart);
}
+
+ /**
+ * Configure remote repository.
+ * @param repo HelmRepository
+ * @throws ServiceException incase of error
+ */
+ public void configureRepository(HelmRepository repo) throws ServiceException {
+ if (repo.getAddress() != null && repo.getPort() != null) {
+ helmClient.addRepository(repo);
+ }
+ }
+
/**
* Finds helm chart repository for a given chart.
* @param chart chartInfo.
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml
index a27c33d44..713b072a2 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml
@@ -13,8 +13,8 @@ participant:
reportingTimeIntervalMs: 120000
description: Participant Description
participantId:
- name: K8sParticipant0
- version: 1.0.0
+ name: org.onap.k8s.controlloop.K8SControlLoopParticipant
+ version: 2.3.4
participantType:
name: org.onap.k8s.controlloop.K8SControlLoopParticipant
version: 2.3.4
@@ -42,6 +42,8 @@ server:
# Configuration of the HTTP/REST server. The parameters are defined and handled by the springboot framework.
# See springboot documentation.
port: 8083
+ servlet:
+ context-path: /onap/k8sparticipant
logging:
# Configuration of logging