Skip to content

Commit

Permalink
feat(cli): add support for multiple sources to sync command (#18016)
Browse files Browse the repository at this point in the history
* update sync command

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

use arrays instead of map to display ApplicationManifetQuery fields in swagger

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rebase and update logic for sync command

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

update conditions

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

update displayRevisions on OperationState

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

remove rerunreport file

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix index 0 out of bounds error

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

Address comments

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix codegen

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rename GetSourcePtrBySourceIndex to GetSourcePtrByIndex

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rename GetSourcePtrBySourcePosition to GetSourcePtrByPosition

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rebase with master and resolve conflicts

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix codegen

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

Address feedback and add tests

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix unit test

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

* codegen post cherry-pick

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

---------

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>
  • Loading branch information
ishitasequeira committed Apr 29, 2024
1 parent e1f890d commit f875931
Show file tree
Hide file tree
Showing 15 changed files with 834 additions and 361 deletions.
13 changes: 13 additions & 0 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -4238,6 +4238,19 @@
"revision": {
"type": "string"
},
"revisions": {
"type": "array",
"items": {
"type": "string"
}
},
"sourcePositions": {
"type": "array",
"items": {
"type": "string",
"format": "int64"
}
},
"strategy": {
"$ref": "#/definitions/v1alpha1SyncStrategy"
},
Expand Down
56 changes: 41 additions & 15 deletions cmd/argocd/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
}
}

source := app.Spec.GetSourcePtr(sourcePosition)
source := app.Spec.GetSourcePtrByPosition(sourcePosition)

updated, nothingToUnset := unset(source, opts)
if nothingToUnset {
Expand Down Expand Up @@ -1807,6 +1807,8 @@ func printTreeViewDetailed(nodeMapping map[string]argoappv1.ResourceNode, parent
func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
revision string
revisions []string
sourcePositions []int64
resources []string
labels []string
selector string
Expand Down Expand Up @@ -1849,6 +1851,9 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
argocd app sync -l '!app.kubernetes.io/instance'
argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)'
# Sync a multi-source application for specific revision of specific sources
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
# Sync a specific resource
# Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME
argocd app sync my-app --resource :Service:my-service
Expand All @@ -1867,6 +1872,21 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
if len(args) > 1 && selector != "" {
log.Fatal("Cannot use selector option when application name(s) passed as argument(s)")
}

if len(args) != 1 && (len(revisions) > 0 || len(sourcePositions) > 0) {
log.Fatal("Cannot use --revisions and --source-positions options when 0 or more than 1 application names are passed as argument(s)")
}

if len(revisions) != len(sourcePositions) {
log.Fatal("While using --revisions and --source-positions, length of values for both flags should be same.")
}

for _, pos := range sourcePositions {
if pos <= 0 {
log.Fatal("source-position cannot be less than or equal to 0, Counting starts at 1")
}
}

acdClient := headless.NewClientOrDie(clientOpts, c)
conn, appIf := acdClient.NewApplicationClientOrDie()
defer argoio.Close(conn)
Expand Down Expand Up @@ -1908,9 +1928,11 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co

if len(selectedLabels) > 0 {
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
Revision: &revision,
Name: &appName,
AppNamespace: &appNs,
Revision: &revision,
Revisions: revisions,
SourcePositions: sourcePositions,
}

res, err := appIf.GetManifests(ctx, &q)
Expand Down Expand Up @@ -1953,7 +1975,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co

if app.Spec.HasMultipleSources() {
if revision != "" {
log.Fatal("argocd cli does not work on multi-source app with --revision flag")
log.Fatal("argocd cli does not work on multi-source app with --revision flag. Use --revisions and --source-position instead.")
return
}

Expand Down Expand Up @@ -2018,15 +2040,17 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
}

syncReq := application.ApplicationSyncRequest{
Name: &appName,
AppNamespace: &appNs,
DryRun: &dryRun,
Revision: &revision,
Resources: filteredResources,
Prune: &prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
SyncOptions: syncOptionsFactory(),
Name: &appName,
AppNamespace: &appNs,
DryRun: &dryRun,
Revision: &revision,
Resources: filteredResources,
Prune: &prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
SyncOptions: syncOptionsFactory(),
Revisions: revisions,
SourcePositions: sourcePositions,
}

switch strategy {
Expand Down Expand Up @@ -2123,6 +2147,8 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree|tree=detailed")
command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only sync an application in namespace")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions")
command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.")
return command
}

Expand Down Expand Up @@ -2505,7 +2531,7 @@ func setParameterOverrides(app *argoappv1.Application, parameters []string, sour
if len(parameters) == 0 {
return
}
source := app.Spec.GetSourcePtr(sourcePosition)
source := app.Spec.GetSourcePtrByPosition(sourcePosition)
var sourceType argoappv1.ApplicationSourceType
if st, _ := source.ExplicitType(); st != nil {
sourceType = *st
Expand Down
14 changes: 7 additions & 7 deletions cmd/util/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,21 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field")
}

func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, index int) int {
func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, sourcePosition int) int {
visited := 0
if flags == nil {
return visited
}
source := spec.GetSourcePtr(index)
source := spec.GetSourcePtrByPosition(sourcePosition)
if source == nil {
source = &argoappv1.ApplicationSource{}
}
source, visited = ConstructSource(source, *appOpts, flags)
if spec.HasMultipleSources() {
if index == 0 {
spec.Sources[index] = *source
} else if index > 0 {
spec.Sources[index-1] = *source
if sourcePosition == 0 {
spec.Sources[sourcePosition] = *source
} else if sourcePosition > 0 {
spec.Sources[sourcePosition-1] = *source
} else {
spec.Sources = append(spec.Sources, *source)
}
Expand Down Expand Up @@ -428,7 +428,7 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string, inde
if len(parameters) == 0 {
return
}
source := app.Spec.GetSourcePtr(index)
source := app.Spec.GetSourcePtrByIndex(index)
var sourceType argoappv1.ApplicationSourceType
if st, _ := source.ExplicitType(); st != nil {
sourceType = *st
Expand Down
5 changes: 5 additions & 0 deletions docs/user-guide/commands/argocd_app_sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags]
argocd app sync -l '!app.kubernetes.io/instance'
argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)'
# Sync a multi-source application for specific revision of specific sources
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
# Sync a specific resource
# Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME
argocd app sync my-app --resource :Service:my-service
Expand Down Expand Up @@ -61,8 +64,10 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags]
--retry-backoff-max-duration duration Max retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s)
--retry-limit int Max number of allowed sync retries
--revision string Sync to a specific revision. Preserves parameter overrides
--revisions stringArray Show manifests at specific revisions for source position in source-positions
-l, --selector string Sync apps that match this label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints.
--server-side Use server-side apply while syncing the application
--source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default [])
--strategy string Sync strategy (one of: apply|hook)
--timeout uint Time out after this many seconds
```
Expand Down
Loading

0 comments on commit f875931

Please sign in to comment.