Skip to content

Commit a2a491e

Browse files
authored
fix: deployment template (devtron-labs#1603)
* User Authorisation to save Template * User Authorisation to save Template * Updating as per PR comments * delete folder for validation error * refactoring code
1 parent cc5bd1d commit a2a491e

3 files changed

Lines changed: 113 additions & 27 deletions

File tree

api/deployment/DeploymentConfigRestHandler.go

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package deployment
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"github.com/devtron-labs/devtron/api/restHandler/common"
67
chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
@@ -14,11 +15,14 @@ import (
1415
"io/ioutil"
1516
"net/http"
1617
"os"
18+
"path/filepath"
19+
"strings"
1720
"time"
1821
)
1922

2023
type DeploymentConfigRestHandler interface {
2124
CreateChartFromFile(w http.ResponseWriter, r *http.Request)
25+
SaveChart(w http.ResponseWriter, r *http.Request)
2226
}
2327

2428
type DeploymentConfigRestHandlerImpl struct {
@@ -31,6 +35,13 @@ type DeploymentConfigRestHandlerImpl struct {
3135
chartRefRepository chartRepoRepository.ChartRefRepository
3236
}
3337

38+
type DeploymentChartInfo struct {
39+
ChartName string `json:"chartName"`
40+
Description string `json:"description"`
41+
FileId string `json:"fileId"`
42+
Action string `json:"action"`
43+
}
44+
3445
func NewDeploymentConfigRestHandlerImpl(Logger *zap.SugaredLogger, userAuthService user.UserService, enforcer casbin.Enforcer, validator *validator.Validate,
3546
refChartDir pipeline.RefChartDir, chartService pipeline.ChartService, chartRefRepository chartRepoRepository.ChartRefRepository) *DeploymentConfigRestHandlerImpl {
3647
return &DeploymentConfigRestHandlerImpl{
@@ -86,14 +97,13 @@ func (handler *DeploymentConfigRestHandlerImpl) CreateChartFromFile(w http.Respo
8697

8798
chartInfo, err := handler.chartService.ExtractChartIfMissing(fileBytes, string(handler.refChartDir), "")
8899

89-
if chartInfo.TemporaryFolder != "" {
90-
err1 := os.RemoveAll(chartInfo.TemporaryFolder)
91-
if err1 != nil {
92-
handler.Logger.Errorw("error in deleting temp dir ", "err", err)
93-
}
94-
}
95-
96100
if err != nil {
101+
if chartInfo.TemporaryFolder != "" {
102+
err1 := os.RemoveAll(chartInfo.TemporaryFolder)
103+
if err1 != nil {
104+
handler.Logger.Errorw("error in deleting temp dir ", "err", err1)
105+
}
106+
}
97107
common.WriteJsonResp(w, fmt.Errorf(err.Error()), nil, http.StatusBadRequest)
98108
return
99109
}
@@ -113,12 +123,78 @@ func (handler *DeploymentConfigRestHandlerImpl) CreateChartFromFile(w http.Respo
113123
},
114124
}
115125

116-
err = handler.chartRefRepository.Save(chartRefs)
126+
chartsJson, _ := json.Marshal(chartRefs)
127+
err = ioutil.WriteFile(filepath.Join(chartInfo.TemporaryFolder, "output.json"), chartsJson, 0644)
128+
if err != nil {
129+
common.WriteJsonResp(w, fmt.Errorf(err.Error()), nil, http.StatusInternalServerError)
130+
return
131+
}
132+
133+
pathList := strings.Split(chartInfo.TemporaryFolder, "/")
134+
chartData := &DeploymentChartInfo{
135+
ChartName: chartInfo.ChartName,
136+
Description: chartInfo.Description,
137+
FileId: pathList[len(pathList)-1],
138+
}
139+
140+
common.WriteJsonResp(w, err, chartData, http.StatusOK)
141+
return
142+
}
143+
144+
func (handler *DeploymentConfigRestHandlerImpl) SaveChart(w http.ResponseWriter, r *http.Request) {
145+
decoder := json.NewDecoder(r.Body)
146+
userId, err := handler.userAuthService.GetLoggedInUser(r)
147+
if userId == 0 || err != nil {
148+
common.WriteJsonResp(w, err, nil, http.StatusUnauthorized)
149+
return
150+
}
151+
152+
token := r.Header.Get("token")
153+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
154+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
155+
return
156+
}
157+
158+
var request DeploymentChartInfo
159+
err = decoder.Decode(&request)
117160
if err != nil {
118-
handler.Logger.Errorw("error in saving ConfigMap, CallbackConfigMap", "err", err)
119-
common.WriteJsonResp(w, err, "Chart couldn't be saved", http.StatusInternalServerError)
161+
handler.Logger.Errorw("decode err", "err", err)
162+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
120163
return
121164
}
122-
common.WriteJsonResp(w, err, "Chart Saved Successfully", http.StatusOK)
165+
166+
location := filepath.Join(string(handler.refChartDir), request.FileId)
167+
if request.Action == "Save" {
168+
file, err := ioutil.ReadFile(filepath.Join(location, "output.json"))
169+
if err != nil {
170+
handler.Logger.Errorw("Error reading output.json", "err", err)
171+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
172+
return
173+
}
174+
chartRefs := &chartRepoRepository.ChartRef{}
175+
err = json.Unmarshal(file, &chartRefs)
176+
if err != nil {
177+
handler.Logger.Errorw("unmarshall err", "err", err)
178+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
179+
return
180+
}
181+
182+
err = handler.chartRefRepository.Save(chartRefs)
183+
if err != nil {
184+
handler.Logger.Errorw("error in saving Chart", "err", err)
185+
common.WriteJsonResp(w, err, "Chart couldn't be saved", http.StatusInternalServerError)
186+
return
187+
}
188+
}
189+
190+
if location != "" {
191+
err = os.RemoveAll(location)
192+
if err != nil {
193+
handler.Logger.Errorw("error in deleting temp dir ", "err", err)
194+
}
195+
}
196+
197+
common.WriteJsonResp(w, err, "Processed successfully", http.StatusOK)
123198
return
199+
124200
}

api/deployment/DeploymentConfigRouter.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ func NewDeploymentRouterImpl(deploymentRestHandler DeploymentConfigRestHandler)
1717
}
1818

1919
func (router DeploymentConfigRouterImpl) Init(configRouter *mux.Router) {
20-
configRouter.Path("/upload").
20+
configRouter.Path("/validate").
2121
HandlerFunc(router.deploymentRestHandler.CreateChartFromFile).Methods("POST")
22+
configRouter.Path("/upload").
23+
HandlerFunc(router.deploymentRestHandler.SaveChart).Methods("PUT")
2224
}

pkg/pipeline/ChartService.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ type ChartService interface {
134134
CheckChartExists(chartRefId int) error
135135
GetLocationFromChartNameAndVersion(chartName string, chartVersion string) string
136136
ValidateUploadedFileFormat(fileName string) error
137-
ReadChartMetaDataForLocation(chartDir string, fileName string) (string, string, error)
137+
ReadChartMetaDataForLocation(chartDir string, fileName string) (*ChartYamlStruct, error)
138138
}
139139
type ChartServiceImpl struct {
140140
chartRepository chartRepoRepository.ChartRepository
@@ -905,15 +905,17 @@ type chartRefResponse struct {
905905
}
906906

907907
type ChartYamlStruct struct {
908-
Name string `yaml:"name"`
909-
Version string `yaml:"version"`
908+
Name string `yaml:"name"`
909+
Version string `yaml:"version"`
910+
Description string `yaml:"description"`
910911
}
911912

912913
type ChartDataInfo struct {
913914
ChartLocation string `json:"chartLocation"`
914915
ChartName string `json:"chartName"`
915916
ChartVersion string `json:"chartVersion"`
916917
TemporaryFolder string `json:"temporaryFolder"`
918+
Description string `json:"description"`
917919
}
918920

919921
func (impl ChartServiceImpl) ChartRefAutocomplete() ([]chartRef, error) {
@@ -1305,31 +1307,31 @@ func (impl *ChartServiceImpl) ValidateUploadedFileFormat(fileName string) error
13051307
return nil
13061308
}
13071309

1308-
func (impl ChartServiceImpl) ReadChartMetaDataForLocation(chartDir string, fileName string) (string, string, error) {
1310+
func (impl ChartServiceImpl) ReadChartMetaDataForLocation(chartDir string, fileName string) (*ChartYamlStruct, error) {
13091311
chartLocation := filepath.Clean(filepath.Join(chartDir, fileName))
13101312

13111313
chartYamlPath := filepath.Clean(filepath.Join(chartLocation, "Chart.yaml"))
13121314
if _, err := os.Stat(chartYamlPath); os.IsNotExist(err) {
1313-
return "", "", fmt.Errorf("Chart.yaml file not present in the directory")
1315+
return nil, fmt.Errorf("Chart.yaml file not present in the directory")
13141316
}
13151317

13161318
data, err := ioutil.ReadFile(chartYamlPath)
13171319
if err != nil {
13181320
impl.logger.Errorw("failed reading data from file", "err", err)
1319-
return "", "", err
1321+
return nil, err
13201322
}
13211323
//println(data)
13221324
var chartYaml ChartYamlStruct
13231325
err = yaml.Unmarshal(data, &chartYaml)
13241326
if err != nil {
13251327
impl.logger.Errorw("Unmarshal error of yaml file", "err", err)
1326-
return "", "", err
1328+
return nil, err
13271329
}
13281330
if chartYaml.Name == "" || chartYaml.Version == "" {
13291331
impl.logger.Errorw("Missing values in yaml file either name or version", "err", err)
1330-
return "", "", errors.New("Missing values in yaml file either name or version")
1332+
return nil, errors.New("Missing values in yaml file either name or version")
13311333
}
1332-
return chartYaml.Name, chartYaml.Version, nil
1334+
return &chartYaml, nil
13331335
}
13341336

13351337
func (impl ChartServiceImpl) ExtractChartIfMissing(chartData []byte, refChartDir string, location string) (*ChartDataInfo, error) {
@@ -1340,6 +1342,7 @@ func (impl ChartServiceImpl) ExtractChartIfMissing(chartData []byte, refChartDir
13401342
ChartVersion: "",
13411343
ChartLocation: "",
13421344
TemporaryFolder: "",
1345+
Description: "",
13431346
}
13441347
temporaryChartWorkingDir := filepath.Clean(filepath.Join(refChartDir, dir))
13451348
err := os.MkdirAll(temporaryChartWorkingDir, os.ModePerm)
@@ -1373,7 +1376,10 @@ func (impl ChartServiceImpl) ExtractChartIfMissing(chartData []byte, refChartDir
13731376
currentChartWorkingDir := filepath.Clean(filepath.Join(temporaryChartWorkingDir, fileName))
13741377

13751378
if location == "" {
1376-
chartName, chartVersion, err = impl.ReadChartMetaDataForLocation(temporaryChartWorkingDir, fileName)
1379+
chartYaml, err := impl.ReadChartMetaDataForLocation(temporaryChartWorkingDir, fileName)
1380+
chartName = chartYaml.Name
1381+
chartVersion = chartYaml.Version
1382+
chartInfo.Description = chartYaml.Description
13771383
if err != nil {
13781384
impl.logger.Errorw("Chart yaml file not found")
13791385
return chartInfo, err
@@ -1398,12 +1404,14 @@ func (impl ChartServiceImpl) ExtractChartIfMissing(chartData []byte, refChartDir
13981404
return chartInfo, err
13991405
}
14001406
location = chartLocation
1407+
1408+
err = dirCopy.Copy(currentChartWorkingDir, filepath.Clean(filepath.Join(refChartDir, location)))
1409+
if err != nil {
1410+
impl.logger.Errorw("error in copying chart from temp dir to ref chart dir", "err", err)
1411+
return chartInfo, err
1412+
}
14011413
}
1402-
err = dirCopy.Copy(currentChartWorkingDir, filepath.Clean(filepath.Join(refChartDir, location)))
1403-
if err != nil {
1404-
impl.logger.Errorw("error in copying chart from temp dir to ref chart dir", "err", err)
1405-
return chartInfo, err
1406-
}
1414+
14071415
chartInfo.ChartLocation = location
14081416
chartInfo.ChartName = chartName
14091417
chartInfo.ChartVersion = chartVersion

0 commit comments

Comments
 (0)