2 * ========================LICENSE_START=================================
3 * Copyright (C) 2021-2022 Nordix Foundation. All rights reserved.
4 * ======================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ========================LICENSE_END===================================
19 package org.onap.policy.clamp.controlloop.participant.kubernetes.controller;
21 import io.swagger.annotations.Api;
22 import io.swagger.annotations.ApiOperation;
23 import io.swagger.annotations.ApiResponse;
24 import io.swagger.annotations.ApiResponses;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException;
28 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo;
29 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList;
30 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository;
31 import org.onap.policy.clamp.controlloop.participant.kubernetes.models.InstallationInfo;
32 import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService;
33 import org.onap.policy.common.utils.coder.CoderException;
34 import org.onap.policy.common.utils.coder.StandardCoder;
35 import org.springframework.beans.factory.annotation.Autowired;
36 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
37 import org.springframework.http.HttpStatus;
38 import org.springframework.http.MediaType;
39 import org.springframework.http.ResponseEntity;
40 import org.springframework.web.bind.annotation.DeleteMapping;
41 import org.springframework.web.bind.annotation.GetMapping;
42 import org.springframework.web.bind.annotation.PathVariable;
43 import org.springframework.web.bind.annotation.PostMapping;
44 import org.springframework.web.bind.annotation.RequestBody;
45 import org.springframework.web.bind.annotation.RequestMapping;
46 import org.springframework.web.bind.annotation.RequestParam;
47 import org.springframework.web.bind.annotation.RequestPart;
48 import org.springframework.web.bind.annotation.RestController;
49 import org.springframework.web.multipart.MultipartFile;
51 @RestController("chartController")
52 @ConditionalOnExpression("${chart.api.enabled:false}")
53 @RequestMapping("helm")
54 @Api(tags = {"k8s-participant"})
55 public class ChartController {
58 private ChartService chartService;
60 private static final StandardCoder CODER = new StandardCoder();
63 * REST endpoint to get all the charts.
65 * @return List of charts installed
67 @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE)
68 @ApiOperation(value = "Return all Charts")
69 @ApiResponses(value = {@ApiResponse(code = 200, message = "chart List")})
70 public ResponseEntity<ChartList> getAllCharts() {
71 return new ResponseEntity<>(ChartList.builder().charts(new ArrayList<>(chartService.getAllCharts())).build(),
76 * REST endpoint to install a helm chart.
78 * @param info Info of the chart to be installed
79 * @return Status of the install operation
80 * @throws ServiceException in case of error
81 * @throws IOException in case of IO error
83 @PostMapping(path = "/install", consumes = MediaType.APPLICATION_JSON_VALUE,
84 produces = MediaType.APPLICATION_JSON_VALUE)
85 @ApiOperation(value = "Install the chart")
86 @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Installed")})
87 public ResponseEntity<Object> installChart(@RequestBody InstallationInfo info)
88 throws ServiceException, IOException {
89 ChartInfo chart = chartService.getChart(info.getName(), info.getVersion());
91 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
94 chartService.installChart(chart);
95 return new ResponseEntity<>(HttpStatus.CREATED);
99 * REST endpoint to uninstall a specific chart.
101 * @param name name of the chart
102 * @param version version of the chart
103 * @return Status of operation
104 * @throws ServiceException in case of error.
106 @DeleteMapping(path = "/uninstall/{name}/{version}", produces = MediaType.APPLICATION_JSON_VALUE)
107 @ApiOperation(value = "Uninstall the Chart")
108 @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Uninstalled")})
109 public ResponseEntity<Object> uninstallChart(@PathVariable("name") String name,
110 @PathVariable("version") String version) throws ServiceException {
111 ChartInfo chart = chartService.getChart(name, version);
113 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
116 chartService.uninstallChart(chart);
117 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
121 * REST endpoint to onboard a chart.
123 * @param chartFile Multipart file for the helm chart
124 * @param infoJson AppInfo of the chart
125 * @param overrideFile the file for overriding the chart
126 * @return Status of onboard operation
127 * @throws ServiceException in case of error
128 * @throws IOException in case of IO error
130 @PostMapping(path = "/onboard/chart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
131 produces = MediaType.APPLICATION_JSON_VALUE)
132 @ApiOperation(value = "Onboard the Chart")
133 @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")})
134 public ResponseEntity<String> onboardChart(@RequestPart("chart") MultipartFile chartFile,
135 @RequestParam(name = "values", required = false) MultipartFile overrideFile,
136 @RequestParam("info") String infoJson) throws ServiceException, IOException {
140 info = CODER.decode(infoJson, ChartInfo.class);
141 } catch (CoderException e) {
142 throw new ServiceException("Error parsing the chart information", e);
145 chartService.saveChart(info, chartFile, overrideFile);
146 return new ResponseEntity<>(HttpStatus.OK);
150 * REST endpoint to delete a specific helm chart.
152 * @param name name of the chart
153 * @param version version of the chart
154 * @return Status of operation
156 @DeleteMapping(path = "/chart/{name}/{version}")
157 @ApiOperation(value = "Delete the chart")
158 @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")})
159 public ResponseEntity<Object> deleteChart(@PathVariable("name") String name,
160 @PathVariable("version") String version) {
162 ChartInfo chart = chartService.getChart(name, version);
164 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
167 chartService.deleteChart(chart);
168 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
172 * REST endpoint to configure a helm Repository.
174 * @param repo Helm repository to be configured
175 * @return Status of the operation
176 * @throws ServiceException in case of error
177 * @throws IOException in case of IO error
179 @PostMapping(path = "/repo", consumes = MediaType.APPLICATION_JSON_VALUE,
180 produces = MediaType.APPLICATION_JSON_VALUE)
181 @ApiOperation(value = "Configure helm repository")
182 @ApiResponses(value = {@ApiResponse(code = 201, message = "Repository added")})
183 public ResponseEntity<Object> configureRepo(@RequestBody String repo)
184 throws ServiceException, IOException {
185 HelmRepository repository;
187 repository = CODER.decode(repo, HelmRepository.class);
188 } catch (CoderException e) {
189 throw new ServiceException("Error parsing the repository information", e);
191 chartService.configureRepository(repository);
193 return new ResponseEntity<>(HttpStatus.CREATED);