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.acm.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.lang.invoke.MethodHandles;
27 import java.util.ArrayList;
28 import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
29 import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
30 import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList;
31 import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository;
32 import org.onap.policy.clamp.acm.participant.kubernetes.models.InstallationInfo;
33 import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService;
34 import org.onap.policy.common.utils.coder.CoderException;
35 import org.onap.policy.common.utils.coder.StandardCoder;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.springframework.beans.factory.annotation.Autowired;
39 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
40 import org.springframework.http.HttpStatus;
41 import org.springframework.http.MediaType;
42 import org.springframework.http.ResponseEntity;
43 import org.springframework.web.bind.annotation.DeleteMapping;
44 import org.springframework.web.bind.annotation.GetMapping;
45 import org.springframework.web.bind.annotation.PathVariable;
46 import org.springframework.web.bind.annotation.PostMapping;
47 import org.springframework.web.bind.annotation.RequestBody;
48 import org.springframework.web.bind.annotation.RequestMapping;
49 import org.springframework.web.bind.annotation.RequestParam;
50 import org.springframework.web.bind.annotation.RequestPart;
51 import org.springframework.web.bind.annotation.RestController;
52 import org.springframework.web.multipart.MultipartFile;
54 @RestController("chartController")
55 @ConditionalOnExpression("${chart.api.enabled:false}")
56 @RequestMapping("helm")
57 @Api(tags = {"k8s-participant"})
58 public class ChartController {
59 private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
62 private ChartService chartService;
64 private static final StandardCoder CODER = new StandardCoder();
67 * REST endpoint to get all the charts.
69 * @return List of charts installed
71 @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE)
72 @ApiOperation(value = "Return all Charts")
73 @ApiResponses(value = {@ApiResponse(code = 200, message = "chart List")})
74 public ResponseEntity<ChartList> getAllCharts() {
75 return new ResponseEntity<>(ChartList.builder().charts(new ArrayList<>(chartService.getAllCharts())).build(),
80 * REST endpoint to install a helm chart.
82 * @param info Info of the chart to be installed
83 * @return Status of the install operation
84 * @throws ServiceException in case of error
85 * @throws IOException in case of IO error
87 @PostMapping(path = "/install", consumes = MediaType.APPLICATION_JSON_VALUE,
88 produces = MediaType.APPLICATION_JSON_VALUE)
89 @ApiOperation(value = "Install the chart")
90 @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Installed")})
91 public ResponseEntity<Object> installChart(@RequestBody InstallationInfo info)
92 throws ServiceException, IOException {
93 ChartInfo chart = chartService.getChart(info.getName(), info.getVersion());
95 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
98 chartService.installChart(chart);
99 return new ResponseEntity<>(HttpStatus.CREATED);
103 * REST endpoint to uninstall a specific chart.
105 * @param name name of the chart
106 * @param version version of the chart
107 * @return Status of operation
108 * @throws ServiceException in case of error.
110 @DeleteMapping(path = "/uninstall/{name}/{version}", produces = MediaType.APPLICATION_JSON_VALUE)
111 @ApiOperation(value = "Uninstall the Chart")
112 @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Uninstalled")})
113 public ResponseEntity<Object> uninstallChart(@PathVariable("name") String name,
114 @PathVariable("version") String version) throws ServiceException {
115 ChartInfo chart = chartService.getChart(name, version);
117 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
120 chartService.uninstallChart(chart);
121 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
125 * REST endpoint to onboard a chart.
127 * @param chartFile Multipart file for the helm chart
128 * @param infoJson AppInfo of the chart
129 * @param overrideFile the file for overriding the chart
130 * @return Status of onboard operation
131 * @throws ServiceException in case of error
132 * @throws IOException in case of IO error
134 @PostMapping(path = "/onboard/chart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
135 produces = MediaType.APPLICATION_JSON_VALUE)
136 @ApiOperation(value = "Onboard the Chart")
137 @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")})
138 public ResponseEntity<String> onboardChart(@RequestPart("chart") MultipartFile chartFile,
139 @RequestParam(name = "values", required = false) MultipartFile overrideFile,
140 @RequestParam("info") String infoJson) throws ServiceException, IOException {
144 info = CODER.decode(infoJson, ChartInfo.class);
145 } catch (CoderException e) {
146 throw new ServiceException("Error parsing the chart information", e);
149 chartService.saveChart(info, chartFile, overrideFile);
150 return new ResponseEntity<>(HttpStatus.OK);
154 * REST endpoint to delete a specific helm chart.
156 * @param name name of the chart
157 * @param version version of the chart
158 * @return Status of operation
160 @DeleteMapping(path = "/chart/{name}/{version}")
161 @ApiOperation(value = "Delete the chart")
162 @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")})
163 public ResponseEntity<Object> deleteChart(@PathVariable("name") String name,
164 @PathVariable("version") String version) {
166 ChartInfo chart = chartService.getChart(name, version);
168 return new ResponseEntity<>(HttpStatus.NOT_FOUND);
171 chartService.deleteChart(chart);
172 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
176 * REST endpoint to configure a helm Repository.
178 * @param repo Helm repository to be configured
179 * @return Status of the operation
180 * @throws ServiceException in case of error
181 * @throws IOException in case of IO error
183 @PostMapping(path = "/repo", consumes = MediaType.APPLICATION_JSON_VALUE,
184 produces = MediaType.APPLICATION_JSON_VALUE)
185 @ApiOperation(value = "Configure helm repository")
186 @ApiResponses(value = {@ApiResponse(code = 201, message = "Repository added"),
187 @ApiResponse(code = 409, message = "Repository already Exist")})
188 public ResponseEntity<Object> configureRepo(@RequestBody String repo)
189 throws ServiceException, IOException {
190 HelmRepository repository;
192 repository = CODER.decode(repo, HelmRepository.class);
193 } catch (CoderException e) {
194 logger.warn("Error parsing the repository information:", e);
195 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
196 .body("Error parsing the repository information");
198 if (chartService.configureRepository(repository)) {
199 return new ResponseEntity<>(HttpStatus.CREATED);
201 return new ResponseEntity<>(HttpStatus.CONFLICT);