Add OCI support to `create source helm`

closes #2774

Signed-off-by: Max Jonas Werner <mail@makk.es>
pull/2781/head
Max Jonas Werner 3 years ago
parent bcef28e80b
commit e19ea796b1
No known key found for this signature in database
GPG Key ID: EB525E0F02B52140

@ -44,23 +44,34 @@ var createSourceHelmCmd = &cobra.Command{
Short: "Create or update a HelmRepository source", Short: "Create or update a HelmRepository source",
Long: `The create source helm command generates a HelmRepository resource and waits for it to fetch the index. Long: `The create source helm command generates a HelmRepository resource and waits for it to fetch the index.
For private Helm repositories, the basic authentication credentials are stored in a Kubernetes secret.`, For private Helm repositories, the basic authentication credentials are stored in a Kubernetes secret.`,
Example: ` # Create a source for a public Helm repository Example: ` # Create a source for an HTTPS public Helm repository
flux create source helm podinfo \ flux create source helm podinfo \
--url=https://stefanprodan.github.io/podinfo \ --url=https://stefanprodan.github.io/podinfo \
--interval=10m --interval=10m
# Create a source for a Helm repository using basic authentication # Create a source for an HTTPS Helm repository using basic authentication
flux create source helm podinfo \ flux create source helm podinfo \
--url=https://stefanprodan.github.io/podinfo \ --url=https://stefanprodan.github.io/podinfo \
--username=username \ --username=username \
--password=password --password=password
# Create a source for a Helm repository using TLS authentication # Create a source for an HTTPS Helm repository using TLS authentication
flux create source helm podinfo \ flux create source helm podinfo \
--url=https://stefanprodan.github.io/podinfo \ --url=https://stefanprodan.github.io/podinfo \
--cert-file=./cert.crt \ --cert-file=./cert.crt \
--key-file=./key.crt \ --key-file=./key.crt \
--ca-file=./ca.crt`, --ca-file=./ca.crt
# Create a source for an OCI Helm repository
flux create source helm podinfo \
--url=oci://ghcr.io/stefanprodan/charts/podinfo
--username=username \
--password=password
# Create a source for an OCI Helm repository using an existing secret with basic auth or dockerconfig credentials
flux create source helm podinfo \
--url=oci://ghcr.io/stefanprodan/charts/podinfo
--secret-ref=docker-config`,
RunE: createSourceHelmCmdRun, RunE: createSourceHelmCmdRun,
} }
@ -84,7 +95,7 @@ func init() {
createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.certFile, "cert-file", "", "TLS authentication cert file path") createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.certFile, "cert-file", "", "TLS authentication cert file path")
createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.keyFile, "key-file", "", "TLS authentication key file path") createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.keyFile, "key-file", "", "TLS authentication key file path")
createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.caFile, "ca-file", "", "TLS authentication CA file path") createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.caFile, "ca-file", "", "TLS authentication CA file path")
createSourceHelmCmd.Flags().StringVarP(&sourceHelmArgs.secretRef, "secret-ref", "", "", "the name of an existing secret containing TLS or basic auth credentials") createSourceHelmCmd.Flags().StringVarP(&sourceHelmArgs.secretRef, "secret-ref", "", "", "the name of an existing secret containing TLS, basic auth or docker-config credentials")
createSourceHelmCmd.Flags().BoolVarP(&sourceHelmArgs.passCredentials, "pass-credentials", "", false, "pass credentials to all domains") createSourceHelmCmd.Flags().BoolVarP(&sourceHelmArgs.passCredentials, "pass-credentials", "", false, "pass credentials to all domains")
createSourceCmd.AddCommand(createSourceHelmCmd) createSourceCmd.AddCommand(createSourceHelmCmd)
@ -126,6 +137,14 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
}, },
} }
url, err := url.Parse(sourceHelmArgs.url)
if err != nil {
return fmt.Errorf("failed to parse URL: %w", err)
}
if url.Scheme == sourcev1.HelmRepositoryTypeOCI {
helmRepository.Spec.Type = sourcev1.HelmRepositoryTypeOCI
}
if createSourceArgs.fetchTimeout > 0 { if createSourceArgs.fetchTimeout > 0 {
helmRepository.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout} helmRepository.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout}
} }
@ -196,6 +215,11 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
} }
logger.Successf("HelmRepository source reconciliation completed") logger.Successf("HelmRepository source reconciliation completed")
if helmRepository.Spec.Type == sourcev1.HelmRepositoryTypeOCI {
// OCI repos don't expose any artifact so we just return early here
return nil
}
if helmRepository.Status.Artifact == nil { if helmRepository.Status.Artifact == nil {
return fmt.Errorf("HelmRepository source reconciliation completed but no artifact was found") return fmt.Errorf("HelmRepository source reconciliation completed but no artifact was found")
} }

@ -0,0 +1,81 @@
//go:build unit
// +build unit
/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"testing"
)
func TestCreateSourceHelm(t *testing.T) {
tests := []struct {
name string
args string
resultFile string
assertFunc string
}{
{
name: "no args",
args: "create source helm",
resultFile: "name is required",
assertFunc: "assertError",
},
{
name: "OCI repo",
args: "create source helm podinfo --url=oci://ghcr.io/stefanprodan/charts/podinfo --interval 5m --export",
resultFile: "./testdata/create_source_helm/oci.golden",
assertFunc: "assertGoldenTemplateFile",
},
{
name: "OCI repo with Secret ref",
args: "create source helm podinfo --url=oci://ghcr.io/stefanprodan/charts/podinfo --interval 5m --secret-ref=creds --export",
resultFile: "./testdata/create_source_helm/oci-with-secret.golden",
assertFunc: "assertGoldenTemplateFile",
},
{
name: "HTTPS repo",
args: "create source helm podinfo --url=https://stefanprodan.github.io/charts/podinfo --interval 5m --export",
resultFile: "./testdata/create_source_helm/https.golden",
assertFunc: "assertGoldenTemplateFile",
},
}
tmpl := map[string]string{
"fluxns": allocateNamespace("flux-system"),
}
setup(t, tmpl)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var assert assertFunc
switch tt.assertFunc {
case "assertGoldenTemplateFile":
assert = assertGoldenTemplateFile(tt.resultFile, tmpl)
case "assertError":
assert = assertError(tt.resultFile)
}
cmd := cmdTestCase{
args: tt.args + " -n " + tmpl["fluxns"],
assert: assert,
}
cmd.runTestCmd(t)
})
}
}

@ -386,6 +386,7 @@ func executeCommand(cmd string) (string, error) {
func resetCmdArgs() { func resetCmdArgs() {
createArgs = createFlags{} createArgs = createFlags{}
getArgs = GetFlags{} getArgs = GetFlags{}
sourceHelmArgs = sourceHelmFlags{}
secretGitArgs = NewSecretGitFlags() secretGitArgs = NewSecretGitFlags()
} }

@ -0,0 +1,10 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: podinfo
namespace: {{ .fluxns }}
spec:
interval: 5m0s
url: https://stefanprodan.github.io/charts/podinfo

@ -0,0 +1,13 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: podinfo
namespace: {{ .fluxns }}
spec:
interval: 5m0s
secretRef:
name: creds
type: oci
url: oci://ghcr.io/stefanprodan/charts/podinfo

@ -0,0 +1,11 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: podinfo
namespace: {{ .fluxns }}
spec:
interval: 5m0s
type: oci
url: oci://ghcr.io/stefanprodan/charts/podinfo

@ -19,7 +19,7 @@ require (
github.com/fluxcd/pkg/ssh v0.4.1 github.com/fluxcd/pkg/ssh v0.4.1
github.com/fluxcd/pkg/untar v0.1.0 github.com/fluxcd/pkg/untar v0.1.0
github.com/fluxcd/pkg/version v0.1.0 github.com/fluxcd/pkg/version v0.1.0
github.com/fluxcd/source-controller/api v0.24.4 github.com/fluxcd/source-controller/api v0.25.0
github.com/go-git/go-git/v5 v5.4.2 github.com/go-git/go-git/v5 v5.4.2
github.com/gonvenience/bunt v1.3.3 github.com/gonvenience/bunt v1.3.3
github.com/gonvenience/ytbx v1.4.4 github.com/gonvenience/ytbx v1.4.4

@ -219,8 +219,8 @@ github.com/fluxcd/pkg/untar v0.1.0 h1:k97V/xV5hFrAkIkVPuv5AVhyxh1ZzzAKba/lbDfGo6
github.com/fluxcd/pkg/untar v0.1.0/go.mod h1:aGswNyzB1mlz/T/kpOS58mITBMxMKc9tlJBH037A2HY= github.com/fluxcd/pkg/untar v0.1.0/go.mod h1:aGswNyzB1mlz/T/kpOS58mITBMxMKc9tlJBH037A2HY=
github.com/fluxcd/pkg/version v0.1.0 h1:v+SmCanmCB5Tj2Cx9TXlj+kNRfPGbAvirkeqsp7ZEAQ= github.com/fluxcd/pkg/version v0.1.0 h1:v+SmCanmCB5Tj2Cx9TXlj+kNRfPGbAvirkeqsp7ZEAQ=
github.com/fluxcd/pkg/version v0.1.0/go.mod h1:V7Z/w8dxLQzv0FHqa5ox5TeyOd2zOd49EeuWFgnwyj4= github.com/fluxcd/pkg/version v0.1.0/go.mod h1:V7Z/w8dxLQzv0FHqa5ox5TeyOd2zOd49EeuWFgnwyj4=
github.com/fluxcd/source-controller/api v0.24.4 h1:m54sS1rJlgJf5j9qDRgKLhbPJAnJ9dY+VrstPKj0aQo= github.com/fluxcd/source-controller/api v0.25.0 h1:+uL+hQb/6h2MHuE9/Iq054TrDWF70puAuWBcoBrZK5M=
github.com/fluxcd/source-controller/api v0.24.4/go.mod h1:b0MmMPGE8gcpgSyGXe5m7see77tBW26eZrvGkkPstUs= github.com/fluxcd/source-controller/api v0.25.0/go.mod h1:tuMrqHHpRt7mxdLeRXGIMtTKAMufLwLTm5uXkEOJWFw=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=

@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.24.4/source-controller.crds.yaml - https://github.com/fluxcd/source-controller/releases/download/v0.25.0/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.24.4/source-controller.deployment.yaml - https://github.com/fluxcd/source-controller/releases/download/v0.25.0/source-controller.deployment.yaml
- account.yaml - account.yaml
patchesJson6902: patchesJson6902:
- target: - target:

Loading…
Cancel
Save