Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2dda807
Make values accepts a string and an object
mcbenjemaa Mar 10, 2022
4abd841
Fix string Values
mcbenjemaa Mar 11, 2022
61ca96d
Make argocd application spec.source.hem.values accepts either a stri…
mcbenjemaa Mar 16, 2022
b5f6ecd
Add org to users
mcbenjemaa Mar 21, 2022
e23b384
Fix e2e test and fix lint
mcbenjemaa Mar 21, 2022
953ce0a
Add unit test for helm values as raw format
mcbenjemaa Mar 22, 2022
831035a
Fix MarshalJSON
mcbenjemaa Mar 22, 2022
40533b2
Fix TestHelmValuesLiteralFileRemote test
Mar 22, 2022
b6718cb
Add a cli flag for accepting helm values as raw object and adding an …
mcbenjemaa Mar 30, 2022
f201dc1
Regenrate
mcbenjemaa Mar 30, 2022
b83d435
docs: clarify flag docs
crenshaw-dev Apr 12, 2022
1b96fe0
chore: merge upstream
crenshaw-dev Apr 12, 2022
48675a9
chore: abstract function
crenshaw-dev Apr 12, 2022
8b48442
chore: better order
crenshaw-dev Apr 12, 2022
fdd9d22
chore: ordering
crenshaw-dev Apr 12, 2022
aea275d
chore: hack to allow strings or objects for values field
crenshaw-dev Apr 13, 2022
240db7f
chore: tests
crenshaw-dev Apr 13, 2022
c06465a
chore: encapsulate and test StringOrObject behavior
crenshaw-dev Apr 13, 2022
fca3a62
chore: lint
crenshaw-dev Apr 13, 2022
6fa9472
chore: more tests
crenshaw-dev Apr 14, 2022
77c6405
chore: lint
crenshaw-dev Apr 14, 2022
e55e5d5
chore: more tests
crenshaw-dev Apr 14, 2022
3eadae8
chore: make the tests actually test something
crenshaw-dev Apr 14, 2022
3056255
chore: update cli docs
crenshaw-dev Apr 14, 2022
ac74c6a
chore: test all the things
crenshaw-dev Apr 14, 2022
ecc2030
chore: better IsEmpty function
crenshaw-dev Apr 14, 2022
6634172
chore: don't do tests in this PR
crenshaw-dev Apr 14, 2022
6bafc0a
chore: need coffee
crenshaw-dev Apr 14, 2022
06c27fb
Merge branch 'master' into feat/argocd-helm-values-raw
crenshaw-dev Apr 14, 2022
0990517
Merge branch 'master' into feat/argocd-helm-values-raw
crenshaw-dev Apr 14, 2022
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
3 changes: 2 additions & 1 deletion USERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Quipper](https://www.quipper.com/)
1. [Recreation.gov](https://www.recreation.gov/)
1. [Red Hat](https://www.redhat.com/)
1. [Renault Group](https://www.renaultgroup.com/)
1. [RightRev](https://rightrev.com/)
1. [Rise](https://www.risecard.eu/)
1. [Riskified](https://www.riskified.com/)
Expand Down Expand Up @@ -175,6 +176,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Tiger Analytics](https://www.tigeranalytics.com/)
1. [Tigera](https://www.tigera.io/)
1. [Toss](https://toss.im/en)
1. [Trendyol](https://www.trendyol.com/)
1. [tru.ID](https://tru.id)
1. [Twilio SendGrid](https://sendgrid.com)
1. [tZERO](https://www.tzero.com/)
Expand Down Expand Up @@ -202,4 +204,3 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Yubo](https://www.yubo.live/)
1. [Zimpler](https://www.zimpler.com/)
1. [ZOZO](https://corp.zozo.com/)
1. [Trendyol](https://www.trendyol.com/)
6 changes: 4 additions & 2 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -4946,8 +4946,7 @@
}
},
"values": {
"type": "string",
"title": "Values specifies Helm values to be passed to helm template, typically defined as a block"
"$ref": "#/definitions/v1alpha1StringOrObject"
},
"version": {
"type": "string",
Expand Down Expand Up @@ -6459,6 +6458,9 @@
}
}
},
"v1alpha1StringOrObject": {
"description": "Either a string or an object"
},
"v1alpha1SyncOperation": {
"description": "SyncOperation contains details about a sync operation.",
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion cmd/argocd/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
}
}
if valuesLiteral {
app.Spec.Source.Helm.Values = ""
app.Spec.Source.Helm.Values = argoappv1.NewStringOrObjectFromString("")
updated = true
}
for _, valuesFile := range valuesFiles {
Expand Down
42 changes: 30 additions & 12 deletions cmd/util/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"github.com/argoproj/gitops-engine/pkg/utils/kube"

log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -74,6 +73,7 @@ type AppOptions struct {
retryBackoffDuration time.Duration
retryBackoffMaxDuration time.Duration
retryBackoffFactor int64
valuesRaw string
}

func AddAppFlags(command *cobra.Command, opts *AppOptions) {
Expand All @@ -89,7 +89,8 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
command.Flags().StringArrayVarP(&opts.Parameters, "parameter", "p", []string{}, "set a parameter override (e.g. -p guestbook=image=example/guestbook:latest)")
command.Flags().StringArrayVar(&opts.valuesFiles, "values", []string{}, "Helm values file(s) to use")
command.Flags().BoolVar(&opts.ignoreMissingValueFiles, "ignore-missing-value-files", false, "Ignore locally missing valueFiles when setting helm template --values")
command.Flags().StringVar(&opts.values, "values-literal-file", "", "Filename or URL to import as a literal Helm values block")
command.Flags().StringVar(&opts.values, "values-literal-file", "", "Filename or URL to import as a literal Helm values block (as a string)")
command.Flags().StringVar(&opts.valuesRaw, "values-raw-literal-file", "", "Filename or URL to import as a literal Helm values block (as a map)")
command.Flags().StringVar(&opts.releaseName, "release-name", "", "Helm release-name")
command.Flags().StringVar(&opts.helmVersion, "helm-version", "", "Helm version")
command.Flags().BoolVar(&opts.helmPassCredentials, "helm-pass-credentials", false, "Pass credentials to all domain")
Expand Down Expand Up @@ -152,17 +153,13 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap
case "ignore-missing-value-files":
setHelmOpt(&spec.Source, helmOpts{ignoreMissingValueFiles: appOpts.ignoreMissingValueFiles})
case "values-literal-file":
var data []byte

// read uri
parsedURL, err := url.ParseRequestURI(appOpts.values)
if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") {
data, err = ioutil.ReadFile(appOpts.values)
} else {
data, err = config.ReadRemoteFile(appOpts.values)
}
data, err := getValuesFromRef(appOpts.values)
errors.CheckError(err)
setHelmOpt(&spec.Source, helmOpts{values: string(data)})
case "values-raw-literal-file":
data, err := getValuesFromRef(appOpts.valuesRaw)
errors.CheckError(err)
setHelmOpt(&spec.Source, helmOpts{valuesRaw: data})
case "release-name":
setHelmOpt(&spec.Source, helmOpts{releaseName: appOpts.releaseName})
case "helm-version":
Expand Down Expand Up @@ -316,6 +313,20 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap
return visited
}

// getValuesFromRef gets values file contents, either from and http(s) source or from disk.
func getValuesFromRef(valuesRef string) ([]byte, error) {
var data []byte

// read uri
parsedURL, err := url.ParseRequestURI(valuesRef)
if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") {
data, err = ioutil.ReadFile(valuesRef)
} else {
data, err = config.ReadRemoteFile(valuesRef)
}
return data, err
}

type kustomizeOpts struct {
namePrefix string
nameSuffix string
Expand Down Expand Up @@ -378,6 +389,7 @@ type helmOpts struct {
valueFiles []string
ignoreMissingValueFiles bool
values string
valuesRaw []byte
releaseName string
version string
helmSets []string
Expand All @@ -398,7 +410,13 @@ func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) {
src.Helm.IgnoreMissingValueFiles = opts.ignoreMissingValueFiles
}
if len(opts.values) > 0 {
src.Helm.Values = opts.values
src.Helm.Values.SetStringValue(opts.values)
}
if len(opts.valuesRaw) > 0 {
err := src.Helm.Values.SetYAMLValue(opts.valuesRaw)
if err != nil {
log.Fatal(err)
}
}
if opts.releaseName != "" {
src.Helm.ReleaseName = opts.releaseName
Expand Down
98 changes: 98 additions & 0 deletions cmd/util/app_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package util

import (
"github.com/ghodss/yaml"
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"testing"
Expand Down Expand Up @@ -192,6 +194,102 @@ func Test_setAppSpecOptions(t *testing.T) {
})
}

var configMapUrl = "https://raw.githubusercontent.com/argoproj/argo-cd/db547567b9eafcba44e3df2883a40b8d03c71bf0/manifests/base/config/argocd-cm.yaml"
var congigMapYaml = `apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
`

func Test_setAppSpecOptions_valuesLiteralFile(t *testing.T) {
testCases := []struct{
name string
sourceUrl string
expectedYaml string
}{
{
name: "valid yaml",
sourceUrl: writeTempFile(t, "some: yaml"),
expectedYaml: "some: yaml",
},
{
name: "invalid yaml",
sourceUrl: writeTempFile(t, "{some invalid yaml"),
expectedYaml: "{some invalid yaml",
},
{
name: "ConfigMap from URL",
sourceUrl: configMapUrl,
expectedYaml: congigMapYaml,
},
}

for _, testCase := range testCases {
testCaseCopy := testCase

t.Run(testCaseCopy.name, func(t *testing.T) {
t.Parallel()

f := newAppOptionsFixture()
assert.NoError(t, f.SetFlag("values-literal-file", testCaseCopy.sourceUrl))
assert.Equal(t, testCaseCopy.expectedYaml, string(f.spec.Source.Helm.Values.YAML()))
})
}
}

func Test_setAppSpecOptions_valuesRawLiteralFile(t *testing.T) {
// Unmarshal and re-marshal so it's sorted.
var unmarshalledYaml interface{}
err := yaml.Unmarshal([]byte(congigMapYaml), &unmarshalledYaml)
require.NoError(t, err)
marshalledYaml, err := yaml.Marshal(unmarshalledYaml)
require.NoError(t, err)

testCases := []struct{
name string
sourceUrl string
expectedYaml string
}{
{
name: "valid yaml",
sourceUrl: writeTempFile(t, "some: yaml"),
expectedYaml: "some: yaml\n",
},
{
name: "ConfigMap from URL",
sourceUrl: configMapUrl,
expectedYaml: string(marshalledYaml),
},
}

for _, testCase := range testCases {
testCaseCopy := testCase

t.Run(testCaseCopy.name, func(t *testing.T) {
t.Parallel()

f := newAppOptionsFixture()
assert.NoError(t, f.SetFlag("values-raw-literal-file", testCaseCopy.sourceUrl))
assert.Equal(t, testCaseCopy.expectedYaml, string(f.spec.Source.Helm.Values.YAML()))
})
}
}

func writeTempFile(t *testing.T, contents string) string {
tempYaml, err := ioutil.TempFile(t.TempDir(), "")
require.NoError(t, err)
_, err = tempYaml.WriteString(contents)
require.NoError(t, err)
err = tempYaml.Sync()
require.NoError(t, err)
err = tempYaml.Close()
require.NoError(t, err)
return tempYaml.Name()
}

func Test_setAnnotations(t *testing.T) {
t.Run("Annotations", func(t *testing.T) {
app := v1alpha1.Application{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ argocd admin app generate-spec APPNAME [flags]
--sync-retry-limit int Max number of allowed sync retries
--validate Validation of repo and cluster (default true)
--values stringArray Helm values file(s) to use
--values-literal-file string Filename or URL to import as a literal Helm values block
--values-literal-file string Filename or URL to import as a literal Helm values block (as a string)
--values-raw-literal-file string Filename or URL to import as a literal Helm values block (as a map)
```

### Options inherited from parent commands
Expand Down
3 changes: 2 additions & 1 deletion docs/user-guide/commands/argocd_app_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ argocd app create APPNAME [flags]
--upsert Allows to override application with the same name even if supplied application spec is different from existing spec
--validate Validation of repo and cluster (default true)
--values stringArray Helm values file(s) to use
--values-literal-file string Filename or URL to import as a literal Helm values block
--values-literal-file string Filename or URL to import as a literal Helm values block (as a string)
--values-raw-literal-file string Filename or URL to import as a literal Helm values block (as a map)
```

### Options inherited from parent commands
Expand Down
3 changes: 2 additions & 1 deletion docs/user-guide/commands/argocd_app_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ argocd app set APPNAME [flags]
--sync-retry-limit int Max number of allowed sync retries
--validate Validation of repo and cluster (default true)
--values stringArray Helm values file(s) to use
--values-literal-file string Filename or URL to import as a literal Helm values block
--values-literal-file string Filename or URL to import as a literal Helm values block (as a string)
--values-raw-literal-file string Filename or URL to import as a literal Helm values block (as a map)
```

### Options inherited from parent commands
Expand Down
9 changes: 7 additions & 2 deletions hack/generate-proto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ EOF
rm -f "${SWAGGER_OUT}"

find "${SWAGGER_ROOT}" -name '*.swagger.json' -exec swagger mixin -c "${EXPECTED_COLLISIONS}" "${PRIMARY_SWAGGER}" '{}' \+ > "${COMBINED_SWAGGER}"
jq -r 'del(.definitions[].properties[]? | select(."$ref"!=null and .description!=null).description) | del(.definitions[].properties[]? | select(."$ref"!=null and .title!=null).title)' "${COMBINED_SWAGGER}" > "${SWAGGER_OUT}"
jq -r 'del(.definitions[].properties[]? | select(."$ref"!=null and .description!=null).description) |
del(.definitions[].properties[]? | select(."$ref"!=null and .title!=null).title) |
del(.definitions.runtimeRawExtension) |
if .definitions.v1alpha1StringOrObject then .definitions.v1alpha1StringOrObject = {"description": "Either a string or an object"} else . end' \
"${COMBINED_SWAGGER}" > "${SWAGGER_OUT}"


/bin/rm "${PRIMARY_SWAGGER}" "${COMBINED_SWAGGER}"
}
Expand All @@ -121,7 +126,7 @@ clean_swagger() {
}

echo "If additional types are added, the number of expected collisions may need to be increased"
EXPECTED_COLLISION_COUNT=62
EXPECTED_COLLISION_COUNT=63
collect_swagger server ${EXPECTED_COLLISION_COUNT}
clean_swagger server
clean_swagger reposerver
Expand Down
Loading