diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 088be0ea..ef4bc8bf 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -121,7 +121,7 @@ jobs: run: | /tmp/flux create hr podinfo-helm \ --target-namespace=default \ - --source=HelmRepository/podinfo \ + --source=HelmRepository/podinfo.flux-system \ --chart=podinfo \ --chart-version=">4.0.0 <5.0.0" - name: flux create helmrelease --source=GitRepository/podinfo diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index 4db39e4f..e1318f38 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -91,6 +91,12 @@ var createHelmReleaseCmd = &cobra.Command{ --source=HelmRepository/podinfo \ --chart=podinfo + # Create a HelmRelease using a source from a different namespace + flux create hr podinfo \ + --namespace=default \ + --source=HelmRepository/podinfo.flux-system \ + --chart=podinfo + # Create a HelmRelease definition on disk without applying it on the cluster flux create hr podinfo \ --source=HelmRepository/podinfo \ @@ -164,8 +170,9 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { Chart: helmReleaseArgs.chart, Version: helmReleaseArgs.chartVersion, SourceRef: helmv2.CrossNamespaceObjectReference{ - Kind: helmReleaseArgs.source.Kind, - Name: helmReleaseArgs.source.Name, + Kind: helmReleaseArgs.source.Kind, + Name: helmReleaseArgs.source.Name, + Namespace: helmReleaseArgs.source.Namespace, }, }, }, diff --git a/cmd/flux/create_kustomization.go b/cmd/flux/create_kustomization.go index 1ddcfc11..fa48272c 100644 --- a/cmd/flux/create_kustomization.go +++ b/cmd/flux/create_kustomization.go @@ -46,7 +46,7 @@ var createKsCmd = &cobra.Command{ Long: "The kustomization source create command generates a Kustomize resource for a given source.", Example: ` # Create a Kustomization resource from a source at a given path flux create kustomization contour \ - --source=contour \ + --source=GitRepository/contour \ --path="./examples/contour/" \ --prune=true \ --interval=10m \ @@ -58,7 +58,16 @@ var createKsCmd = &cobra.Command{ # Create a Kustomization resource that depends on the previous one flux create kustomization webapp \ --depends-on=contour \ - --source=webapp \ + --source=GitRepository/webapp \ + --path="./deploy/overlays/dev" \ + --prune=true \ + --interval=5m \ + --validation=client + + # Create a Kustomization using a source from a different namespace + flux create kustomization podinfo \ + --namespace=default \ + --source=GitRepository/podinfo.flux-system \ --path="./deploy/overlays/dev" \ --prune=true \ --interval=5m \ @@ -145,8 +154,9 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { Path: filepath.ToSlash(kustomizationArgs.path.String()), Prune: kustomizationArgs.prune, SourceRef: kustomizev1.CrossNamespaceSourceReference{ - Kind: kustomizationArgs.source.Kind, - Name: kustomizationArgs.source.Name, + Kind: kustomizationArgs.source.Kind, + Name: kustomizationArgs.source.Name, + Namespace: kustomizationArgs.source.Namespace, }, Suspend: false, Validation: kustomizationArgs.validation, diff --git a/docs/cmd/flux_create_helmrelease.md b/docs/cmd/flux_create_helmrelease.md index e458ea06..38792c5c 100644 --- a/docs/cmd/flux_create_helmrelease.md +++ b/docs/cmd/flux_create_helmrelease.md @@ -62,6 +62,12 @@ flux create helmrelease [name] [flags] --source=HelmRepository/podinfo \ --chart=podinfo + # Create a HelmRelease using a source from a different namespace + flux create hr podinfo \ + --namespace=default \ + --source=HelmRepository/podinfo.flux-system \ + --chart=podinfo + # Create a HelmRelease definition on disk without applying it on the cluster flux create hr podinfo \ --source=HelmRepository/podinfo \ @@ -79,7 +85,7 @@ flux create helmrelease [name] [flags] -h, --help help for helmrelease --release-name string name used for the Helm release, defaults to a composition of '[-]' --service-account string the name of the service account to impersonate when reconciling this HelmRelease - --source helmChartSource source that contains the chart in the format '/', where kind must be one of: (HelmRepository, GitRepository, Bucket) + --source helmChartSource source that contains the chart in the format '/.', where kind must be one of: (HelmRepository, GitRepository, Bucket) --target-namespace string namespace to install this release, defaults to the HelmRelease namespace --values stringArray local path to values.yaml files --values-from helmReleaseValuesFrom Kubernetes object reference that contains the values.yaml data key in the format '/', where kind must be one of: (Secret, ConfigMap) diff --git a/docs/cmd/flux_create_kustomization.md b/docs/cmd/flux_create_kustomization.md index 38e2fb88..eed7eef5 100644 --- a/docs/cmd/flux_create_kustomization.md +++ b/docs/cmd/flux_create_kustomization.md @@ -18,7 +18,7 @@ flux create kustomization [name] [flags] ``` # Create a Kustomization resource from a source at a given path flux create kustomization contour \ - --source=contour \ + --source=GitRepository/contour \ --path="./examples/contour/" \ --prune=true \ --interval=10m \ @@ -30,7 +30,16 @@ flux create kustomization [name] [flags] # Create a Kustomization resource that depends on the previous one flux create kustomization webapp \ --depends-on=contour \ - --source=webapp \ + --source=GitRepository/webapp \ + --path="./deploy/overlays/dev" \ + --prune=true \ + --interval=5m \ + --validation=client + + # Create a Kustomization using a source from a different namespace + flux create kustomization podinfo \ + --namespace=default \ + --source=GitRepository/podinfo.flux-system \ --path="./deploy/overlays/dev" \ --prune=true \ --interval=5m \ @@ -55,7 +64,7 @@ flux create kustomization [name] [flags] --path safeRelativePath path to the directory containing a kustomization.yaml file (default ./) --prune enable garbage collection --service-account string the name of the service account to impersonate when reconciling this Kustomization - --source kustomizationSource source that contains the Kubernetes manifests in the format '[/]', where kind must be one of: (GitRepository, Bucket), if kind is not specified it defaults to GitRepository + --source kustomizationSource source that contains the Kubernetes manifests in the format '[/].', where kind must be one of: (GitRepository, Bucket), if kind is not specified it defaults to GitRepository --target-namespace string overrides the namespace of all Kustomization objects reconciled by this Kustomization --validation string validate the manifests before applying them on the cluster, can be 'client' or 'server' ``` diff --git a/internal/flags/helm_chart_source.go b/internal/flags/helm_chart_source.go index f367e43b..c085d21f 100644 --- a/internal/flags/helm_chart_source.go +++ b/internal/flags/helm_chart_source.go @@ -28,8 +28,9 @@ import ( var supportedHelmChartSourceKinds = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind} type HelmChartSource struct { - Kind string - Name string + Kind string + Name string + Namespace string } func (s *HelmChartSource) String() string { @@ -45,7 +46,7 @@ func (s *HelmChartSource) Set(str string) error { s.Description()) } - sourceKind, sourceName := utils.ParseObjectKindName(str) + sourceKind, sourceName, sourceNamespace := utils.ParseObjectKindNameNamespace(str) if sourceKind == "" || sourceName == "" { return fmt.Errorf("invalid helm chart source '%s', must be in format /", str) } @@ -55,8 +56,9 @@ func (s *HelmChartSource) Set(str string) error { sourceKind, strings.Join(supportedHelmChartSourceKinds, ", ")) } - s.Name = sourceName s.Kind = cleanSourceKind + s.Name = sourceName + s.Namespace = sourceNamespace return nil } @@ -67,7 +69,7 @@ func (s *HelmChartSource) Type() string { func (s *HelmChartSource) Description() string { return fmt.Sprintf( - "source that contains the chart in the format '/', "+ + "source that contains the chart in the format '/.', "+ "where kind must be one of: (%s)", strings.Join(supportedHelmChartSourceKinds, ", "), ) diff --git a/internal/flags/kustomization_source.go b/internal/flags/kustomization_source.go index 3b66ca70..ca0b9f8e 100644 --- a/internal/flags/kustomization_source.go +++ b/internal/flags/kustomization_source.go @@ -28,8 +28,9 @@ import ( var supportedKustomizationSourceKinds = []string{sourcev1.GitRepositoryKind, sourcev1.BucketKind} type KustomizationSource struct { - Kind string - Name string + Kind string + Name string + Namespace string } func (s *KustomizationSource) String() string { @@ -45,7 +46,7 @@ func (s *KustomizationSource) Set(str string) error { s.Description()) } - sourceKind, sourceName := utils.ParseObjectKindName(str) + sourceKind, sourceName, sourceNamespace := utils.ParseObjectKindNameNamespace(str) if sourceName == "" { return fmt.Errorf("no name given for source of kind '%s'", sourceKind) } @@ -61,8 +62,9 @@ func (s *KustomizationSource) Set(str string) error { sourceKind, strings.Join(supportedKustomizationSourceKinds, ", ")) } - s.Name = sourceName s.Kind = cleanSourceKind + s.Name = sourceName + s.Namespace = sourceNamespace return nil } @@ -73,7 +75,7 @@ func (s *KustomizationSource) Type() string { func (s *KustomizationSource) Description() string { return fmt.Sprintf( - "source that contains the Kubernetes manifests in the format '[/]', "+ + "source that contains the Kubernetes manifests in the format '[/].', "+ "where kind must be one of: (%s), if kind is not specified it defaults to GitRepository", strings.Join(supportedKustomizationSourceKinds, ", "), ) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 594b99b5..461fdd74 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -216,9 +216,10 @@ func ContainsEqualFoldItemString(s []string, e string) (string, bool) { return "", false } -func ParseObjectKindName(input string) (string, string) { - kind := "" - name := input +// ParseObjectKindName extracts the kind and name of a resource +// based on the '/' format +func ParseObjectKindName(input string) (kind, name string) { + name = input parts := strings.Split(input, "/") if len(parts) == 2 { kind, name = parts[0], parts[1] @@ -226,6 +227,23 @@ func ParseObjectKindName(input string) (string, string) { return kind, name } +// ParseObjectKindNameNamespace extracts the kind, name and namespace of a resource +// based on the '/.' format +func ParseObjectKindNameNamespace(input string) (kind, name, namespace string) { + name = input + parts := strings.Split(input, "/") + if len(parts) == 2 { + kind, name = parts[0], parts[1] + } + + if nn := strings.Split(name, "."); len(nn) > 1 { + name = strings.Join(nn[:len(nn)-1], ".") + namespace = nn[len(nn)-1] + } + + return kind, name, namespace +} + func MakeDependsOn(deps []string) []dependency.CrossNamespaceDependencyReference { refs := []dependency.CrossNamespaceDependencyReference{} for _, dep := range deps {