Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion cmd/argocd/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/server/application"
"github.com/argoproj/argo-cd/util"
"github.com/argoproj/argo-cd/util/argo"
"github.com/argoproj/argo-cd/util/cli"
"github.com/argoproj/argo-cd/util/diff"
"github.com/argoproj/argo-cd/util/ksonnet"
Expand Down Expand Up @@ -312,17 +313,33 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
os.Exit(1)
}
setParameterOverrides(app, appOpts.parameters)
_, err = appIf.UpdateSpec(context.Background(), &application.ApplicationUpdateSpecRequest{
oldOverrides := app.Spec.Source.ComponentParameterOverrides
updatedSpec, err := appIf.UpdateSpec(context.Background(), &application.ApplicationUpdateSpecRequest{
Name: &app.Name,
Spec: app.Spec,
})
errors.CheckError(err)

newOverrides := updatedSpec.Source.ComponentParameterOverrides
checkDroppedParams(newOverrides, oldOverrides)
},
}
addAppFlags(command, &appOpts)
return command
}

func checkDroppedParams(newOverrides []argoappv1.ComponentParameter, oldOverrides []argoappv1.ComponentParameter) {
newOverrideMap := argo.ParamToMap(newOverrides)

if len(oldOverrides) > len(newOverrides) {
for _, oldOverride := range oldOverrides {
if !argo.CheckValidParam(newOverrideMap, oldOverride) {
log.Warnf("Parameter %s in %s does not exist in ksonnet, parameter override dropped", oldOverride.Name, oldOverride.Component)
}
}
}
}

type appOptions struct {
repoURL string
appPath string
Expand Down
48 changes: 47 additions & 1 deletion server/application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"strings"
"time"

"github.com/argoproj/argo-cd/util/argo"

"github.com/ghodss/yaml"
"github.com/ksonnet/ksonnet/pkg/app"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -250,7 +252,47 @@ func (s *Server) Update(ctx context.Context, q *ApplicationUpdateRequest) (*appv
return s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Update(a)
}

// UpdateSpec updates an application spec
// removeInvalidOverrides removes any prameter overrides that are no longer valid
// drops old overrides that are invalid
// throws an error is passed override is invalid
// if passed override and old overrides are invalid, throws error, old overrides not dropped
func (s *Server) removeInvalidOverrides(a *appv1.Application, q *ApplicationUpdateSpecRequest) (*ApplicationUpdateSpecRequest, error) {
validAppSet := argo.ParamToMap(a.Status.Parameters)
invalidOldParams := make(map[string]map[string]bool)
var overrideParams []appv1.ComponentParameter
for _, unvettedExistingParam := range a.Spec.Source.ComponentParameterOverrides {
if argo.CheckValidParam(validAppSet, unvettedExistingParam) {
overrideParams = append(overrideParams, unvettedExistingParam)
} else {
if invalidOldParams[unvettedExistingParam.Component] == nil {
invalidOldParams[unvettedExistingParam.Component] = make(map[string]bool)
}
invalidOldParams[unvettedExistingParam.Component][unvettedExistingParam.Name] = true
}
}
for _, unvettedRequestedParam := range q.Spec.Source.ComponentParameterOverrides {
if argo.CheckValidParam(validAppSet, unvettedRequestedParam) {
paramExists := false
for _, overrideParam := range overrideParams {
if unvettedRequestedParam.Component == overrideParam.Component && unvettedRequestedParam.Name == overrideParam.Name && unvettedRequestedParam.Value == overrideParam.Value {
paramExists = true
}
}
if !paramExists {
overrideParams = append(overrideParams, unvettedRequestedParam)
}
} else {
if !argo.CheckValidParam(invalidOldParams, unvettedRequestedParam) {
return nil, status.Errorf(codes.InvalidArgument, "Parameter '%s' in '%s' does not exist in ksonnet", unvettedRequestedParam.Name, unvettedRequestedParam.Component)

}
}
}
q.Spec.Source.ComponentParameterOverrides = overrideParams
return q, nil
}

// UpdateSpec updates an application spec and filters out any invalid parameter overrides
func (s *Server) UpdateSpec(ctx context.Context, q *ApplicationUpdateSpecRequest) (*appv1.ApplicationSpec, error) {

if !q.Spec.BelongsToDefaultProject() {
Expand All @@ -269,6 +311,10 @@ func (s *Server) UpdateSpec(ctx context.Context, q *ApplicationUpdateSpecRequest
if err != nil {
return nil, err
}
q, err = s.removeInvalidOverrides(a, q)
if err != nil {
return nil, err
}
patch, err := json.Marshal(map[string]appv1.ApplicationSpec{
"spec": q.Spec,
})
Expand Down
23 changes: 23 additions & 0 deletions util/argo/argo.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ func FilterByProjects(apps []argoappv1.Application, projects []string) []argoapp
}
}
return items

}

//ParamToMap converts a ComponentParameter list to a map for easy filtering
func ParamToMap(params []argoappv1.ComponentParameter) map[string]map[string]bool {
validAppSet := make(map[string]map[string]bool)
for _, p := range params {
if validAppSet[p.Component] == nil {
validAppSet[p.Component] = make(map[string]bool)
}
validAppSet[p.Component][p.Name] = true
}
return validAppSet
}

// CheckValidParam checks if the parameter passed is overridable for the given appMap
func CheckValidParam(appMap map[string]map[string]bool, newParam argoappv1.ComponentParameter) bool {
if val, ok := appMap[newParam.Component]; ok {
if _, ok2 := val[newParam.Name]; ok2 {
return true
}
}
return false
}

// RefreshApp updates the refresh annotation of an application to coerce the controller to process it
Expand Down
18 changes: 18 additions & 0 deletions util/argo/argo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,24 @@ func TestRefreshApp(t *testing.T) {
//assert.True(t, ok)
}

func TestCheckValidParam(t *testing.T) {
oldAppSet := make(map[string]map[string]bool)
oldAppSet["testComponent"] = make(map[string]bool)
oldAppSet["testComponent"]["overrideParam"] = true
newParam := argoappv1.ComponentParameter{
Component: "testComponent",
Name: "overrideParam",
Value: "new-value",
}
badParam := argoappv1.ComponentParameter{
Component: "testComponent",
Name: "badParam",
Value: "new-value",
}
assert.True(t, CheckValidParam(oldAppSet, newParam))
assert.False(t, CheckValidParam(oldAppSet, badParam))
}

func TestWaitForRefresh(t *testing.T) {
appClientset := appclientset.NewSimpleClientset()

Expand Down