mirror of
https://github.com/fluxcd/flux2.git
synced 2026-02-08 00:37:27 +00:00
Compare commits
17 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca29bb1a41 | ||
|
|
c707c3ae7b | ||
|
|
53552c8816 | ||
|
|
fb8f2508d1 | ||
|
|
de92e95a50 | ||
|
|
b398208c7e | ||
|
|
8d0001f5b6 | ||
|
|
a2ff6c601e | ||
|
|
4accd37c1a | ||
|
|
742baa62d1 | ||
|
|
784a62c6a5 | ||
|
|
0bcccb2482 | ||
|
|
17dae751a2 | ||
|
|
93a87240b0 | ||
|
|
9c66b0d752 | ||
|
|
9fc6853024 | ||
|
|
22a8310b0a |
40 changed files with 898 additions and 84 deletions
2
.github/workflows/e2e-gcp.yaml
vendored
2
.github/workflows/e2e-gcp.yaml
vendored
|
|
@ -60,7 +60,7 @@ jobs:
|
|||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
- name: Log into us-central1-docker.pkg.dev
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: us-central1-docker.pkg.dev
|
||||
username: oauth2accesstoken
|
||||
|
|
|
|||
4
.github/workflows/ossf.yaml
vendored
4
.github/workflows/ossf.yaml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Run analysis
|
||||
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
|
|
@ -34,6 +34,6 @@ jobs:
|
|||
path: results.sarif
|
||||
retention-days: 5
|
||||
- name: Upload SARIF results
|
||||
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
||||
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
10
.github/workflows/release.yaml
vendored
10
.github/workflows/release.yaml
vendored
|
|
@ -40,13 +40,13 @@ jobs:
|
|||
- name: Setup Kustomize
|
||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||
|
|
@ -104,19 +104,21 @@ jobs:
|
|||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
||||
- name: Setup Flux CLI
|
||||
uses: ./action/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
VERSION=$(flux version --client | awk '{ print $NF }')
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||
|
|
|
|||
|
|
@ -88,22 +88,6 @@ brews:
|
|||
generate_completions_from_executable(bin/"flux", "completion")
|
||||
test: |
|
||||
system "#{bin}/flux --version"
|
||||
publishers:
|
||||
- name: aur-pkg-bin
|
||||
env:
|
||||
- AUR_BOT_SSH_PRIVATE_KEY={{ .Env.AUR_BOT_SSH_PRIVATE_KEY }}
|
||||
cmd: |
|
||||
.github/aur/flux-bin/publish.sh {{ .Version }}
|
||||
- name: aur-pkg-scm
|
||||
env:
|
||||
- AUR_BOT_SSH_PRIVATE_KEY={{ .Env.AUR_BOT_SSH_PRIVATE_KEY }}
|
||||
cmd: |
|
||||
.github/aur/flux-scm/publish.sh {{ .Version }}
|
||||
- name: aur-pkg-go
|
||||
env:
|
||||
- AUR_BOT_SSH_PRIVATE_KEY={{ .Env.AUR_BOT_SSH_PRIVATE_KEY }}
|
||||
cmd: |
|
||||
.github/aur/flux-go/publish.sh {{ .Version }}
|
||||
dockers:
|
||||
- image_templates:
|
||||
- 'fluxcd/flux-cli:{{ .Tag }}-amd64'
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func diffArtifactCmdRun(cmd *cobra.Command, args []string) error {
|
|||
|
||||
if diffArtifactArgs.provider.String() != sourcev1.GenericOCIProvider {
|
||||
logger.Actionf("logging in to registry with provider credentials")
|
||||
opt, err := loginWithProvider(ctx, url, diffArtifactArgs.provider.String())
|
||||
opt, _, err := loginWithProvider(ctx, url, diffArtifactArgs.provider.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login with provider: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ var listArtifactsCmd = &cobra.Command{
|
|||
Long: `The list command fetches the tags and their metadata from a remote OCI repository.
|
||||
The command can read the credentials from '~/.docker/config.json' but they can also be passed with --creds. It can also login to a supported provider with the --provider flag.`,
|
||||
Example: ` # List the artifacts stored in an OCI repository
|
||||
flux list artifact oci://ghcr.io/org/config/app
|
||||
flux list artifacts oci://ghcr.io/org/config/app
|
||||
`,
|
||||
RunE: listArtifactsCmdRun,
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ func listArtifactsCmdRun(cmd *cobra.Command, args []string) error {
|
|||
|
||||
if listArtifactArgs.provider.String() != sourcev1.GenericOCIProvider {
|
||||
logger.Actionf("logging in to registry with provider credentials")
|
||||
ociOpt, err := loginWithProvider(ctx, url, listArtifactArgs.provider.String())
|
||||
ociOpt, _, err := loginWithProvider(ctx, url, listArtifactArgs.provider.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login with provider: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,41 +18,189 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fluxcd/pkg/ssa"
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/spf13/cobra"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2"
|
||||
imageautov1 "github.com/fluxcd/image-automation-controller/api/v1"
|
||||
imageautov1b2 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1"
|
||||
imagev1b2 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||
notificationv1 "github.com/fluxcd/notification-controller/api/v1"
|
||||
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||
swv1b1 "github.com/fluxcd/source-watcher/api/v2/v1beta1"
|
||||
|
||||
"github.com/fluxcd/flux2/v2/internal/utils"
|
||||
)
|
||||
|
||||
// APIVersions holds the mapping of GroupKinds to their respective
|
||||
// latest API versions for a specific Flux version.
|
||||
type APIVersions struct {
|
||||
FluxVersion string
|
||||
LatestVersions map[schema.GroupKind]string
|
||||
}
|
||||
|
||||
// TODO: Update this mapping when new Flux minor versions are released!
|
||||
// latestAPIVersions contains the latest API versions for each GroupKind
|
||||
// for each supported Flux version. We maintain the latest two minor versions.
|
||||
var latestAPIVersions = []APIVersions{
|
||||
{
|
||||
FluxVersion: "2.7",
|
||||
LatestVersions: map[schema.GroupKind]string{
|
||||
// source-controller
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
||||
|
||||
// kustomize-controller
|
||||
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
||||
|
||||
// helm-controller
|
||||
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
||||
|
||||
// notification-controller
|
||||
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
||||
|
||||
// image-reflector-controller
|
||||
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImageRepositoryKind}: imagev1.GroupVersion.Version,
|
||||
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImagePolicyKind}: imagev1.GroupVersion.Version,
|
||||
|
||||
// image-automation-controller
|
||||
{Group: imageautov1.GroupVersion.Group, Kind: imageautov1.ImageUpdateAutomationKind}: imageautov1.GroupVersion.Version,
|
||||
|
||||
// source-watcher
|
||||
{Group: swv1b1.GroupVersion.Group, Kind: swv1b1.ArtifactGeneratorKind}: swv1b1.GroupVersion.Version,
|
||||
},
|
||||
},
|
||||
{
|
||||
FluxVersion: "2.6",
|
||||
LatestVersions: map[schema.GroupKind]string{
|
||||
// source-controller
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
||||
|
||||
// kustomize-controller
|
||||
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
||||
|
||||
// helm-controller
|
||||
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
||||
|
||||
// notification-controller
|
||||
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
||||
|
||||
// image-reflector-controller
|
||||
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImageRepositoryKind}: imagev1b2.GroupVersion.Version,
|
||||
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImagePolicyKind}: imagev1b2.GroupVersion.Version,
|
||||
|
||||
// image-automation-controller
|
||||
{Group: imageautov1b2.GroupVersion.Group, Kind: imageautov1b2.ImageUpdateAutomationKind}: imageautov1b2.GroupVersion.Version,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var migrateCmd = &cobra.Command{
|
||||
Use: "migrate",
|
||||
Args: cobra.NoArgs,
|
||||
Short: "Migrate the Flux custom resources to their latest API version",
|
||||
Long: `The migrate command must be run before a Flux minor version upgrade.
|
||||
The command migrates the Flux custom resources stored in Kubernetes etcd to their latest API version,
|
||||
ensuring the Flux components can continue to function correctly after the upgrade.
|
||||
|
||||
The command has two modes of operation:
|
||||
|
||||
- Cluster mode (default): migrates all the Flux custom resources stored in Kubernetes etcd to their latest API version.
|
||||
- File system mode (-f): migrates the Flux custom resources defined in the manifests located in the specified path.
|
||||
`,
|
||||
Example: ` # Migrate all the Flux custom resources in the cluster.
|
||||
# This uses the current kubeconfig context and requires cluster-admin permissions.
|
||||
flux migrate
|
||||
|
||||
# Migrate all the Flux custom resources in a Git repository
|
||||
# checked out in the current working directory.
|
||||
flux migrate -f .
|
||||
|
||||
# Migrate all Flux custom resources defined in YAML and Helm YAML template files.
|
||||
flux migrate -f . --extensions=.yml,.yaml,.tpl
|
||||
|
||||
# Migrate the Flux custom resources to the latest API versions of Flux 2.6.
|
||||
flux migrate -f . --version=2.6
|
||||
|
||||
# Migrate the Flux custom resources defined in a multi-document YAML manifest file.
|
||||
flux migrate -f path/to/manifest.yaml
|
||||
|
||||
# Simulate the migration without making any changes.
|
||||
flux migrate -f . --dry-run
|
||||
|
||||
# Run the migration skipping confirmation prompts.
|
||||
flux migrate -f . --yes
|
||||
`,
|
||||
RunE: runMigrateCmd,
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(migrateCmd)
|
||||
var migrateFlags struct {
|
||||
yes bool
|
||||
dryRun bool
|
||||
path string
|
||||
version string
|
||||
extensions []string
|
||||
}
|
||||
|
||||
func runMigrateCmd(cmd *cobra.Command, args []string) error {
|
||||
func init() {
|
||||
rootCmd.AddCommand(migrateCmd)
|
||||
|
||||
migrateCmd.Flags().StringVarP(&migrateFlags.path, "path", "f", "",
|
||||
"the path to the directory containing the manifests to migrate")
|
||||
migrateCmd.Flags().StringSliceVarP(&migrateFlags.extensions, "extensions", "e", []string{".yaml", ".yml"},
|
||||
"the file extensions to consider when migrating manifests, only applicable with --path")
|
||||
migrateCmd.Flags().StringVarP(&migrateFlags.version, "version", "v", "",
|
||||
"the target Flux minor version to migrate manifests to, only applicable with --path (defaults to the version of the CLI)")
|
||||
migrateCmd.Flags().BoolVarP(&migrateFlags.yes, "yes", "y", false,
|
||||
"skip confirmation prompts when migrating manifests, only applicable with --path")
|
||||
migrateCmd.Flags().BoolVar(&migrateFlags.dryRun, "dry-run", false,
|
||||
"simulate the migration of manifests without making any changes, only applicable with --path")
|
||||
}
|
||||
|
||||
func runMigrateCmd(*cobra.Command, []string) error {
|
||||
if migrateFlags.path == "" {
|
||||
return migrateCluster()
|
||||
}
|
||||
return migrateFileSystem()
|
||||
}
|
||||
|
||||
func migrateCluster() error {
|
||||
logger.Actionf("starting migration of custom resources")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
cfg, err := utils.KubeConfig(kubeconfigArgs, kubeclientOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Kubernetes client initialization failed: %s", err.Error())
|
||||
return fmt.Errorf("the Kubernetes client initialization failed: %w", err)
|
||||
}
|
||||
|
||||
kubeClient, err := client.New(cfg, client.Options{Scheme: utils.NewScheme()})
|
||||
|
|
@ -60,7 +208,7 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
migrator := NewMigrator(kubeClient, client.MatchingLabels{
|
||||
migrator := NewClusterMigrator(kubeClient, client.MatchingLabels{
|
||||
"app.kubernetes.io/part-of": "flux",
|
||||
})
|
||||
|
||||
|
|
@ -72,28 +220,64 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type Migrator struct {
|
||||
func migrateFileSystem() error {
|
||||
pathRoot, err := os.OpenRoot(".")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open filesystem at the current working directory: %w", err)
|
||||
}
|
||||
defer pathRoot.Close()
|
||||
|
||||
fileSystem := &osFS{pathRoot.FS()}
|
||||
yes := migrateFlags.yes
|
||||
dryRun := migrateFlags.dryRun
|
||||
path := migrateFlags.path
|
||||
extensions := migrateFlags.extensions
|
||||
var latestVersions map[schema.GroupKind]string
|
||||
|
||||
// Determine latest API versions based on the Flux version.
|
||||
if migrateFlags.version == "" {
|
||||
latestVersions = latestAPIVersions[0].LatestVersions
|
||||
} else {
|
||||
supportedVersions := make([]string, 0, len(latestAPIVersions))
|
||||
for _, v := range latestAPIVersions {
|
||||
if v.FluxVersion == migrateFlags.version {
|
||||
latestVersions = v.LatestVersions
|
||||
break
|
||||
}
|
||||
supportedVersions = append(supportedVersions, v.FluxVersion)
|
||||
}
|
||||
if latestVersions == nil {
|
||||
return fmt.Errorf("version %s is not supported, supported versions are: %s",
|
||||
migrateFlags.version, strings.Join(supportedVersions, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
return NewFileSystemMigrator(fileSystem, yes, dryRun, path, extensions, latestVersions).Run()
|
||||
}
|
||||
|
||||
// ClusterMigrator migrates all the CRs in the cluster for the CRDs matching the label selector.
|
||||
type ClusterMigrator struct {
|
||||
labelSelector client.MatchingLabels
|
||||
kubeClient client.Client
|
||||
}
|
||||
|
||||
// NewMigrator creates a new Migrator instance with the specified label selector.
|
||||
func NewMigrator(kubeClient client.Client, labelSelector client.MatchingLabels) *Migrator {
|
||||
return &Migrator{
|
||||
// NewClusterMigrator creates a new ClusterMigrator instance with the specified label selector.
|
||||
func NewClusterMigrator(kubeClient client.Client, labelSelector client.MatchingLabels) *ClusterMigrator {
|
||||
return &ClusterMigrator{
|
||||
labelSelector: labelSelector,
|
||||
kubeClient: kubeClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Migrator) Run(ctx context.Context) error {
|
||||
func (c *ClusterMigrator) Run(ctx context.Context) error {
|
||||
crdList := &apiextensionsv1.CustomResourceDefinitionList{}
|
||||
|
||||
if err := m.kubeClient.List(ctx, crdList, m.labelSelector); err != nil {
|
||||
if err := c.kubeClient.List(ctx, crdList, c.labelSelector); err != nil {
|
||||
return fmt.Errorf("failed to list CRDs: %w", err)
|
||||
}
|
||||
|
||||
for _, crd := range crdList.Items {
|
||||
if err := m.migrateCRD(ctx, crd.Name); err != nil {
|
||||
if err := c.migrateCRD(ctx, crd.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -101,22 +285,22 @@ func (m *Migrator) Run(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Migrator) migrateCRD(ctx context.Context, name string) error {
|
||||
func (c *ClusterMigrator) migrateCRD(ctx context.Context, name string) error {
|
||||
crd := &apiextensionsv1.CustomResourceDefinition{}
|
||||
|
||||
if err := m.kubeClient.Get(ctx, client.ObjectKey{Name: name}, crd); err != nil {
|
||||
if err := c.kubeClient.Get(ctx, client.ObjectKey{Name: name}, crd); err != nil {
|
||||
return fmt.Errorf("failed to get CRD %s: %w", name, err)
|
||||
}
|
||||
|
||||
// get the latest storage version for the CRD
|
||||
storageVersion := m.getStorageVersion(crd)
|
||||
storageVersion := c.getStorageVersion(crd)
|
||||
if storageVersion == "" {
|
||||
return fmt.Errorf("no storage version found for CRD %s", name)
|
||||
}
|
||||
|
||||
// migrate all the resources for the CRD
|
||||
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
return m.migrateCR(ctx, crd, storageVersion)
|
||||
return c.migrateCR(ctx, crd, storageVersion)
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to migrate resources for CRD %s: %w", name, err)
|
||||
|
|
@ -125,7 +309,7 @@ func (m *Migrator) migrateCRD(ctx context.Context, name string) error {
|
|||
// set the CRD status to contain only the latest storage version
|
||||
if len(crd.Status.StoredVersions) > 1 || crd.Status.StoredVersions[0] != storageVersion {
|
||||
crd.Status.StoredVersions = []string{storageVersion}
|
||||
if err := m.kubeClient.Status().Update(ctx, crd); err != nil {
|
||||
if err := c.kubeClient.Status().Update(ctx, crd); err != nil {
|
||||
return fmt.Errorf("failed to update CRD %s status: %w", crd.Name, err)
|
||||
}
|
||||
logger.Successf("%s migrated to storage version %s", crd.Name, storageVersion)
|
||||
|
|
@ -133,8 +317,8 @@ func (m *Migrator) migrateCRD(ctx context.Context, name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// migrateCR migrates all CRs for the given CRD to the specified version by patching them with an empty patch.
|
||||
func (m *Migrator) migrateCR(ctx context.Context, crd *apiextensionsv1.CustomResourceDefinition, version string) error {
|
||||
// migrateCR migrates all CRs for the given CRD to the specified version by patching them.
|
||||
func (c *ClusterMigrator) migrateCR(ctx context.Context, crd *apiextensionsv1.CustomResourceDefinition, version string) error {
|
||||
list := &unstructured.UnstructuredList{}
|
||||
|
||||
apiVersion := crd.Spec.Group + "/" + version
|
||||
|
|
@ -143,7 +327,7 @@ func (m *Migrator) migrateCR(ctx context.Context, crd *apiextensionsv1.CustomRes
|
|||
list.SetAPIVersion(apiVersion)
|
||||
list.SetKind(listKind)
|
||||
|
||||
err := m.kubeClient.List(ctx, list, client.InNamespace(""))
|
||||
err := c.kubeClient.List(ctx, list, client.InNamespace(""))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list resources for CRD %s: %w", crd.Name, err)
|
||||
}
|
||||
|
|
@ -153,16 +337,39 @@ func (m *Migrator) migrateCR(ctx context.Context, crd *apiextensionsv1.CustomRes
|
|||
}
|
||||
|
||||
for _, item := range list.Items {
|
||||
// patch the resource with an empty patch to update the version
|
||||
if err := m.kubeClient.Patch(
|
||||
ctx,
|
||||
&item,
|
||||
client.RawPatch(client.Merge.Type(), []byte("{}")),
|
||||
); err != nil && !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf(" %s/%s/%s failed to migrate: %w",
|
||||
patches, err := ssa.PatchMigrateToVersion(&item, apiVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create migration patch for %s/%s/%s: %w",
|
||||
item.GetKind(), item.GetNamespace(), item.GetName(), err)
|
||||
}
|
||||
|
||||
if len(patches) == 0 {
|
||||
// patch the resource with an empty patch to update the version
|
||||
if err := c.kubeClient.Patch(
|
||||
ctx,
|
||||
&item,
|
||||
client.RawPatch(client.Merge.Type(), []byte("{}")),
|
||||
); err != nil && !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf(" %s/%s/%s failed to migrate: %w",
|
||||
item.GetKind(), item.GetNamespace(), item.GetName(), err)
|
||||
}
|
||||
} else {
|
||||
// patch the resource to migrate the managed fields to the latest apiVersion
|
||||
rawPatch, err := json.Marshal(patches)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal migration patch for %s/%s/%s: %w",
|
||||
item.GetKind(), item.GetNamespace(), item.GetName(), err)
|
||||
}
|
||||
if err := c.kubeClient.Patch(
|
||||
ctx,
|
||||
&item,
|
||||
client.RawPatch(types.JSONPatchType, rawPatch),
|
||||
); err != nil && !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf(" %s/%s/%s failed to migrate managed fields: %w",
|
||||
item.GetKind(), item.GetNamespace(), item.GetName(), err)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Successf("%s/%s/%s migrated to version %s",
|
||||
item.GetKind(), item.GetNamespace(), item.GetName(), version)
|
||||
}
|
||||
|
|
@ -171,7 +378,7 @@ func (m *Migrator) migrateCR(ctx context.Context, crd *apiextensionsv1.CustomRes
|
|||
}
|
||||
|
||||
// getStorageVersion retrieves the storage version of a CustomResourceDefinition.
|
||||
func (m *Migrator) getStorageVersion(crd *apiextensionsv1.CustomResourceDefinition) string {
|
||||
func (c *ClusterMigrator) getStorageVersion(crd *apiextensionsv1.CustomResourceDefinition) string {
|
||||
var version string
|
||||
for _, v := range crd.Spec.Versions {
|
||||
if v.Storage {
|
||||
|
|
@ -182,3 +389,303 @@ func (m *Migrator) getStorageVersion(crd *apiextensionsv1.CustomResourceDefiniti
|
|||
|
||||
return version
|
||||
}
|
||||
|
||||
// WritableFS extends fs.FS with a WriteFile method.
|
||||
type WritableFS interface {
|
||||
fs.FS
|
||||
WriteFile(name string, data []byte, perm os.FileMode) error
|
||||
}
|
||||
|
||||
// osFS is a WritableFS implementation that uses the file system of the OS.
|
||||
type osFS struct {
|
||||
fs.FS
|
||||
}
|
||||
|
||||
func (o *osFS) WriteFile(name string, data []byte, perm os.FileMode) error {
|
||||
return os.WriteFile(name, data, perm)
|
||||
}
|
||||
|
||||
// FileSystemMigrator migrates all the CRs found in the manifests located in the specified path.
|
||||
type FileSystemMigrator struct {
|
||||
fileSystem WritableFS
|
||||
yes bool
|
||||
dryRun bool
|
||||
path string
|
||||
extensions []string
|
||||
latestVersions map[schema.GroupKind]string
|
||||
}
|
||||
|
||||
// FileAPIUpgrades represents the API upgrades detected in a specific manifest file.
|
||||
type FileAPIUpgrades struct {
|
||||
File string
|
||||
Upgrades []APIUpgrade
|
||||
}
|
||||
|
||||
// APIUpgrade represents an upgrade of a specific API version in a manifest file.
|
||||
type APIUpgrade struct {
|
||||
Line int
|
||||
Kind string
|
||||
OldVersion string
|
||||
NewVersion string
|
||||
}
|
||||
|
||||
// NewFileSystemMigrator creates a new FileSystemMigrator instance with the specified flags.
|
||||
func NewFileSystemMigrator(fileSystem WritableFS, yes, dryRun bool, path string,
|
||||
extensions []string, latestVersions map[schema.GroupKind]string) *FileSystemMigrator {
|
||||
return &FileSystemMigrator{
|
||||
fileSystem: fileSystem,
|
||||
yes: yes,
|
||||
dryRun: dryRun,
|
||||
path: filepath.Clean(path), // convert dir/ to dir to avoid error when walking
|
||||
extensions: extensions,
|
||||
latestVersions: latestVersions,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) Run() error {
|
||||
logger.Actionf("starting migration of custom resources")
|
||||
|
||||
// List and filter files.
|
||||
files, err := f.listFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Detect upgrades.
|
||||
upgrades, err := f.detectUpgrades(files)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(upgrades) == 0 {
|
||||
logger.Successf("no custom resources found that require migration")
|
||||
return nil
|
||||
}
|
||||
if f.dryRun {
|
||||
logger.Successf("dry-run mode enabled, no changes will be made")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Confirm upgrades.
|
||||
if !f.yes {
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Are you sure you want to proceed with the above upgrades", // Already prints "? [y/N]"
|
||||
IsConfirm: true,
|
||||
}
|
||||
if _, err := prompt.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate files.
|
||||
for _, fileUpgrades := range upgrades {
|
||||
if err := f.migrateFile(&fileUpgrades); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("file %s migrated successfully", fileUpgrades.File)
|
||||
}
|
||||
|
||||
logger.Successf("custom resources migrated successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) listFiles() ([]string, error) {
|
||||
fileInfo, err := fs.Stat(f.fileSystem, f.path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to stat path %s: %w", f.path, err)
|
||||
}
|
||||
if fileInfo.IsDir() {
|
||||
return f.listDirectoryFiles()
|
||||
}
|
||||
if err := f.validateSingleFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []string{f.path}, nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) listDirectoryFiles() ([]string, error) {
|
||||
var files []string
|
||||
err := fs.WalkDir(f.fileSystem, f.path, func(path string, dirEntry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !f.matchesExtensions(path) {
|
||||
return nil
|
||||
}
|
||||
fileInfo, err := dirEntry.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fileInfo.Mode().IsRegular() {
|
||||
files = append(files, path)
|
||||
} else if !fileInfo.IsDir() {
|
||||
logger.Warningf("skipping irregular file %s", path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to walk directory %s: %w", f.path, err)
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) validateSingleFile() error {
|
||||
if !f.matchesExtensions(f.path) {
|
||||
return fmt.Errorf("file %s does not match the specified extensions: %v",
|
||||
f.path, strings.Join(f.extensions, ", "))
|
||||
}
|
||||
|
||||
// Check if it's irregular by walking the parent directory.
|
||||
var irregular bool
|
||||
err := fs.WalkDir(f.fileSystem, filepath.Dir(f.path), func(path string, dirEntry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if path != f.path {
|
||||
return nil
|
||||
}
|
||||
fileInfo, err := dirEntry.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !fileInfo.Mode().IsRegular() {
|
||||
irregular = true
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to validate file %s: %w", f.path, err)
|
||||
}
|
||||
if irregular {
|
||||
return fmt.Errorf("file %s is irregular", f.path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) matchesExtensions(file string) bool {
|
||||
for _, ext := range f.extensions {
|
||||
if strings.HasSuffix(file, ext) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) detectUpgrades(files []string) ([]FileAPIUpgrades, error) {
|
||||
var upgrades []FileAPIUpgrades
|
||||
for _, file := range files {
|
||||
fileUpgrades, err := f.detectFileUpgrades(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(fileUpgrades) == 0 {
|
||||
continue
|
||||
}
|
||||
fu := FileAPIUpgrades{
|
||||
File: file,
|
||||
Upgrades: fileUpgrades,
|
||||
}
|
||||
upgrades = append(upgrades, fu)
|
||||
f.printDetectedUpgrades(&fu)
|
||||
}
|
||||
return upgrades, nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) detectFileUpgrades(file string) ([]APIUpgrade, error) {
|
||||
b, err := fs.ReadFile(f.fileSystem, file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file %s: %w", file, err)
|
||||
}
|
||||
lines := strings.Split(string(b), "\n")
|
||||
|
||||
var fileUpgrades []APIUpgrade
|
||||
for line, apiVersionLine := range lines {
|
||||
// Parse apiVersion.
|
||||
const apiVersionPrefix = "apiVersion: "
|
||||
idx := strings.Index(apiVersionLine, apiVersionPrefix)
|
||||
if idx == -1 {
|
||||
continue
|
||||
}
|
||||
apiVersionValuePrefix := strings.TrimSpace(apiVersionLine[idx+len(apiVersionPrefix):])
|
||||
apiVersion := strings.Split(apiVersionValuePrefix, " ")[0]
|
||||
gv, err := schema.ParseGroupVersion(apiVersion)
|
||||
if err != nil {
|
||||
logger.Warningf("%s:%d: %v", file, line+1, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse kind.
|
||||
if line+1 >= len(lines) {
|
||||
continue
|
||||
}
|
||||
kindLine := lines[line+1]
|
||||
const kindPrefix = "kind: "
|
||||
idx = strings.Index(kindLine, kindPrefix)
|
||||
if idx == -1 {
|
||||
continue
|
||||
}
|
||||
kindValuePrefix := strings.TrimSpace(kindLine[idx+len(kindPrefix):])
|
||||
kind := strings.Split(kindValuePrefix, " ")[0]
|
||||
|
||||
// Build GroupKind.
|
||||
gk := schema.GroupKind{
|
||||
Group: gv.Group,
|
||||
Kind: kind,
|
||||
}
|
||||
|
||||
// Check if there's a newer version for the GroupKind.
|
||||
latestVersion, ok := f.latestVersions[gk]
|
||||
if !ok || latestVersion == gv.Version {
|
||||
continue
|
||||
}
|
||||
|
||||
// Record the upgrade.
|
||||
fileUpgrades = append(fileUpgrades, APIUpgrade{
|
||||
Line: line,
|
||||
Kind: kind,
|
||||
OldVersion: gv.Version,
|
||||
NewVersion: latestVersion,
|
||||
})
|
||||
}
|
||||
return fileUpgrades, nil
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) printDetectedUpgrades(fileUpgrades *FileAPIUpgrades) {
|
||||
for _, upgrade := range fileUpgrades.Upgrades {
|
||||
logger.Generatef("%s:%d: %s %s -> %s",
|
||||
fileUpgrades.File,
|
||||
upgrade.Line+1,
|
||||
upgrade.Kind,
|
||||
upgrade.OldVersion,
|
||||
upgrade.NewVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FileSystemMigrator) migrateFile(fileUpgrades *FileAPIUpgrades) error {
|
||||
// Read file and map lines.
|
||||
b, err := fs.ReadFile(f.fileSystem, fileUpgrades.File)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read file %s: %w", fileUpgrades.File, err)
|
||||
}
|
||||
lines := strings.Split(string(b), "\n")
|
||||
|
||||
// Apply upgrades to lines.
|
||||
for _, upgrade := range fileUpgrades.Upgrades {
|
||||
line := lines[upgrade.Line]
|
||||
line = strings.Replace(line, upgrade.OldVersion, upgrade.NewVersion, 1)
|
||||
lines[upgrade.Line] = line
|
||||
}
|
||||
|
||||
// Read file info to preserve permissions.
|
||||
fileInfo, err := fs.Stat(f.fileSystem, fileUpgrades.File)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat file %s: %w", fileUpgrades.File, err)
|
||||
}
|
||||
|
||||
// Write file with preserved permissions.
|
||||
b = []byte(strings.Join(lines, "\n"))
|
||||
if err := f.fileSystem.WriteFile(fileUpgrades.File, b, fileInfo.Mode()); err != nil {
|
||||
return fmt.Errorf("failed to write file %s: %w", fileUpgrades.File, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
161
cmd/flux/migrate_test.go
Normal file
161
cmd/flux/migrate_test.go
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
Copyright 2025 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 (
|
||||
"bytes"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type writeToMemoryFS struct {
|
||||
fs.FS
|
||||
|
||||
writtenFiles map[string][]byte
|
||||
}
|
||||
|
||||
func (m *writeToMemoryFS) WriteFile(name string, data []byte, perm os.FileMode) error {
|
||||
m.writtenFiles[name] = data
|
||||
return nil
|
||||
}
|
||||
|
||||
type writtenFile struct {
|
||||
file string
|
||||
goldenFile string
|
||||
}
|
||||
|
||||
func TestFileSystemMigrator(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
path string
|
||||
outputGolden string
|
||||
writtenFiles []writtenFile
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "errors out for single file that is a symlink",
|
||||
path: "testdata/migrate/file-system/single-file-link.yaml",
|
||||
err: "file testdata/migrate/file-system/single-file-link.yaml is irregular",
|
||||
},
|
||||
{
|
||||
name: "errors out for single file with wrong extension",
|
||||
path: "testdata/migrate/file-system/single-file-wrong-ext.json",
|
||||
err: "file testdata/migrate/file-system/single-file-wrong-ext.json does not match the specified extensions: .yaml, .yml",
|
||||
},
|
||||
{
|
||||
name: "migrate single file",
|
||||
path: "testdata/migrate/file-system/single-file.yaml",
|
||||
outputGolden: "testdata/migrate/file-system/single-file.yaml.output.golden",
|
||||
writtenFiles: []writtenFile{
|
||||
{
|
||||
file: "testdata/migrate/file-system/single-file.yaml",
|
||||
goldenFile: "testdata/migrate/file-system/single-file.yaml.golden",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "migrate files in directory",
|
||||
path: "testdata/migrate/file-system/dir",
|
||||
outputGolden: "testdata/migrate/file-system/dir.output.golden",
|
||||
writtenFiles: []writtenFile{
|
||||
{
|
||||
file: "testdata/migrate/file-system/dir/some-dir/another-file.yaml",
|
||||
goldenFile: "testdata/migrate/file-system/dir.golden/some-dir/another-file.yaml",
|
||||
},
|
||||
{
|
||||
file: "testdata/migrate/file-system/dir/some-dir/another-file.yml",
|
||||
goldenFile: "testdata/migrate/file-system/dir.golden/some-dir/another-file.yml",
|
||||
},
|
||||
{
|
||||
file: "testdata/migrate/file-system/dir/some-file.yaml",
|
||||
goldenFile: "testdata/migrate/file-system/dir.golden/some-file.yaml",
|
||||
},
|
||||
{
|
||||
file: "testdata/migrate/file-system/dir/some-file.yml",
|
||||
goldenFile: "testdata/migrate/file-system/dir.golden/some-file.yml",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
// Store logger, replace with test logger, and restore at the end of the test.
|
||||
var testLogger bytes.Buffer
|
||||
oldLogger := logger
|
||||
logger = stderrLogger{&testLogger}
|
||||
t.Cleanup(func() { logger = oldLogger })
|
||||
|
||||
// Open current working directory as root and build write-to-memory filesystem.
|
||||
pathRoot, err := os.OpenRoot(".")
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
t.Cleanup(func() { pathRoot.Close() })
|
||||
fileSystem := &writeToMemoryFS{
|
||||
FS: pathRoot.FS(),
|
||||
writtenFiles: make(map[string][]byte),
|
||||
}
|
||||
|
||||
// Prepare other inputs.
|
||||
const yes = true
|
||||
const dryRun = false
|
||||
extensions := []string{".yaml", ".yml"}
|
||||
latestVersions := map[schema.GroupKind]string{
|
||||
{Group: "image.toolkit.fluxcd.io", Kind: "ImageRepository"}: "v1",
|
||||
{Group: "image.toolkit.fluxcd.io", Kind: "ImagePolicy"}: "v1",
|
||||
{Group: "image.toolkit.fluxcd.io", Kind: "ImageUpdateAutomation"}: "v1",
|
||||
}
|
||||
|
||||
// Run migration.
|
||||
err = NewFileSystemMigrator(fileSystem, yes, dryRun, tt.path, extensions, latestVersions).Run()
|
||||
if tt.err != "" {
|
||||
g.Expect(err).To(HaveOccurred())
|
||||
g.Expect(err.Error()).To(Equal(tt.err))
|
||||
return
|
||||
}
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
// Assert logger output.
|
||||
b, err := os.ReadFile(tt.outputGolden)
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
g.Expect(string(b)).To(Equal(testLogger.String()),
|
||||
"logger output does not match golden file %s", tt.outputGolden)
|
||||
|
||||
// Assert which files were written.
|
||||
writtenFiles := make([]string, 0, len(fileSystem.writtenFiles))
|
||||
for name := range fileSystem.writtenFiles {
|
||||
writtenFiles = append(writtenFiles, name)
|
||||
}
|
||||
expectedWrittenFiles := make([]string, 0, len(tt.writtenFiles))
|
||||
for _, wf := range tt.writtenFiles {
|
||||
expectedWrittenFiles = append(expectedWrittenFiles, wf.file)
|
||||
}
|
||||
g.Expect(writtenFiles).To(ConsistOf(expectedWrittenFiles))
|
||||
|
||||
// Assert contents of written files.
|
||||
for _, wf := range tt.writtenFiles {
|
||||
b, err := os.ReadFile(wf.goldenFile)
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
g.Expect(string(fileSystem.writtenFiles[wf.file])).To(Equal(string(b)),
|
||||
"file %s does not match golden file %s", wf.file, wf.goldenFile)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/crane"
|
||||
|
||||
"github.com/fluxcd/pkg/auth"
|
||||
|
|
@ -28,14 +29,14 @@ import (
|
|||
)
|
||||
|
||||
// loginWithProvider gets a crane authentication option for the given provider and URL.
|
||||
func loginWithProvider(ctx context.Context, url, provider string) (crane.Option, error) {
|
||||
func loginWithProvider(ctx context.Context, url, provider string) (crane.Option, authn.Authenticator, error) {
|
||||
var opts []auth.Option
|
||||
if provider == azure.ProviderName {
|
||||
opts = append(opts, auth.WithAllowShellOut())
|
||||
}
|
||||
authenticator, err := authutils.GetArtifactRegistryCredentials(ctx, provider, url, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not login to provider %s with url %s: %w", provider, url, err)
|
||||
return nil, nil, fmt.Errorf("could not login to provider %s with url %s: %w", provider, url, err)
|
||||
}
|
||||
return crane.WithAuth(authenticator), nil
|
||||
return crane.WithAuth(authenticator), authenticator, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func pullArtifactCmdRun(cmd *cobra.Command, args []string) error {
|
|||
|
||||
if pullArtifactArgs.provider.String() != sourcev1.GenericOCIProvider {
|
||||
logger.Actionf("logging in to registry with provider credentials")
|
||||
opt, err := loginWithProvider(ctx, url, pullArtifactArgs.provider.String())
|
||||
opt, _, err := loginWithProvider(ctx, url, pullArtifactArgs.provider.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login with provider: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,11 +225,12 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error {
|
|||
|
||||
if provider := pushArtifactArgs.provider.String(); provider != sourcev1.GenericOCIProvider {
|
||||
logger.Actionf("logging in to registry with provider credentials")
|
||||
authOpt, err := loginWithProvider(ctx, url, provider)
|
||||
var opt crane.Option
|
||||
opt, authenticator, err = loginWithProvider(ctx, url, provider)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login with provider: %w", err)
|
||||
}
|
||||
opts = append(opts, authOpt)
|
||||
opts = append(opts, opt)
|
||||
}
|
||||
|
||||
if rootArgs.timeout != 0 {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ func tagArtifactCmdRun(cmd *cobra.Command, args []string) error {
|
|||
|
||||
if tagArtifactArgs.provider.String() != sourcev1.GenericOCIProvider {
|
||||
logger.Actionf("logging in to registry with provider credentials")
|
||||
opt, err := loginWithProvider(ctx, url, tagArtifactArgs.provider.String())
|
||||
opt, _, err := loginWithProvider(ctx, url, tagArtifactArgs.provider.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login with provider: %w", err)
|
||||
}
|
||||
|
|
|
|||
0
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file
vendored
Normal file
0
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file
vendored
Normal file
1
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file-link.yaml
vendored
Symbolic link
1
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file-link.yaml
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
./another-file.yaml
|
||||
5
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file.yaml
vendored
Normal file
5
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file.yaml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageUpdateAutomation
|
||||
---
|
||||
|
||||
6
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file.yml
vendored
Normal file
6
cmd/flux/testdata/migrate/file-system/dir.golden/some-dir/another-file.yml
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# This file has Windows line endings.
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageUpdateAutomation
|
||||
---
|
||||
|
||||
0
cmd/flux/testdata/migrate/file-system/dir.golden/some-file
vendored
Normal file
0
cmd/flux/testdata/migrate/file-system/dir.golden/some-file
vendored
Normal file
1
cmd/flux/testdata/migrate/file-system/dir.golden/some-file-link.yaml
vendored
Symbolic link
1
cmd/flux/testdata/migrate/file-system/dir.golden/some-file-link.yaml
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
some-file.yaml
|
||||
22
cmd/flux/testdata/migrate/file-system/dir.golden/some-file.yaml
vendored
Normal file
22
cmd/flux/testdata/migrate/file-system/dir.golden/some-file.yaml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImagePolicy
|
||||
|
||||
---
|
||||
spec:
|
||||
wait: true
|
||||
dependsOn:
|
||||
- apiVersion: image.toolkit.fluxcd.io/v1 # update this from v1beta1
|
||||
kind: ImageRepository # there can be comments here too
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
17
cmd/flux/testdata/migrate/file-system/dir.golden/some-file.yml
vendored
Normal file
17
cmd/flux/testdata/migrate/file-system/dir.golden/some-file.yml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# This file has Windows line endings.
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImagePolicy
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
17
cmd/flux/testdata/migrate/file-system/dir.output.golden
vendored
Normal file
17
cmd/flux/testdata/migrate/file-system/dir.output.golden
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
â–ş starting migration of custom resources
|
||||
⚠️ skipping irregular file testdata/migrate/file-system/dir/some-dir/another-file-link.yaml
|
||||
⚠️ skipping irregular file testdata/migrate/file-system/dir/some-file-link.yaml
|
||||
âśš testdata/migrate/file-system/dir/some-dir/another-file.yaml:2: ImageUpdateAutomation v1beta2 -> v1
|
||||
âśš testdata/migrate/file-system/dir/some-dir/another-file.yml:3: ImageUpdateAutomation v1beta2 -> v1
|
||||
⚠️ testdata/migrate/file-system/dir/some-file.yaml:20: unexpected GroupVersion string: image.toolkit.fluxcd.io/v1/v2
|
||||
âśš testdata/migrate/file-system/dir/some-file.yaml:1: ImageRepository v1beta1 -> v1
|
||||
âśš testdata/migrate/file-system/dir/some-file.yaml:7: ImagePolicy v1beta2 -> v1
|
||||
âśš testdata/migrate/file-system/dir/some-file.yaml:14: ImageRepository v1beta1 -> v1
|
||||
⚠️ testdata/migrate/file-system/dir/some-file.yml:15: unexpected GroupVersion string: image.toolkit.fluxcd.io/v1/v2
|
||||
âśš testdata/migrate/file-system/dir/some-file.yml:3: ImageRepository v1beta2 -> v1
|
||||
âśš testdata/migrate/file-system/dir/some-file.yml:9: ImagePolicy v1beta1 -> v1
|
||||
âś” file testdata/migrate/file-system/dir/some-dir/another-file.yaml migrated successfully
|
||||
âś” file testdata/migrate/file-system/dir/some-dir/another-file.yml migrated successfully
|
||||
âś” file testdata/migrate/file-system/dir/some-file.yaml migrated successfully
|
||||
âś” file testdata/migrate/file-system/dir/some-file.yml migrated successfully
|
||||
âś” custom resources migrated successfully
|
||||
0
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file
vendored
Normal file
0
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file
vendored
Normal file
1
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file-link.yaml
vendored
Symbolic link
1
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file-link.yaml
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
./another-file.yaml
|
||||
5
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file.yaml
vendored
Normal file
5
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file.yaml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageUpdateAutomation
|
||||
---
|
||||
|
||||
6
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file.yml
vendored
Normal file
6
cmd/flux/testdata/migrate/file-system/dir/some-dir/another-file.yml
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# This file has Windows line endings.
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageUpdateAutomation
|
||||
---
|
||||
|
||||
0
cmd/flux/testdata/migrate/file-system/dir/some-file
vendored
Normal file
0
cmd/flux/testdata/migrate/file-system/dir/some-file
vendored
Normal file
1
cmd/flux/testdata/migrate/file-system/dir/some-file-link.yaml
vendored
Symbolic link
1
cmd/flux/testdata/migrate/file-system/dir/some-file-link.yaml
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
some-file.yaml
|
||||
22
cmd/flux/testdata/migrate/file-system/dir/some-file.yaml
vendored
Normal file
22
cmd/flux/testdata/migrate/file-system/dir/some-file.yaml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
|
||||
---
|
||||
spec:
|
||||
wait: true
|
||||
dependsOn:
|
||||
- apiVersion: image.toolkit.fluxcd.io/v1beta1 # update this from v1beta1
|
||||
kind: ImageRepository # there can be comments here too
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
17
cmd/flux/testdata/migrate/file-system/dir/some-file.yml
vendored
Normal file
17
cmd/flux/testdata/migrate/file-system/dir/some-file.yml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# This file has Windows line endings.
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
||||
kind: ImagePolicy
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
1
cmd/flux/testdata/migrate/file-system/single-file-link.yaml
vendored
Symbolic link
1
cmd/flux/testdata/migrate/file-system/single-file-link.yaml
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
./single-file.yaml
|
||||
0
cmd/flux/testdata/migrate/file-system/single-file-wrong-ext.json
vendored
Normal file
0
cmd/flux/testdata/migrate/file-system/single-file-wrong-ext.json
vendored
Normal file
15
cmd/flux/testdata/migrate/file-system/single-file.yaml
vendored
Normal file
15
cmd/flux/testdata/migrate/file-system/single-file.yaml
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||
kind: ImagePolicy
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
15
cmd/flux/testdata/migrate/file-system/single-file.yaml.golden
vendored
Normal file
15
cmd/flux/testdata/migrate/file-system/single-file.yaml.golden
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImageRepository
|
||||
---
|
||||
|
||||
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1
|
||||
kind: ImagePolicy
|
||||
|
||||
|
||||
---
|
||||
|
||||
apiVersion: image.toolkit.fluxcd.io/v1/v2
|
||||
kind: ImagePolicy
|
||||
|
||||
6
cmd/flux/testdata/migrate/file-system/single-file.yaml.output.golden
vendored
Normal file
6
cmd/flux/testdata/migrate/file-system/single-file.yaml.output.golden
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
â–ş starting migration of custom resources
|
||||
⚠️ testdata/migrate/file-system/single-file.yaml:13: unexpected GroupVersion string: image.toolkit.fluxcd.io/v1/v2
|
||||
âśš testdata/migrate/file-system/single-file.yaml:1: ImageRepository v1beta1 -> v1
|
||||
âśš testdata/migrate/file-system/single-file.yaml:7: ImagePolicy v1beta2 -> v1
|
||||
âś” file testdata/migrate/file-system/single-file.yaml migrated successfully
|
||||
âś” custom resources migrated successfully
|
||||
8
go.mod
8
go.mod
|
|
@ -12,11 +12,11 @@ require (
|
|||
github.com/distribution/distribution/v3 v3.0.0
|
||||
github.com/fluxcd/cli-utils v0.36.0-flux.15
|
||||
github.com/fluxcd/go-git-providers v0.24.0
|
||||
github.com/fluxcd/helm-controller/api v1.4.0
|
||||
github.com/fluxcd/helm-controller/api v1.4.1
|
||||
github.com/fluxcd/image-automation-controller/api v1.0.1
|
||||
github.com/fluxcd/image-reflector-controller/api v1.0.1
|
||||
github.com/fluxcd/kustomize-controller/api v1.7.0
|
||||
github.com/fluxcd/notification-controller/api v1.7.1
|
||||
github.com/fluxcd/notification-controller/api v1.7.2
|
||||
github.com/fluxcd/pkg/apis/event v0.19.0
|
||||
github.com/fluxcd/pkg/apis/meta v1.21.0
|
||||
github.com/fluxcd/pkg/auth v0.31.0
|
||||
|
|
@ -28,11 +28,11 @@ require (
|
|||
github.com/fluxcd/pkg/oci v0.56.0
|
||||
github.com/fluxcd/pkg/runtime v0.86.0
|
||||
github.com/fluxcd/pkg/sourceignore v0.14.0
|
||||
github.com/fluxcd/pkg/ssa v0.58.0
|
||||
github.com/fluxcd/pkg/ssa v0.59.0
|
||||
github.com/fluxcd/pkg/ssh v0.21.0
|
||||
github.com/fluxcd/pkg/tar v0.14.0
|
||||
github.com/fluxcd/pkg/version v0.10.0
|
||||
github.com/fluxcd/source-controller/api v1.7.0
|
||||
github.com/fluxcd/source-controller/api v1.7.1
|
||||
github.com/fluxcd/source-watcher/api/v2 v2.0.1
|
||||
github.com/go-git/go-git/v5 v5.16.2
|
||||
github.com/go-logr/logr v1.4.3
|
||||
|
|
|
|||
16
go.sum
16
go.sum
|
|
@ -174,16 +174,16 @@ github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg=
|
|||
github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo=
|
||||
github.com/fluxcd/go-git-providers v0.24.0 h1:g+96IxOG1g0kf/DOFUFMkz1MtKvG5aeqmkIqmRBY1qU=
|
||||
github.com/fluxcd/go-git-providers v0.24.0/go.mod h1:RH1ei52TOdIb/GgPd22tr7kIuPD/xc8XTy5sKpV9xM8=
|
||||
github.com/fluxcd/helm-controller/api v1.4.0 h1:SIU/H+pKdaxF+hT3+0ZreoCw7rfBW5wsS2HCNt0pThw=
|
||||
github.com/fluxcd/helm-controller/api v1.4.0/go.mod h1:qmt+v3nIjxjmToxW3Q7Tye5aCLt3oS1YLqAAMjV2MyY=
|
||||
github.com/fluxcd/helm-controller/api v1.4.1 h1:+MhLCCd7MFtGsycyGI1VS9Dc5ymHQRe/wgPwkSltV9E=
|
||||
github.com/fluxcd/helm-controller/api v1.4.1/go.mod h1:qmt+v3nIjxjmToxW3Q7Tye5aCLt3oS1YLqAAMjV2MyY=
|
||||
github.com/fluxcd/image-automation-controller/api v1.0.1 h1:clmZZqbnfbpClEfyFlgDYK7hrmVZfFPrXwIaaXaI/UQ=
|
||||
github.com/fluxcd/image-automation-controller/api v1.0.1/go.mod h1:hI4BA09jtuIg3oQqCQsO3NIeWe5RbZ0+T9TjvVQbdH8=
|
||||
github.com/fluxcd/image-reflector-controller/api v1.0.1 h1:ZEUOZYdxt2vyrcTc911K0i7PZJtgm1otTfUrZk6cgPw=
|
||||
github.com/fluxcd/image-reflector-controller/api v1.0.1/go.mod h1:J562aKopNq0H2m0Hnz2M9kOwwyLjjwPwJgNBiIlNHQo=
|
||||
github.com/fluxcd/kustomize-controller/api v1.7.0 h1:5AO+pNY24qdJxxmtKNauplalII2HwED936pOMIDqNOA=
|
||||
github.com/fluxcd/kustomize-controller/api v1.7.0/go.mod h1:VuW1e7ILa6QVUnZ0Cxg+9Ghf12LvXu336vE2rAlHg4Y=
|
||||
github.com/fluxcd/notification-controller/api v1.7.1 h1:lSdKJQ8afnXJ/+EnJAe371R27BM4Vqhc63xq2wsHfpc=
|
||||
github.com/fluxcd/notification-controller/api v1.7.1/go.mod h1:00RNyw4r9KnUgpM9pFdJZ8vv/Er7b+xxeZI6tYltY3E=
|
||||
github.com/fluxcd/notification-controller/api v1.7.2 h1:Gt/KRuXw0LMQx/i3B4zPthWDMbNP1U+/8BHDoCt5k0k=
|
||||
github.com/fluxcd/notification-controller/api v1.7.2/go.mod h1:00RNyw4r9KnUgpM9pFdJZ8vv/Er7b+xxeZI6tYltY3E=
|
||||
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
|
||||
github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
|
||||
github.com/fluxcd/pkg/apis/event v0.19.0 h1:ZJU2voontkzp5rNYA4JMOu40S4tRcrWi4Do59EnyFwg=
|
||||
|
|
@ -214,16 +214,16 @@ github.com/fluxcd/pkg/runtime v0.86.0 h1:q7aBSerJwt0N9hpurPVElG+HWpVhZcs6t96bcNQ
|
|||
github.com/fluxcd/pkg/runtime v0.86.0/go.mod h1:Wt9mUzQgMPQMu2D/wKl5pG4zh5vu/tfF5wq9pPobxOQ=
|
||||
github.com/fluxcd/pkg/sourceignore v0.14.0 h1:ZiZzbXtXb/Qp7I7JCStsxOlX8ri8rWwCvmvIrJ0UzQQ=
|
||||
github.com/fluxcd/pkg/sourceignore v0.14.0/go.mod h1:E3zKvyTyB+oQKqm/2I/jS6Rrt3B7fNuig/4bY2vi3bg=
|
||||
github.com/fluxcd/pkg/ssa v0.58.0 h1:W7m2LQFsZxPN9nn3lfGVDwXsZnIgCWWJ/+/K5hpzW+k=
|
||||
github.com/fluxcd/pkg/ssa v0.58.0/go.mod h1:iN/QDMqdJaVXKkqwbXqGa4PyWQwtyIy2WkeM2+9kfXA=
|
||||
github.com/fluxcd/pkg/ssa v0.59.0 h1:c88Q5w9e0MgrEi3Z7/+FWEVvtJFaVHfA9sxreMJUR7g=
|
||||
github.com/fluxcd/pkg/ssa v0.59.0/go.mod h1:iN/QDMqdJaVXKkqwbXqGa4PyWQwtyIy2WkeM2+9kfXA=
|
||||
github.com/fluxcd/pkg/ssh v0.21.0 h1:ZmyF0n9je0cTTkOpvFVgIhmdx9qtswnVE60TK4IzJh0=
|
||||
github.com/fluxcd/pkg/ssh v0.21.0/go.mod h1:nX+gvJOmjf0E7lxq5mKKzDIdPEL2jOUQZbkBMS+mDtk=
|
||||
github.com/fluxcd/pkg/tar v0.14.0 h1:9Gku8FIvPt2bixKldZnzXJ/t+7SloxePlzyVGOK8GVQ=
|
||||
github.com/fluxcd/pkg/tar v0.14.0/go.mod h1:+rOWYk93qLEJ8WwmkvJOkB8i0dna1mrwJFybE8i9Udo=
|
||||
github.com/fluxcd/pkg/version v0.10.0 h1:WETlCRbfbocsDItkCCeh/4x4zQkZ5i/lUe7P7VaQBrI=
|
||||
github.com/fluxcd/pkg/version v0.10.0/go.mod h1:dgmjEq4ykvBnqK1oVXM+hcXx3kAY/b4uZDYUn8XnHjk=
|
||||
github.com/fluxcd/source-controller/api v1.7.0 h1:y6vjvbkIN4JzianhmaJqujeghVpvQn3gcsVW/f1xMeA=
|
||||
github.com/fluxcd/source-controller/api v1.7.0/go.mod h1:UOIEs9AACxPW7fQFqGWw1/FN2QqYDLG6WkvPIyscHkw=
|
||||
github.com/fluxcd/source-controller/api v1.7.1 h1:THbPlCIrTpDejnztjKoY/iDD6/B0sPN8F2ROcFFgARQ=
|
||||
github.com/fluxcd/source-controller/api v1.7.1/go.mod h1:UOIEs9AACxPW7fQFqGWw1/FN2QqYDLG6WkvPIyscHkw=
|
||||
github.com/fluxcd/source-watcher/api/v2 v2.0.1 h1:XUVRjQvMMhYNryBnV6mItw/Eay1DSMksdFr6UDxlwws=
|
||||
github.com/fluxcd/source-watcher/api/v2 v2.0.1/go.mod h1:w1Z6yxPqjerwwvh4ljcSGHkRMA5HmFEdu8EmhiQfWKs=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.0/helm-controller.crds.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.0/helm-controller.deployment.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.1/helm-controller.crds.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.1/helm-controller.deployment.yaml
|
||||
- account.yaml
|
||||
transformers:
|
||||
- labels.yaml
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.1/notification-controller.crds.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.1/notification-controller.deployment.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.2/notification-controller.crds.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.2/notification-controller.deployment.yaml
|
||||
- account.yaml
|
||||
transformers:
|
||||
- labels.yaml
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.0/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.0/source-controller.deployment.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.1/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.1/source-controller.deployment.yaml
|
||||
- account.yaml
|
||||
transformers:
|
||||
- labels.yaml
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.0/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.1/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.7.0/kustomize-controller.crds.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.0/helm-controller.crds.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.1/notification-controller.crds.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.1/helm-controller.crds.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.2/notification-controller.crds.yaml
|
||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.0.1/image-reflector-controller.crds.yaml
|
||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.0.1/image-automation-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-watcher/releases/download/v2.0.1/source-watcher.crds.yaml
|
||||
|
|
|
|||
Loading…
Reference in a new issue