1
0
mirror of synced 2026-03-01 19:26:55 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Max Jonas Werner
3f79b4dd57 [wip] Add audit command
Signed-off-by: Max Jonas Werner <mail@makk.es>
2023-12-01 17:29:31 +01:00
113 changed files with 1517 additions and 1790 deletions

View File

@@ -17,7 +17,7 @@ jobs:
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs - name: Create backport PRs
uses: korthout/backport-action@b982d297e31f500652b2246cf26714796312bd23 # v2.2.0 uses: korthout/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191 # v2.1.1
# xref: https://github.com/korthout/backport-action#inputs # xref: https://github.com/korthout/backport-action#inputs
with: with:
# Use token to allow workflows to be triggered for the created PR # Use token to allow workflows to be triggered for the created PR

View File

@@ -17,13 +17,13 @@ jobs:
matrix: matrix:
# Keep this list up-to-date with https://endoflife.date/kubernetes # Keep this list up-to-date with https://endoflife.date/kubernetes
# Check which versions are available on DockerHub with 'crane ls kindest/node' # Check which versions are available on DockerHub with 'crane ls kindest/node'
KUBERNETES_VERSION: [ 1.26.6, 1.27.3, 1.28.0, 1.29.0 ] KUBERNETES_VERSION: [ 1.25.11, 1.26.6, 1.27.3, 1.28.0 ]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |

View File

@@ -32,7 +32,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: tests/azure/go.sum cache-dependency-path: tests/azure/go.sum
@@ -77,7 +77,7 @@ jobs:
- name: CheckoutD - name: CheckoutD
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: tests/integration/go.sum cache-dependency-path: tests/integration/go.sum
@@ -92,7 +92,7 @@ jobs:
env: env:
SOPS_VER: 3.7.1 SOPS_VER: 3.7.1
- name: Authenticate to Azure - name: Authenticate to Azure
uses: Azure/login@de95379fe4dadc2defb305917eaa7e5dde727294 # v1.4.6 uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6
with: with:
creds: '{"clientId":"${{ secrets.AZ_ARM_CLIENT_ID }}","clientSecret":"${{ secrets.AZ_ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZ_ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZ_ARM_TENANT_ID }}"}' creds: '{"clientId":"${{ secrets.AZ_ARM_CLIENT_ID }}","clientSecret":"${{ secrets.AZ_ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZ_ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZ_ARM_TENANT_ID }}"}'
- name: Set dynamic variables in .env - name: Set dynamic variables in .env

View File

@@ -19,7 +19,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |

View File

@@ -31,7 +31,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: tests/integration/go.sum cache-dependency-path: tests/integration/go.sum
@@ -46,13 +46,13 @@ jobs:
env: env:
SOPS_VER: 3.7.1 SOPS_VER: 3.7.1
- name: Authenticate to Google Cloud - name: Authenticate to Google Cloud
uses: google-github-actions/auth@67e9c72af6e0492df856527b474995862b7b6591 # v2.0.0 uses: google-github-actions/auth@35b0e87d162680511bf346c299f71c9c5c379033 # v1.1.1
id: 'auth' id: 'auth'
with: with:
credentials_json: '${{ secrets.FLUX2_E2E_GOOGLE_CREDENTIALS }}' credentials_json: '${{ secrets.FLUX2_E2E_GOOGLE_CREDENTIALS }}'
token_format: 'access_token' token_format: 'access_token'
- name: Setup gcloud - name: Setup gcloud
uses: google-github-actions/setup-gcloud@825196879a077b7efa50db2e88409f44de4635c2 # v2.0.0 uses: google-github-actions/setup-gcloud@e30db14379863a8c79331b04a9969f4c1e225e0b # v1.1.1
- name: Setup QEMU - name: Setup QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
- name: Setup Docker Buildx - name: Setup Docker Buildx

View File

@@ -23,7 +23,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |

View File

@@ -24,7 +24,7 @@ jobs:
- name: Unshallow - name: Unshallow
run: git fetch --prune --unshallow run: git fetch --prune --unshallow
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache: false cache: false
@@ -34,7 +34,7 @@ jobs:
id: buildx id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
- name: Setup Syft - name: Setup Syft
uses: anchore/sbom-action/download-syft@5ecf649a417b8ae17dc8383dc32d46c03f2312df # v0.15.1 uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3
- name: Setup Cosign - name: Setup Cosign
uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0 uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0
- name: Setup Kustomize - name: Setup Kustomize

View File

@@ -19,7 +19,7 @@ jobs:
steps: steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Run FOSSA scan and upload build data - name: Run FOSSA scan and upload build data
uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0 uses: fossa-contrib/fossa-action@6728dc6fe9a068c648d080c33829ffbe56565023 # v2.0.0
with: with:
# FOSSA Push-Only API Token # FOSSA Push-Only API Token
fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de
@@ -35,7 +35,7 @@ jobs:
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@main uses: fluxcd/pkg/actions/kustomize@main
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |
@@ -66,7 +66,7 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |

View File

@@ -20,7 +20,7 @@ jobs:
- name: Check out code - name: Check out code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go - name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with: with:
go-version: 1.20.x go-version: 1.20.x
cache-dependency-path: | cache-dependency-path: |

View File

@@ -1,15 +1,15 @@
FROM alpine:3.19 as builder FROM alpine:3.18 as builder
RUN apk add --no-cache ca-certificates curl RUN apk add --no-cache ca-certificates curl
ARG ARCH=linux/amd64 ARG ARCH=linux/amd64
ARG KUBECTL_VER=1.28.4 ARG KUBECTL_VER=1.27.3
RUN curl -sL https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \ RUN curl -sL https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \
-o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl && \ -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl && \
kubectl version --client=true kubectl version --client=true
FROM alpine:3.19 as flux-cli FROM alpine:3.18 as flux-cli
RUN apk add --no-cache ca-certificates RUN apk add --no-cache ca-certificates

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
// notificationv1.Alert // notificationv1.Alert

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
// notificationv1.Provider // notificationv1.Provider

195
cmd/flux/audit.go Normal file
View File

@@ -0,0 +1,195 @@
/*
Copyright 2023 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 (
"context"
"fmt"
"strings"
"github.com/fluxcd/flux2/v2/internal/utils"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
v1 "k8s.io/api/apps/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
)
var ctrlChecks = map[string]map[string]bool{
"helm-controller": {
"insecure-kubeconfig-exec": false,
"insecure-kubeconfig-tls": false,
},
"kustomize-controller": {
"insecure-kubeconfig-exec": false,
"insecure-kubeconfig-tls": false,
"no-remote-bases": true,
},
}
var multiTenancyCtrlChecks = map[string]map[string]bool{
"helm-controller": {
"no-cross-namespace-refs": true,
},
"kustomize-controller": {
"no-cross-namespace-refs": true,
},
"notification-controller": {
"no-cross-namespace-refs": true,
},
"image-reflector-controller": {
"no-cross-namespace-refs": true,
},
"image-automation-controller": {
"no-cross-namespace-refs": true,
},
}
var multiTenancyFlag bool
var auditCmd = &cobra.Command{
Use: "audit",
Short: "Audit the Flux installation for security best practices",
Long: withPreviewNote("TBD"),
Example: ` TBD`,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
logger.Actionf("Starting audit")
for ctrl, checks := range ctrlChecks {
if err := auditController(ctx, kubeClient, ctrl, checks); err != nil {
return fmt.Errorf("failed auditing %s: %w", ctrl, err)
}
}
if err := auditSecretDecryption(ctx, kubeClient); err != nil {
return fmt.Errorf("failed auditing Secret decryption: %w", err)
}
if multiTenancyFlag {
logger.Actionf("Multi-tenancy lock-down")
for ctrl, checks := range multiTenancyCtrlChecks {
if err := auditController(ctx, kubeClient, ctrl, checks); err != nil {
return fmt.Errorf("failed auditing %s for multi-tenancy lock-down: %w", ctrl, err)
}
}
}
return nil
},
}
func auditSecretDecryption(ctx context.Context, c client.Client) error {
var ksl kustomizev1.KustomizationList
if err := c.List(ctx, &ksl); err != nil {
return fmt.Errorf("failed to retrieve Kustomizations: %w", err)
}
success := true
for _, ks := range ksl.Items {
if ks.Status.Inventory == nil {
continue
}
if ks.Spec.Decryption != nil {
continue
}
for _, e := range ks.Status.Inventory.Entries {
parts := strings.Split(e.ID, "_")
if parts[2] == "" && parts[3] == "Secret" {
success = false
logger.Warningf("%s/%s doesn't have Secret decryption configured", ks.Namespace, ks.Name)
}
}
}
if success {
logger.Successf("Secret decryption is configured for all Kustomizations that create Secrets")
}
return nil
}
func auditController(ctx context.Context, c client.Client, name string, flags map[string]bool) error {
hcDeploys, err := getManagerArgs(ctx, c, name)
if err != nil {
return fmt.Errorf("failed to get %s flags: %w", name, err)
}
if len(hcDeploys) == 0 {
logger.Warningf("No %s Deployment found, auditing skipped", name)
} else {
for name, args := range hcDeploys {
for flag, desired := range flags {
hcExec, err := assertBoolFlagValue(args, flag, desired)
if err != nil {
return fmt.Errorf("failed parsing %q args: %w", name, err)
}
if hcExec == desired {
logger.Successf("%s: %s is %t", name, flag, desired)
} else {
logger.Warningf("%s: %s should be %t", name, flag, desired)
}
}
}
}
return nil
}
func getManagerArgs(ctx context.Context, c client.Client, component string) (map[string][]string, error) {
var deploys v1.DeploymentList
if err := c.List(ctx, &deploys, client.MatchingLabels{
"app.kubernetes.io/component": component,
}); err != nil {
return nil, fmt.Errorf("failed to retrieve %s deployments: %w", component, err)
}
res := make(map[string][]string, 0)
for _, deploy := range deploys.Items {
for _, ctr := range deploy.Spec.Template.Spec.Containers {
if ctr.Name == "manager" {
res[deploy.Name] = ctr.Args
}
}
}
return res, nil
}
func assertBoolFlagValue(args []string, flagName string, value bool) (bool, error) {
fs := pflag.NewFlagSet("tmp", pflag.ContinueOnError)
fs.ParseErrorsWhitelist.UnknownFlags = true
f := fs.BoolP(flagName, "", false, "")
if err := fs.Parse(args); err != nil {
return false, fmt.Errorf("failed parsing args: %w", err)
}
return *f, nil
}
func init() {
auditCmd.Flags().BoolVar(&multiTenancyFlag, "multi-tenancy", false, "Enable additional audit checks for multi-tenant clusters.")
rootCmd.AddCommand(auditCmd)
}

View File

@@ -56,7 +56,7 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a public repository on a personal account # Run bootstrap for a public repository on a personal account
flux bootstrap bitbucket-server --owner=<user> --repository=<repository name> --private=false --personal --hostname=<domain> --token-auth --path=clusters/my-cluster flux bootstrap bitbucket-server --owner=<user> --repository=<repository name> --private=false --personal --hostname=<domain> --token-auth --path=clusters/my-cluster
# Run bootstrap for an existing repository with a branch named main # Run bootstrap for a an existing repository with a branch named main
flux bootstrap bitbucket-server --owner=<project> --username=<user> --repository=<repository name> --branch=main --hostname=<domain> --token-auth --path=clusters/my-cluster`, flux bootstrap bitbucket-server --owner=<project> --username=<user> --repository=<repository name> --branch=main --hostname=<domain> --token-auth --path=clusters/my-cluster`,
RunE: bootstrapBServerCmdRun, RunE: bootstrapBServerCmdRun,
} }

View File

@@ -64,7 +64,7 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a private repository hosted on a GitLab server # Run bootstrap for a private repository hosted on a GitLab server
flux bootstrap gitlab --owner=<group> --repository=<repository name> --hostname=<domain> --token-auth flux bootstrap gitlab --owner=<group> --repository=<repository name> --hostname=<domain> --token-auth
# Run bootstrap for an existing repository with a branch named main # Run bootstrap for a an existing repository with a branch named main
flux bootstrap gitlab --owner=<organization> --repository=<repository name> --branch=main --token-auth flux bootstrap gitlab --owner=<organization> --repository=<repository name> --branch=main --token-auth
# Run bootstrap for a private repository using Deploy Token authentication # Run bootstrap for a private repository using Deploy Token authentication

View File

@@ -18,7 +18,6 @@ package main
import ( import (
"context" "context"
"fmt"
"os" "os"
"time" "time"
@@ -27,7 +26,6 @@ import (
v1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/version" "github.com/fluxcd/pkg/version"
@@ -59,7 +57,7 @@ type checkFlags struct {
} }
var kubernetesConstraints = []string{ var kubernetesConstraints = []string{
">=1.26.0-0", ">=1.25.0-0",
} }
var checkArgs checkFlags var checkArgs checkFlags
@@ -82,20 +80,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
fluxCheck() fluxCheck()
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) if !kubernetesCheck(kubernetesConstraints) {
defer cancel()
cfg, err := utils.KubeConfig(kubeconfigArgs, kubeclientOptions)
if err != nil {
return fmt.Errorf("Kubernetes client initialization failed: %s", err.Error())
}
kubeClient, err := client.New(cfg, client.Options{Scheme: utils.NewScheme()})
if err != nil {
return err
}
if !kubernetesCheck(cfg, kubernetesConstraints) {
checkFailed = true checkFailed = true
} }
@@ -107,18 +92,13 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
logger.Actionf("checking version in cluster")
if !fluxClusterVersionCheck(ctx, kubeClient) {
checkFailed = true
}
logger.Actionf("checking controllers") logger.Actionf("checking controllers")
if !componentsCheck(ctx, kubeClient) { if !componentsCheck() {
checkFailed = true checkFailed = true
} }
logger.Actionf("checking crds") logger.Actionf("checking crds")
if !crdsCheck(ctx, kubeClient) { if !crdsCheck() {
checkFailed = true checkFailed = true
} }
@@ -149,11 +129,17 @@ func fluxCheck() {
return return
} }
if latestSv.GreaterThan(curSv) { if latestSv.GreaterThan(curSv) {
logger.Failuref("flux %s <%s (new CLI version is available, please upgrade)", curSv, latestSv) logger.Failuref("flux %s <%s (new version is available, please upgrade)", curSv, latestSv)
} }
} }
func kubernetesCheck(cfg *rest.Config, constraints []string) bool { func kubernetesCheck(constraints []string) bool {
cfg, err := utils.KubeConfig(kubeconfigArgs, kubeclientOptions)
if err != nil {
logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
return false
}
clientSet, err := kubernetes.NewForConfig(cfg) clientSet, err := kubernetes.NewForConfig(cfg)
if err != nil { if err != nil {
logger.Failuref("Kubernetes client initialization failed: %s", err.Error()) logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
@@ -192,8 +178,21 @@ func kubernetesCheck(cfg *rest.Config, constraints []string) bool {
return true return true
} }
func componentsCheck(ctx context.Context, kubeClient client.Client) bool { func componentsCheck() bool {
statusChecker, err := status.NewStatusCheckerWithClient(kubeClient, checkArgs.pollInterval, rootArgs.timeout, logger) ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeConfig, err := utils.KubeConfig(kubeconfigArgs, kubeclientOptions)
if err != nil {
return false
}
statusChecker, err := status.NewStatusChecker(kubeConfig, checkArgs.pollInterval, rootArgs.timeout, logger)
if err != nil {
return false
}
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil { if err != nil {
return false return false
} }
@@ -223,7 +222,15 @@ func componentsCheck(ctx context.Context, kubeClient client.Client) bool {
return ok return ok
} }
func crdsCheck(ctx context.Context, kubeClient client.Client) bool { func crdsCheck() bool {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return false
}
ok := true ok := true
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue} selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list apiextensionsv1.CustomResourceDefinitionList var list apiextensionsv1.CustomResourceDefinitionList
@@ -246,17 +253,3 @@ func crdsCheck(ctx context.Context, kubeClient client.Client) bool {
} }
return ok return ok
} }
func fluxClusterVersionCheck(ctx context.Context, kubeClient client.Client) bool {
clusterInfo, err := getFluxClusterInfo(ctx, kubeClient)
if err != nil {
logger.Failuref("checking failed: %s", err.Error())
return false
}
if clusterInfo.distribution() != "" {
logger.Successf("distribution: %s", clusterInfo.distribution())
}
logger.Successf("bootstrapped: %t", clusterInfo.bootstrapped)
return true
}

View File

@@ -27,8 +27,6 @@ import (
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
) )
// bootstrapLabels are labels put on a resource by kustomize-controller. These labels on the CRD indicates // bootstrapLabels are labels put on a resource by kustomize-controller. These labels on the CRD indicates
@@ -44,8 +42,6 @@ type fluxClusterInfo struct {
bootstrapped bool bootstrapped bool
// managedBy is the name of the tool being used to manage the installation of Flux. // managedBy is the name of the tool being used to manage the installation of Flux.
managedBy string managedBy string
// partOf indicates which distribution the instance is a part of.
partOf string
// version is the Flux version number in semver format. // version is the Flux version number in semver format.
version string version string
} }
@@ -72,7 +68,7 @@ func getFluxClusterInfo(ctx context.Context, c client.Client) (fluxClusterInfo,
return info, err return info, err
} }
info.version = crdMetadata.Labels[manifestgen.VersionLabelKey] info.version = crdMetadata.Labels["app.kubernetes.io/version"]
var present bool var present bool
for _, l := range bootstrapLabels { for _, l := range bootstrapLabels {
@@ -82,15 +78,11 @@ func getFluxClusterInfo(ctx context.Context, c client.Client) (fluxClusterInfo,
info.bootstrapped = true info.bootstrapped = true
} }
// the `app.kubernetes.io/managed-by` label is not set by flux but might be set by other // the `app.kubernetes.io` label is not set by flux but might be set by other
// tools used to install Flux e.g Helm. // tools used to install Flux e.g Helm.
if manager, ok := crdMetadata.Labels["app.kubernetes.io/managed-by"]; ok { if manager, ok := crdMetadata.Labels["app.kubernetes.io/managed-by"]; ok {
info.managedBy = manager info.managedBy = manager
} }
if partOf, ok := crdMetadata.Labels[manifestgen.PartOfLabelKey]; ok {
info.partOf = partOf
}
return info, nil return info, nil
} }
@@ -113,14 +105,6 @@ func confirmFluxInstallOverride(info fluxClusterInfo) error {
return err return err
} }
func (info fluxClusterInfo) distribution() string {
distribution := info.version
if info.partOf != "" {
distribution = fmt.Sprintf("%s-%s", info.partOf, info.version)
}
return distribution
}
func installManagedByFlux(manager string) bool { func installManagedByFlux(manager string) bool {
return manager == "" || manager == "flux" return manager == "" || manager == "flux"
} }

View File

@@ -102,17 +102,6 @@ func Test_getFluxClusterInfo(t *testing.T) {
version: "v2.1.0", version: "v2.1.0",
}, },
}, },
{
name: "CRD with version and part-of labels",
labels: map[string]string{
"app.kubernetes.io/version": "v2.1.0",
"app.kubernetes.io/part-of": "flux",
},
wantInfo: fluxClusterInfo{
version: "v2.1.0",
partOf: "flux",
},
},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@@ -132,7 +132,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e
logger.Waitingf("waiting for %s reconciliation", names.kind) logger.Waitingf("waiting for %s reconciliation", names.kind)
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, object.asClientObject())); err != nil { isReady(kubeClient, namespacedName, object)); err != nil {
return err return err
} }
logger.Successf("%s reconciliation completed", names.kind) logger.Successf("%s reconciliation completed", names.kind)

View File

@@ -22,13 +22,14 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
@@ -96,13 +97,13 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
logger.Generatef("generating Alert") logger.Generatef("generating Alert")
} }
alert := notificationv1b3.Alert{ alert := notificationv1b2.Alert{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
Namespace: *kubeconfigArgs.Namespace, Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels, Labels: sourceLabels,
}, },
Spec: notificationv1b3.AlertSpec{ Spec: notificationv1b2.AlertSpec{
ProviderRef: meta.LocalObjectReference{ ProviderRef: meta.LocalObjectReference{
Name: alertArgs.providerRef, Name: alertArgs.providerRef,
}, },
@@ -132,7 +133,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Alert reconciliation") logger.Waitingf("waiting for Alert reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil { isAlertReady(kubeClient, namespacedName, &alert)); err != nil {
return err return err
} }
logger.Successf("Alert %s is ready", name) logger.Successf("Alert %s is ready", name)
@@ -140,13 +141,13 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
} }
func upsertAlert(ctx context.Context, kubeClient client.Client, func upsertAlert(ctx context.Context, kubeClient client.Client,
alert *notificationv1b3.Alert) (types.NamespacedName, error) { alert *notificationv1b2.Alert) (types.NamespacedName, error) {
namespacedName := types.NamespacedName{ namespacedName := types.NamespacedName{
Namespace: alert.GetNamespace(), Namespace: alert.GetNamespace(),
Name: alert.GetName(), Name: alert.GetName(),
} }
var existing notificationv1b3.Alert var existing notificationv1b2.Alert
err := kubeClient.Get(ctx, namespacedName, &existing) err := kubeClient.Get(ctx, namespacedName, &existing)
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
@@ -169,3 +170,22 @@ func upsertAlert(ctx context.Context, kubeClient client.Client,
logger.Successf("Alert updated") logger.Successf("Alert updated")
return namespacedName, nil return namespacedName, nil
} }
func isAlertReady(kubeClient client.Client, namespacedName types.NamespacedName, alert *notificationv1b2.Alert) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, alert)
if err != nil {
return false, err
}
if c := apimeta.FindStatusCondition(alert.Status.Conditions, meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -22,12 +22,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
@@ -127,7 +128,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Provider reconciliation") logger.Waitingf("waiting for Provider reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil { isAlertProviderReady(kubeClient, namespacedName, &provider)); err != nil {
return err return err
} }
@@ -166,3 +167,22 @@ func upsertAlertProvider(ctx context.Context, kubeClient client.Client,
logger.Successf("Provider updated") logger.Successf("Provider updated")
return namespacedName, nil return namespacedName, nil
} }
func isAlertProviderReady(kubeClient client.Client, namespacedName types.NamespacedName, provider *notificationv1.Provider) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, provider)
if err != nil {
return false, err
}
if c := apimeta.FindStatusCondition(provider.Status.Conditions, meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -24,22 +24,22 @@ import (
"strings" "strings"
"time" "time"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/transform"
"github.com/fluxcd/flux2/v2/internal/flags" "github.com/fluxcd/flux2/v2/internal/flags"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/transform"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var createHelmReleaseCmd = &cobra.Command{ var createHelmReleaseCmd = &cobra.Command{
@@ -304,7 +304,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for HelmRelease reconciliation") logger.Waitingf("waiting for HelmRelease reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &helmRelease)); err != nil { isHelmReleaseReady(kubeClient, namespacedName, &helmRelease)); err != nil {
return err return err
} }
logger.Successf("HelmRelease %s is ready", name) logger.Successf("HelmRelease %s is ready", name)
@@ -344,6 +344,22 @@ func upsertHelmRelease(ctx context.Context, kubeClient client.Client,
return namespacedName, nil return namespacedName, nil
} }
func isHelmReleaseReady(kubeClient client.Client, namespacedName types.NamespacedName, helmRelease *helmv2.HelmRelease) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, helmRelease)
if err != nil {
return false, err
}
// Confirm the state we are observing is for the current generation
if helmRelease.Generation != helmRelease.Status.ObservedGeneration {
return false, nil
}
return apimeta.IsStatusConditionTrue(helmRelease.Status.Conditions, meta.ReadyCondition), nil
}
}
func validateStrategy(input string) bool { func validateStrategy(input string) bool {
allowedStrategy := []string{"Revision", "ChartVersion"} allowedStrategy := []string{"Revision", "ChartVersion"}

View File

@@ -24,12 +24,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
@@ -263,7 +264,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Kustomization reconciliation") logger.Waitingf("waiting for Kustomization reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &kustomization)); err != nil { isKustomizationReady(kubeClient, namespacedName, &kustomization)); err != nil {
return err return err
} }
logger.Successf("Kustomization %s is ready", name) logger.Successf("Kustomization %s is ready", name)
@@ -302,3 +303,27 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client,
logger.Successf("Kustomization updated") logger.Successf("Kustomization updated")
return namespacedName, nil return namespacedName, nil
} }
func isKustomizationReady(kubeClient client.Client, namespacedName types.NamespacedName, kustomization *kustomizev1.Kustomization) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, kustomization)
if err != nil {
return false, err
}
// Confirm the state we are observing is for the current generation
if kustomization.Generation != kustomization.Status.ObservedGeneration {
return false, nil
}
if c := apimeta.FindStatusCondition(kustomization.Status.Conditions, meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
@@ -139,7 +140,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Receiver reconciliation") logger.Waitingf("waiting for Receiver reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &receiver)); err != nil { isReceiverReady(kubeClient, namespacedName, &receiver)); err != nil {
return err return err
} }
logger.Successf("Receiver %s is ready", name) logger.Successf("Receiver %s is ready", name)
@@ -178,3 +179,22 @@ func upsertReceiver(ctx context.Context, kubeClient client.Client,
logger.Successf("Receiver updated") logger.Successf("Receiver updated")
return namespacedName, nil return namespacedName, nil
} }
func isReceiverReady(kubeClient client.Client, namespacedName types.NamespacedName, receiver *notificationv1.Receiver) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, receiver)
if err != nil {
return false, err
}
if c := apimeta.FindStatusCondition(receiver.Status.Conditions, meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -31,6 +31,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -204,7 +205,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Bucket source reconciliation") logger.Waitingf("waiting for Bucket source reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, bucket)); err != nil { isBucketReady(kubeClient, namespacedName, bucket)); err != nil {
return err return err
} }
logger.Successf("Bucket source reconciliation completed") logger.Successf("Bucket source reconciliation completed")
@@ -246,3 +247,29 @@ func upsertBucket(ctx context.Context, kubeClient client.Client,
logger.Successf("Bucket source updated") logger.Successf("Bucket source updated")
return namespacedName, nil return namespacedName, nil
} }
func isBucketReady(kubeClient client.Client, namespacedName types.NamespacedName, bucket *sourcev1.Bucket) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, bucket)
if err != nil {
return false, err
}
if c := conditions.Get(bucket, meta.ReadyCondition); c != nil {
// Confirm the Ready condition we are observing is for the
// current generation
if c.ObservedGeneration != bucket.GetGeneration() {
return false, nil
}
// Further check the Status
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -35,6 +35,7 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
@@ -325,7 +326,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for GitRepository source reconciliation") logger.Waitingf("waiting for GitRepository source reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &gitRepository)); err != nil { isGitRepositoryReady(kubeClient, namespacedName, &gitRepository)); err != nil {
return err return err
} }
logger.Successf("GitRepository source reconciliation completed") logger.Successf("GitRepository source reconciliation completed")
@@ -367,3 +368,29 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client,
logger.Successf("GitRepository source updated") logger.Successf("GitRepository source updated")
return namespacedName, nil return namespacedName, nil
} }
func isGitRepositoryReady(kubeClient client.Client, namespacedName types.NamespacedName, gitRepository *sourcev1.GitRepository) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, gitRepository)
if err != nil {
return false, err
}
if c := conditions.Get(gitRepository, meta.ReadyCondition); c != nil {
// Confirm the Ready condition we are observing is for the
// current generation
if c.ObservedGeneration != gitRepository.GetGeneration() {
return false, nil
}
// Further check the Status
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -181,21 +181,12 @@ func TestCreateSourceGit(t *testing.T) {
Time: time.Now(), Time: time.Now(),
}, },
} }
repo.Status.ObservedGeneration = repo.GetGeneration()
}, },
}, { }, {
"Failed", "Failed",
command, command,
assertError("failed message"), assertError("failed message"),
func(repo *sourcev1.GitRepository) { func(repo *sourcev1.GitRepository) {
stalledCondition := metav1.Condition{
Type: meta.StalledCondition,
Status: metav1.ConditionTrue,
Reason: sourcev1.URLInvalidReason,
Message: "failed message",
ObservedGeneration: repo.GetGeneration(),
}
apimeta.SetStatusCondition(&repo.Status.Conditions, stalledCondition)
newCondition := metav1.Condition{ newCondition := metav1.Condition{
Type: meta.ReadyCondition, Type: meta.ReadyCondition,
Status: metav1.ConditionFalse, Status: metav1.ConditionFalse,
@@ -204,7 +195,6 @@ func TestCreateSourceGit(t *testing.T) {
ObservedGeneration: repo.GetGeneration(), ObservedGeneration: repo.GetGeneration(),
} }
apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition) apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition)
repo.Status.ObservedGeneration = repo.GetGeneration()
}, },
}, { }, {
"NoArtifact", "NoArtifact",
@@ -220,7 +210,6 @@ func TestCreateSourceGit(t *testing.T) {
ObservedGeneration: repo.GetGeneration(), ObservedGeneration: repo.GetGeneration(),
} }
apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition) apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition)
repo.Status.ObservedGeneration = repo.GetGeneration()
}, },
}, },
} }

View File

@@ -23,6 +23,7 @@ import (
"os" "os"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
@@ -230,12 +231,8 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
} }
logger.Waitingf("waiting for HelmRepository source reconciliation") logger.Waitingf("waiting for HelmRepository source reconciliation")
readyConditionFunc := isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository) if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
if helmRepository.Spec.Type == sourcev1.HelmRepositoryTypeOCI { isHelmRepositoryReady(kubeClient, namespacedName, helmRepository)); err != nil {
// HelmRepository type OCI is a static object.
readyConditionFunc = isStaticObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository)
}
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc); err != nil {
return err return err
} }
logger.Successf("HelmRepository source reconciliation completed") logger.Successf("HelmRepository source reconciliation completed")
@@ -282,3 +279,29 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client,
logger.Successf("source updated") logger.Successf("source updated")
return namespacedName, nil return namespacedName, nil
} }
func isHelmRepositoryReady(kubeClient client.Client, namespacedName types.NamespacedName, helmRepository *sourcev1.HelmRepository) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, helmRepository)
if err != nil {
return false, err
}
if c := conditions.Get(helmRepository, meta.ReadyCondition); c != nil {
// Confirm the Ready condition we are observing is for the
// current generation
if c.ObservedGeneration != helmRepository.GetGeneration() {
return false, nil
}
// Further check the Status
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -29,6 +29,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -192,7 +193,7 @@ func createSourceOCIRepositoryCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for OCIRepository reconciliation") logger.Waitingf("waiting for OCIRepository reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, repository)); err != nil { isOCIRepositoryReady(kubeClient, namespacedName, repository)); err != nil {
return err return err
} }
logger.Successf("OCIRepository reconciliation completed") logger.Successf("OCIRepository reconciliation completed")
@@ -234,3 +235,29 @@ func upsertOCIRepository(ctx context.Context, kubeClient client.Client,
logger.Successf("OCIRepository updated") logger.Successf("OCIRepository updated")
return namespacedName, nil return namespacedName, nil
} }
func isOCIRepositoryReady(kubeClient client.Client, namespacedName types.NamespacedName, ociRepository *sourcev1.OCIRepository) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, ociRepository)
if err != nil {
return false, err
}
if c := conditions.Get(ociRepository, meta.ReadyCondition); c != nil {
// Confirm the Ready condition we are observing is for the
// current generation
if c.ObservedGeneration != ociRepository.GetGeneration() {
return false, nil
}
// Further check the Status
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var deleteAlertCmd = &cobra.Command{ var deleteAlertCmd = &cobra.Command{

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var deleteAlertProviderCmd = &cobra.Command{ var deleteAlertProviderCmd = &cobra.Command{

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var deleteHelmReleaseCmd = &cobra.Command{ var deleteHelmReleaseCmd = &cobra.Command{

View File

@@ -39,12 +39,12 @@ import (
cmdutil "k8s.io/kubectl/pkg/cmd/util" cmdutil "k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
autov1 "github.com/fluxcd/image-automation-controller/api/v1beta1" autov1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -426,14 +426,14 @@ var fluxKindMap = refMap{
}, },
field: []string{"spec", "chart", "spec", "sourceRef"}, field: []string{"spec", "chart", "spec", "sourceRef"},
}, },
notificationv1b3.AlertKind: { notificationv1b2.AlertKind: {
gvk: notificationv1b3.GroupVersion.WithKind(notificationv1b3.AlertKind), gvk: notificationv1b2.GroupVersion.WithKind(notificationv1b2.AlertKind),
kind: notificationv1b3.ProviderKind, kind: notificationv1b2.ProviderKind,
crossNamespaced: false, crossNamespaced: false,
field: []string{"spec", "providerRef"}, field: []string{"spec", "providerRef"},
}, },
notificationv1.ReceiverKind: {gvk: notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)}, notificationv1.ReceiverKind: {gvk: notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)},
notificationv1b3.ProviderKind: {gvk: notificationv1b3.GroupVersion.WithKind(notificationv1b3.ProviderKind)}, notificationv1b2.ProviderKind: {gvk: notificationv1b2.GroupVersion.WithKind(notificationv1b2.ProviderKind)},
imagev1.ImagePolicyKind: { imagev1.ImagePolicyKind: {
gvk: imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind), gvk: imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind),
kind: imagev1.ImageRepositoryKind, kind: imagev1.ImageRepositoryKind,

View File

@@ -27,11 +27,20 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/client/fake"
helmv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
autov1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/ssa" "github.com/fluxcd/pkg/ssa"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
) )
@@ -78,7 +87,7 @@ spec:
timeout: 1m0s timeout: 1m0s
url: ssh://git@github.com/example/repo url: ssh://git@github.com/example/repo
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
name: podinfo name: podinfo
@@ -118,7 +127,7 @@ spec:
name: podinfo-chart name: podinfo-chart
version: '*' version: '*'
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Alert kind: Alert
metadata: metadata:
name: webapp name: webapp
@@ -131,7 +140,7 @@ spec:
providerRef: providerRef:
name: slack name: slack
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Provider kind: Provider
metadata: metadata:
name: slack name: slack
@@ -163,7 +172,7 @@ func Test_getObjectRef(t *testing.T) {
objs, err := ssa.ReadObjects(strings.NewReader(objects)) objs, err := ssa.ReadObjects(strings.NewReader(objects))
g.Expect(err).To(Not(HaveOccurred())) g.Expect(err).To(Not(HaveOccurred()))
builder := fake.NewClientBuilder().WithScheme(utils.NewScheme()) builder := fake.NewClientBuilder().WithScheme(getScheme())
for _, obj := range objs { for _, obj := range objs {
builder = builder.WithObjects(obj) builder = builder.WithObjects(obj)
} }
@@ -247,7 +256,7 @@ func Test_getRows(t *testing.T) {
objs, err := ssa.ReadObjects(strings.NewReader(objects)) objs, err := ssa.ReadObjects(strings.NewReader(objects))
g.Expect(err).To(Not(HaveOccurred())) g.Expect(err).To(Not(HaveOccurred()))
builder := fake.NewClientBuilder().WithScheme(utils.NewScheme()) builder := fake.NewClientBuilder().WithScheme(getScheme())
for _, obj := range objs { for _, obj := range objs {
builder = builder.WithObjects(obj) builder = builder.WithObjects(obj)
} }
@@ -401,6 +410,21 @@ func getTestListOpt(kind, name string) client.ListOption {
return client.MatchingFieldsSelector{Selector: sel} return client.MatchingFieldsSelector{Selector: sel}
} }
func getScheme() *runtime.Scheme {
newscheme := runtime.NewScheme()
corev1.AddToScheme(newscheme)
kustomizev1.AddToScheme(newscheme)
helmv2beta1.AddToScheme(newscheme)
notificationv1.AddToScheme(newscheme)
notificationv1b2.AddToScheme(newscheme)
imagev1.AddToScheme(newscheme)
autov1.AddToScheme(newscheme)
sourcev1.AddToScheme(newscheme)
sourcev1b2.AddToScheme(newscheme)
return newscheme
}
func createEvent(obj client.Object, eventType, msg, reason string) corev1.Event { func createEvent(obj client.Object, eventType, msg, reason string) corev1.Event {
return corev1.Event{ return corev1.Event{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{

View File

@@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var exportAlertCmd = &cobra.Command{ var exportAlertCmd = &cobra.Command{

View File

@@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var exportAlertProviderCmd = &cobra.Command{ var exportAlertProviderCmd = &cobra.Command{

View File

@@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var exportHelmReleaseCmd = &cobra.Command{ var exportHelmReleaseCmd = &cobra.Command{

View File

@@ -18,6 +18,7 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@@ -27,6 +28,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
watchtools "k8s.io/client-go/tools/watch" watchtools "k8s.io/client-go/tools/watch"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
@@ -176,7 +178,8 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
err = kubeClient.List(ctx, get.list.asClientList(), listOpts...) err = kubeClient.List(ctx, get.list.asClientList(), listOpts...)
if err != nil { if err != nil {
if getAll && apimeta.IsNoMatchError(err) { var discErr *discovery.ErrGroupDiscoveryFailed
if getAll && (strings.Contains(err.Error(), "no matches for kind") || errors.As(err, &discErr)) {
return nil return nil
} }
return err return err

View File

@@ -23,10 +23,9 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var getAlertCmd = &cobra.Command{ var getAlertCmd = &cobra.Command{
@@ -78,7 +77,7 @@ func init() {
func (s alertListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string { func (s alertListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i] item := s.Items[i]
status, msg := string(metav1.ConditionTrue), "Alert is Ready" status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace, includeKind), return append(nameColumns(&item, includeNamespace, includeKind),
cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg) cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg)
} }
@@ -92,5 +91,6 @@ func (s alertListAdapter) headers(includeNamespace bool) []string {
} }
func (s alertListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { func (s alertListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool {
return false item := s.Items[i]
return statusMatches(conditionType, conditionStatus, item.Status.Conditions)
} }

View File

@@ -20,10 +20,9 @@ import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var getAlertProviderCmd = &cobra.Command{ var getAlertProviderCmd = &cobra.Command{
@@ -75,7 +74,7 @@ func init() {
func (s alertProviderListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string { func (s alertProviderListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i] item := s.Items[i]
status, msg := string(metav1.ConditionTrue), "Provider is Ready" status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace, includeKind), status, msg) return append(nameColumns(&item, includeNamespace, includeKind), status, msg)
} }
@@ -88,5 +87,6 @@ func (s alertProviderListAdapter) headers(includeNamespace bool) []string {
} }
func (s alertProviderListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { func (s alertProviderListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool {
return false item := s.Items[i]
return statusMatches(conditionType, conditionStatus, item.Status.Conditions)
} }

View File

@@ -17,13 +17,14 @@ limitations under the License.
package main package main
import ( import (
"github.com/spf13/cobra" "strings"
apimeta "k8s.io/apimachinery/pkg/api/meta"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" "github.com/spf13/cobra"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var getAllCmd = &cobra.Command{ var getAllCmd = &cobra.Command{
@@ -62,11 +63,11 @@ var getAllCmd = &cobra.Command{
}, },
{ {
apiType: alertProviderType, apiType: alertProviderType,
list: alertProviderListAdapter{&notificationv1b3.ProviderList{}}, list: alertProviderListAdapter{&notificationv1b2.ProviderList{}},
}, },
{ {
apiType: alertType, apiType: alertType,
list: &alertListAdapter{&notificationv1b3.AlertList{}}, list: &alertListAdapter{&notificationv1b2.AlertList{}},
}, },
} }
@@ -86,7 +87,7 @@ var getAllCmd = &cobra.Command{
} }
func logError(err error) { func logError(err error) {
if !apimeta.IsNoMatchError(err) { if !strings.Contains(err.Error(), "no matches for kind") {
logger.Failuref(err.Error()) logger.Failuref(err.Error())
} }
} }

View File

@@ -25,7 +25,7 @@ import (
"golang.org/x/text/language" "golang.org/x/text/language"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var getHelmReleaseCmd = &cobra.Command{ var getHelmReleaseCmd = &cobra.Command{

View File

@@ -17,8 +17,9 @@ limitations under the License.
package main package main
import ( import (
"strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apimeta "k8s.io/apimachinery/pkg/api/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -64,7 +65,7 @@ var getSourceAllCmd = &cobra.Command{
for _, c := range allSourceCmd { for _, c := range allSourceCmd {
if err := c.run(cmd, args); err != nil { if err := c.run(cmd, args); err != nil {
if !apimeta.IsNoMatchError(err) { if !strings.Contains(err.Error(), "no matches for kind") {
logger.Failuref(err.Error()) logger.Failuref(err.Error())
} }
} }

View File

@@ -23,7 +23,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -83,12 +82,7 @@ func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool,
if item.GetArtifact() != nil { if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision revision = item.GetArtifact().Revision
} }
var status, msg string status, msg := statusAndMessage(item.Status.Conditions)
if item.Spec.Type == sourcev1.HelmRepositoryTypeOCI {
status, msg = string(metav1.ConditionTrue), "Helm repository is Ready"
} else {
status, msg = statusAndMessage(item.Status.Conditions)
}
revision = utils.TruncateHex(revision) revision = utils.TruncateHex(revision)
msg = utils.TruncateHex(msg) msg = utils.TruncateHex(msg)
return append(nameColumns(&item, includeNamespace, includeKind), return append(nameColumns(&item, includeNamespace, includeKind),

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
// helmv2.HelmRelease // helmv2.HelmRelease

View File

@@ -25,15 +25,10 @@ import (
"os" "os"
"testing" "testing"
"github.com/go-logr/logr"
"sigs.k8s.io/controller-runtime/pkg/log"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
log.SetLogger(logr.New(log.NullLogSink{}))
// Ensure tests print consistent timestamps regardless of timezone // Ensure tests print consistent timestamps regardless of timezone
os.Setenv("TZ", "UTC") os.Setenv("TZ", "UTC")

View File

@@ -34,7 +34,6 @@ import (
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/mattn/go-shellwords" "github.com/mattn/go-shellwords"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8syaml "k8s.io/apimachinery/pkg/util/yaml" k8syaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
@@ -113,8 +112,7 @@ func (m *testEnvKubeManager) CreateObjects(clientObjects []*unstructured.Unstruc
} }
obj.SetResourceVersion(createObj.GetResourceVersion()) obj.SetResourceVersion(createObj.GetResourceVersion())
err = m.client.Status().Update(context.Background(), obj) err = m.client.Status().Update(context.Background(), obj)
// Updating status of static objects results in not found error. if err != nil {
if err != nil && !errors.IsNotFound(err) {
return err return err
} }
} }

View File

@@ -22,13 +22,10 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"testing"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/log" "os"
"testing"
) )
// The test environment is long running process shared between tests, initialized // The test environment is long running process shared between tests, initialized
@@ -37,8 +34,6 @@ import (
var testEnv *testEnvKubeManager var testEnv *testEnvKubeManager
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
log.SetLogger(logr.New(log.NullLogSink{}))
// Ensure tests print consistent timestamps regardless of timezone // Ensure tests print consistent timestamps regardless of timezone
os.Setenv("TZ", "UTC") os.Setenv("TZ", "UTC")

View File

@@ -1,149 +0,0 @@
/*
Copyright 2023 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 (
"context"
"fmt"
kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/object"
"github.com/fluxcd/pkg/runtime/patch"
)
// objectStatusType is the type of object in terms of status when computing the
// readiness of an object. Readiness check method depends on the type of object.
// For a dynamic object, Ready status condition is considered only for the
// latest generation of the object. For a static object that don't have any
// condition, the object generation is not considered.
type objectStatusType int
const (
objectStatusDynamic objectStatusType = iota
objectStatusStatic
)
// isObjectReady determines if an object is ready using the kstatus.Compute()
// result. statusType helps differenciate between static and dynamic objects to
// accurately check the object's readiness. A dynamic object may have some extra
// considerations depending on the object.
func isObjectReady(obj client.Object, statusType objectStatusType) (bool, error) {
observedGen, err := object.GetStatusObservedGeneration(obj)
if err != nil && err != object.ErrObservedGenerationNotFound {
return false, err
}
if statusType == objectStatusDynamic {
// Object not reconciled yet.
if observedGen < 1 {
return false, nil
}
cobj, ok := obj.(meta.ObjectWithConditions)
if !ok {
return false, fmt.Errorf("unable to get conditions from object")
}
if c := apimeta.FindStatusCondition(cobj.GetConditions(), meta.ReadyCondition); c != nil {
// Ensure that the ready condition is for the latest generation of
// the object.
// NOTE: Some APIs like ImageUpdateAutomation and HelmRelease don't
// support per condition observed generation yet. Per condition
// observed generation for them are always zero.
// There are two strategies used across different object kinds to
// check the latest ready condition:
// - check that the ready condition's generation matches the
// object's generation.
// - check that the observed generation of the object in the
// status matches the object's generation.
//
// TODO: Once ImageUpdateAutomation and HelmRelease APIs have per
// condition observed generation, remove the object's observed
// generation and object's generation check (the second condition
// below). Also, try replacing this readiness check function with
// fluxcd/pkg/ssa's ResourceManager.Wait(), which uses kstatus
// internally to check readiness of the objects.
if c.ObservedGeneration != 0 && c.ObservedGeneration != obj.GetGeneration() {
return false, nil
}
if c.ObservedGeneration == 0 && observedGen != obj.GetGeneration() {
return false, nil
}
} else {
return false, nil
}
}
u, err := patch.ToUnstructured(obj)
if err != nil {
return false, err
}
result, err := kstatus.Compute(u)
if err != nil {
return false, err
}
switch result.Status {
case kstatus.CurrentStatus:
return true, nil
case kstatus.InProgressStatus:
return false, nil
default:
return false, fmt.Errorf(result.Message)
}
}
// isObjectReadyConditionFunc returns a wait.ConditionFunc to be used with
// wait.Poll* while polling for an object with dynamic status to be ready.
func isObjectReadyConditionFunc(kubeClient client.Client, namespaceName types.NamespacedName, obj client.Object) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespaceName, obj)
if err != nil {
return false, err
}
return isObjectReady(obj, objectStatusDynamic)
}
}
// isStaticObjectReadyConditionFunc returns a wait.ConditionFunc to be used with
// wait.Poll* while polling for an object with static or no status to be
// ready.
func isStaticObjectReadyConditionFunc(kubeClient client.Client, namespaceName types.NamespacedName, obj client.Object) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespaceName, obj)
if err != nil {
return false, err
}
return isObjectReady(obj, objectStatusStatic)
}
}
// kstatusCompute returns the kstatus computed result of a given object.
func kstatusCompute(obj client.Object) (result *kstatus.Result, err error) {
u, err := patch.ToUnstructured(obj)
if err != nil {
return result, err
}
return kstatus.Compute(u)
}

View File

@@ -1,139 +0,0 @@
/*
Copyright 2023 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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
)
func Test_isObjectReady(t *testing.T) {
// Ready object.
readyObj := &sourcev1.GitRepository{}
readyObj.Generation = 1
readyObj.Status.ObservedGeneration = 1
conditions.MarkTrue(readyObj, meta.ReadyCondition, "foo1", "bar1")
// Not ready object.
notReadyObj := readyObj.DeepCopy()
conditions.MarkFalse(notReadyObj, meta.ReadyCondition, "foo2", "bar2")
// Not reconciled object.
notReconciledObj := readyObj.DeepCopy()
notReconciledObj.Status = sourcev1.GitRepositoryStatus{ObservedGeneration: -1}
// No condition.
noConditionObj := readyObj.DeepCopy()
noConditionObj.Status = sourcev1.GitRepositoryStatus{ObservedGeneration: 1}
// Outdated condition.
readyObjOutdated := readyObj.DeepCopy()
readyObjOutdated.Generation = 2
// Object without per condition observed generation.
oldObj := readyObj.DeepCopy()
readyTrueCondn := conditions.TrueCondition(meta.ReadyCondition, "foo3", "bar3")
oldObj.Status.Conditions = []metav1.Condition{*readyTrueCondn}
// Outdated object without per condition observed generation.
oldObjOutdated := oldObj.DeepCopy()
oldObjOutdated.Generation = 2
// Empty status object.
staticObj := readyObj.DeepCopy()
staticObj.Status = sourcev1.GitRepositoryStatus{}
// No status object.
noStatusObj := &notificationv1.Provider{}
noStatusObj.Generation = 1
type args struct {
obj client.Object
statusType objectStatusType
}
tests := []struct {
name string
args args
want bool
wantErr bool
}{
{
name: "dynamic ready",
args: args{obj: readyObj, statusType: objectStatusDynamic},
want: true,
},
{
name: "dynamic not ready",
args: args{obj: notReadyObj, statusType: objectStatusDynamic},
want: false,
},
{
name: "dynamic not reconciled",
args: args{obj: notReconciledObj, statusType: objectStatusDynamic},
want: false,
},
{
name: "dynamic not condition",
args: args{obj: noConditionObj, statusType: objectStatusDynamic},
want: false,
},
{
name: "dynamic ready outdated",
args: args{obj: readyObjOutdated, statusType: objectStatusDynamic},
want: false,
},
{
name: "dynamic ready without per condition gen",
args: args{obj: oldObj, statusType: objectStatusDynamic},
want: true,
},
{
name: "dynamic outdated ready status without per condition gen",
args: args{obj: oldObjOutdated, statusType: objectStatusDynamic},
want: false,
},
{
name: "static empty status",
args: args{obj: staticObj, statusType: objectStatusStatic},
want: true,
},
{
name: "static no status",
args: args{obj: noStatusObj, statusType: objectStatusStatic},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := isObjectReady(tt.args.obj, tt.args.statusType)
if (err != nil) != tt.wantErr {
t.Errorf("isObjectReady() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("isObjectReady() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"time" "time"
kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apimeta "k8s.io/apimachinery/pkg/api/meta" apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -31,7 +30,8 @@ import (
"k8s.io/client-go/util/retry" "k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
@@ -61,7 +61,6 @@ type reconcilable interface {
GetAnnotations() map[string]string GetAnnotations() map[string]string
SetAnnotations(map[string]string) SetAnnotations(map[string]string)
isStatic() bool // is it a static object that does not have a reconciler?
lastHandledReconcileRequest() string // what was the last handled reconcile request? lastHandledReconcileRequest() string // what was the last handled reconcile request?
successMessage() string // what do you want to tell people when successfully reconciled? successMessage() string // what do you want to tell people when successfully reconciled?
} }
@@ -102,11 +101,6 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error {
return err return err
} }
if reconcile.object.isStatic() {
logger.Successf("reconciliation not supported by the object")
return nil
}
if reconcile.object.isSuspended() { if reconcile.object.isSuspended() {
return fmt.Errorf("resource is suspended") return fmt.Errorf("resource is suspended")
} }
@@ -118,6 +112,16 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error {
} }
logger.Successf("%s annotated", reconcile.kind) logger.Successf("%s annotated", reconcile.kind)
if reconcile.kind == notificationv1b2.AlertKind || reconcile.kind == notificationv1.ReceiverKind {
if err = wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isReconcileReady(kubeClient, namespacedName, reconcile.object)); err != nil {
return err
}
logger.Successf(reconcile.object.successMessage())
return nil
}
lastHandledReconcileAt := reconcile.object.lastHandledReconcileRequest() lastHandledReconcileAt := reconcile.object.lastHandledReconcileRequest()
logger.Waitingf("waiting for %s reconciliation", reconcile.kind) logger.Waitingf("waiting for %s reconciliation", reconcile.kind)
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
@@ -142,17 +146,9 @@ func reconciliationHandled(kubeClient client.Client, namespacedName types.Namesp
if err != nil { if err != nil {
return false, err return false, err
} }
isProgressing := apimeta.IsStatusConditionPresentAndEqual(reconcilableConditions(obj),
if obj.lastHandledReconcileRequest() == lastHandledReconcileAt { meta.ReadyCondition, metav1.ConditionUnknown)
return false, nil return obj.lastHandledReconcileRequest() != lastHandledReconcileAt && !isProgressing, nil
}
result, err := kstatusCompute(obj.asClientObject())
if err != nil {
return false, err
}
return result.Status == kstatus.CurrentStatus, nil
} }
} }
@@ -167,26 +163,33 @@ func requestReconciliation(ctx context.Context, kubeClient client.Client,
return err return err
} }
patch := client.MergeFrom(object.DeepCopy()) patch := client.MergeFrom(object.DeepCopy())
if ann := object.GetAnnotations(); ann == nil {
// Add a timestamp annotation to trigger a reconciliation. object.SetAnnotations(map[string]string{
ts := time.Now().Format(time.RFC3339Nano) meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
annotations := object.GetAnnotations() })
if annotations == nil { } else {
annotations = make(map[string]string, 1) ann[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
object.SetAnnotations(ann)
} }
annotations[meta.ReconcileRequestAnnotation] = ts
// HelmRelease specific annotations to force or reset a release.
if gvk.Kind == helmv2.HelmReleaseKind {
if rhrArgs.syncForce {
annotations[helmv2.ForceRequestAnnotation] = ts
}
if rhrArgs.syncReset {
annotations[helmv2.ResetRequestAnnotation] = ts
}
}
object.SetAnnotations(annotations)
return kubeClient.Patch(ctx, object, patch) return kubeClient.Patch(ctx, object, patch)
}) })
} }
func isReconcileReady(kubeClient client.Client, namespacedName types.NamespacedName, obj reconcilable) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, obj.asClientObject())
if err != nil {
return false, err
}
if c := apimeta.FindStatusCondition(reconcilableConditions(obj), meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2020 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 (
"github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
)
var reconcileAlertCmd = &cobra.Command{
Use: "alert [name]",
Short: "Reconcile an Alert",
Long: `The reconcile alert command triggers a reconciliation of an Alert resource and waits for it to finish.`,
Example: ` # Trigger a reconciliation for an existing alert
flux reconcile alert main`,
ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
RunE: reconcileCommand{
apiType: alertType,
object: alertAdapter{&notificationv1.Alert{}},
}.run,
}
func init() {
reconcileCmd.AddCommand(reconcileAlertCmd)
}
func (obj alertAdapter) lastHandledReconcileRequest() string {
return ""
}

View File

@@ -0,0 +1,93 @@
/*
Copyright 2020 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 (
"context"
"fmt"
"time"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/v2/internal/utils"
)
var reconcileAlertProviderCmd = &cobra.Command{
Use: "alert-provider [name]",
Short: "Reconcile a Provider",
Long: `The reconcile alert-provider command triggers a reconciliation of a Provider resource and waits for it to finish.`,
Example: ` # Trigger a reconciliation for an existing provider
flux reconcile alert-provider slack`,
ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
RunE: reconcileAlertProviderCmdRun,
}
func init() {
reconcileCmd.AddCommand(reconcileAlertProviderCmd)
}
func reconcileAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("Provider name is required")
}
name := args[0]
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
logger.Actionf("annotating Provider %s in %s namespace", name, *kubeconfigArgs.Namespace)
var alertProvider notificationv1.Provider
err = kubeClient.Get(ctx, namespacedName, &alertProvider)
if err != nil {
return err
}
if alertProvider.Annotations == nil {
alertProvider.Annotations = map[string]string{
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
alertProvider.Annotations[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &alertProvider); err != nil {
return err
}
logger.Successf("Provider annotated")
logger.Waitingf("waiting for reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isAlertProviderReady(kubeClient, namespacedName, &alertProvider)); err != nil {
return err
}
logger.Successf("Provider reconciliation completed")
return nil
}

View File

@@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
) )
@@ -46,16 +46,13 @@ The reconcile kustomization command triggers a reconciliation of a HelmRelease r
type reconcileHelmReleaseFlags struct { type reconcileHelmReleaseFlags struct {
syncHrWithSource bool syncHrWithSource bool
syncForce bool
syncReset bool
} }
var rhrArgs reconcileHelmReleaseFlags var rhrArgs reconcileHelmReleaseFlags
func init() { func init() {
reconcileHrCmd.Flags().BoolVar(&rhrArgs.syncHrWithSource, "with-source", false, "reconcile HelmRelease source") reconcileHrCmd.Flags().BoolVar(&rhrArgs.syncHrWithSource, "with-source", false, "reconcile HelmRelease source")
reconcileHrCmd.Flags().BoolVar(&rhrArgs.syncForce, "force", false, "force a one-off install or upgrade of the HelmRelease resource")
reconcileHrCmd.Flags().BoolVar(&rhrArgs.syncReset, "reset", false, "reset the failure count for this HelmRelease resource")
reconcileCmd.AddCommand(reconcileHrCmd) reconcileCmd.AddCommand(reconcileHrCmd)
} }
@@ -84,7 +81,3 @@ func (obj helmReleaseAdapter) getSource() (reconcileSource, types.NamespacedName
Namespace: ns, Namespace: ns,
} }
} }
func (obj helmReleaseAdapter) isStatic() bool {
return false
}

View File

@@ -48,7 +48,3 @@ func (obj imageRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj imageRepositoryAdapter) successMessage() string { func (obj imageRepositoryAdapter) successMessage() string {
return fmt.Sprintf("scan fetched %d tags", obj.Status.LastScanResult.TagCount) return fmt.Sprintf("scan fetched %d tags", obj.Status.LastScanResult.TagCount)
} }
func (obj imageRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -56,7 +56,3 @@ func (obj imageUpdateAutomationAdapter) successMessage() string {
} }
return "automation not yet run" return "automation not yet run"
} }
func (obj imageUpdateAutomationAdapter) isStatic() bool {
return false
}

View File

@@ -88,7 +88,3 @@ func (obj kustomizationAdapter) getSource() (reconcileSource, types.NamespacedNa
Namespace: obj.Spec.SourceRef.Namespace, Namespace: obj.Spec.SourceRef.Namespace,
} }
} }
func (obj kustomizationAdapter) isStatic() bool {
return false
}

View File

@@ -17,9 +17,18 @@ limitations under the License.
package main package main
import ( import (
"context"
"fmt"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/v2/internal/utils"
) )
var reconcileReceiverCmd = &cobra.Command{ var reconcileReceiverCmd = &cobra.Command{
@@ -29,20 +38,62 @@ var reconcileReceiverCmd = &cobra.Command{
Example: ` # Trigger a reconciliation for an existing receiver Example: ` # Trigger a reconciliation for an existing receiver
flux reconcile receiver main`, flux reconcile receiver main`,
ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
RunE: reconcileCommand{ RunE: reconcileReceiverCmdRun,
apiType: receiverType,
object: receiverAdapter{&notificationv1.Receiver{}},
}.run,
} }
func init() { func init() {
reconcileCmd.AddCommand(reconcileReceiverCmd) reconcileCmd.AddCommand(reconcileReceiverCmd)
} }
func (obj receiverAdapter) lastHandledReconcileRequest() string { func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error {
return obj.Status.GetLastHandledReconcileRequest() if len(args) < 1 {
} return fmt.Errorf("receiver name is required")
}
name := args[0]
func (obj receiverAdapter) isStatic() bool { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
return false defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
var receiver notificationv1.Receiver
err = kubeClient.Get(ctx, namespacedName, &receiver)
if err != nil {
return err
}
if receiver.Spec.Suspend {
return fmt.Errorf("resource is suspended")
}
logger.Actionf("annotating Receiver %s in %s namespace", name, *kubeconfigArgs.Namespace)
if receiver.Annotations == nil {
receiver.Annotations = map[string]string{
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
receiver.Annotations[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &receiver); err != nil {
return err
}
logger.Successf("Receiver annotated")
logger.Waitingf("waiting for Receiver reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isReceiverReady(kubeClient, namespacedName, &receiver)); err != nil {
return err
}
logger.Successf("Receiver reconciliation completed")
return nil
} }

View File

@@ -48,7 +48,3 @@ func (obj bucketAdapter) lastHandledReconcileRequest() string {
func (obj bucketAdapter) successMessage() string { func (obj bucketAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj bucketAdapter) isStatic() bool {
return false
}

View File

@@ -84,7 +84,3 @@ func (obj helmChartAdapter) getSource() (reconcileSource, types.NamespacedName)
Namespace: obj.Namespace, Namespace: obj.Namespace,
} }
} }
func (obj helmChartAdapter) isStatic() bool {
return false
}

View File

@@ -48,7 +48,3 @@ func (obj gitRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj gitRepositoryAdapter) successMessage() string { func (obj gitRepositoryAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj gitRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -60,7 +60,3 @@ func (obj helmRepositoryAdapter) successMessage() string {
} }
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj helmRepositoryAdapter) isStatic() bool {
return obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI
}

View File

@@ -48,7 +48,3 @@ func (obj ociRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj ociRepositoryAdapter) successMessage() string { func (obj ociRepositoryAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj ociRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -56,7 +56,6 @@ type resumable interface {
copyable copyable
statusable statusable
setUnsuspended() setUnsuspended()
isStatic() bool
successMessage() string successMessage() string
} }
@@ -213,12 +212,8 @@ func (resume resumeCommand) reconcile(ctx context.Context, res resumable) reconc
logger.Waitingf("waiting for %s reconciliation", resume.kind) logger.Waitingf("waiting for %s reconciliation", resume.kind)
readyConditionFunc := isObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject()) if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
if res.isStatic() { isReady(resume.client, namespacedName, res)); err != nil {
readyConditionFunc = isStaticObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject())
}
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc); err != nil {
return reconcileResponse{ return reconcileResponse{
resumable: res, resumable: res,
err: err, err: err,

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var resumeAlertCmd = &cobra.Command{ var resumeAlertCmd = &cobra.Command{
@@ -44,7 +44,7 @@ func init() {
} }
func (obj alertAdapter) getObservedGeneration() int64 { func (obj alertAdapter) getObservedGeneration() int64 {
return 0 return obj.Alert.Status.ObservedGeneration
} }
func (obj alertAdapter) setUnsuspended() { func (obj alertAdapter) setUnsuspended() {
@@ -55,10 +55,6 @@ func (obj alertAdapter) successMessage() string {
return "Alert reconciliation completed" return "Alert reconciliation completed"
} }
func (a alertAdapter) isStatic() bool {
return true
}
func (a alertListAdapter) resumeItem(i int) resumable { func (a alertListAdapter) resumeItem(i int) resumable {
return &alertAdapter{&a.AlertList.Items[i]} return &alertAdapter{&a.AlertList.Items[i]}
} }

View File

@@ -1,64 +0,0 @@
/*
Copyright 2023 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 (
"github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3"
)
var resumeAlertProviderCmd = &cobra.Command{
Use: "alert-provider [name]",
Short: "Resume a suspended Provider",
Long: `The resume command marks a previously suspended Provider resource for reconciliation and waits for it to
finish the apply.`,
Example: ` # Resume reconciliation for an existing Provider
flux resume alert-provider main
# Resume reconciliation for multiple Providers
flux resume alert-provider main-1 main-2`,
ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
RunE: resumeCommand{
apiType: alertProviderType,
list: &alertProviderListAdapter{&notificationv1.ProviderList{}},
}.run,
}
func init() {
resumeCmd.AddCommand(resumeAlertProviderCmd)
}
func (obj alertProviderAdapter) getObservedGeneration() int64 {
return 0
}
func (obj alertProviderAdapter) setUnsuspended() {
obj.Provider.Spec.Suspend = false
}
func (obj alertProviderAdapter) successMessage() string {
return "Provider reconciliation completed"
}
func (a alertProviderAdapter) isStatic() bool {
return true
}
func (a alertProviderListAdapter) resumeItem(i int) resumable {
return &alertProviderAdapter{&a.ProviderList.Items[i]}
}

View File

@@ -21,7 +21,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var resumeHrCmd = &cobra.Command{ var resumeHrCmd = &cobra.Command{

View File

@@ -27,12 +27,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/cli-utils/pkg/kstatus/status" "github.com/fluxcd/cli-utils/pkg/kstatus/status"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
autov1 "github.com/fluxcd/image-automation-controller/api/v1beta1" autov1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -111,14 +111,14 @@ func runStatsCmd(cmd *cobra.Command, args []string) error {
Group: helmv2.GroupVersion.Group, Group: helmv2.GroupVersion.Group,
}, },
{ {
Kind: notificationv1b3.AlertKind, Kind: notificationv1b2.AlertKind,
Version: notificationv1b3.GroupVersion.Version, Version: notificationv1b2.GroupVersion.Version,
Group: notificationv1b3.GroupVersion.Group, Group: notificationv1b2.GroupVersion.Group,
}, },
{ {
Kind: notificationv1b3.ProviderKind, Kind: notificationv1b2.ProviderKind,
Version: notificationv1b3.GroupVersion.Version, Version: notificationv1b2.GroupVersion.Version,
Group: notificationv1b3.GroupVersion.Group, Group: notificationv1b2.GroupVersion.Group,
}, },
{ {
Kind: notificationv1.ReceiverKind, Kind: notificationv1.ReceiverKind,

View File

@@ -17,9 +17,18 @@ limitations under the License.
package main package main
import ( import (
"github.com/fluxcd/cli-utils/pkg/object" "context"
"fmt"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/cli-utils/pkg/object"
"github.com/fluxcd/pkg/apis/meta"
) )
// statusable is used to see if a resource is considered ready in the usual way // statusable is used to see if a resource is considered ready in the usual way
@@ -36,6 +45,42 @@ type oldConditions interface {
GetStatusConditions() *[]metav1.Condition GetStatusConditions() *[]metav1.Condition
} }
func statusableConditions(object statusable) []metav1.Condition {
if s, ok := object.(meta.ObjectWithConditions); ok {
return s.GetConditions()
}
if s, ok := object.(oldConditions); ok {
return *s.GetStatusConditions()
}
return []metav1.Condition{}
}
func isReady(kubeClient client.Client, namespacedName types.NamespacedName, object statusable) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) {
err := kubeClient.Get(ctx, namespacedName, object.asClientObject())
if err != nil {
return false, err
}
// Confirm the state we are observing is for the current generation
if object.GetGeneration() != object.getObservedGeneration() {
return false, nil
}
if c := apimeta.FindStatusCondition(statusableConditions(object), meta.ReadyCondition); c != nil {
switch c.Status {
case metav1.ConditionTrue:
return true, nil
case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message)
}
}
return false, nil
}
}
func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) { func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) {
var objRefs []object.ObjMetadata var objRefs []object.ObjMetadata
for _, deployment := range components { for _, deployment := range components {

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
) )
var suspendAlertCmd = &cobra.Command{ var suspendAlertCmd = &cobra.Command{

View File

@@ -1,56 +0,0 @@
/*
Copyright 2023 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 (
"github.com/spf13/cobra"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta3"
)
var suspendAlertProviderCmd = &cobra.Command{
Use: "alert-provider [name]",
Short: "Suspend reconciliation of Provider",
Long: `The suspend command disables the reconciliation of a Provider resource.`,
Example: ` # Suspend reconciliation for an existing Provider
flux suspend alert-provider main
# Suspend reconciliation for multiple Providers
flux suspend alert-providers main-1 main-2`,
ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
RunE: suspendCommand{
apiType: alertProviderType,
object: &alertProviderAdapter{&notificationv1.Provider{}},
list: &alertProviderListAdapter{&notificationv1.ProviderList{}},
}.run,
}
func init() {
suspendCmd.AddCommand(suspendAlertProviderCmd)
}
func (obj alertProviderAdapter) isSuspended() bool {
return obj.Provider.Spec.Suspend
}
func (obj alertProviderAdapter) setSuspended() {
obj.Provider.Spec.Suspend = true
}
func (a alertProviderListAdapter) item(i int) suspendable {
return &alertProviderAdapter{&a.ProviderList.Items[i]}
}

View File

@@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
) )
var suspendHrCmd = &cobra.Command{ var suspendHrCmd = &cobra.Command{

View File

@@ -1,3 +1,3 @@
► checking prerequisites ► checking prerequisites
✔ Kubernetes {{ .serverVersion }} >=1.26.0-0 ✔ Kubernetes {{ .serverVersion }} >=1.25.0-0
✔ prerequisites checks passed ✔ prerequisites checks passed

View File

@@ -1,5 +1,5 @@
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Alert kind: Alert
metadata: metadata:
name: flux-system name: flux-system

View File

@@ -1,5 +1,5 @@
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
name: flux-system name: flux-system

View File

@@ -4,7 +4,7 @@ kind: Namespace
metadata: metadata:
name: {{ .fluxns }} name: {{ .fluxns }}
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Provider kind: Provider
metadata: metadata:
name: slack name: slack
@@ -14,7 +14,7 @@ spec:
channel: 'A channel with spacess' channel: 'A channel with spacess'
address: https://hooks.slack.com/services/mock address: https://hooks.slack.com/services/mock
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Alert kind: Alert
metadata: metadata:
name: flux-system name: flux-system
@@ -124,7 +124,7 @@ spec:
timeout: 1m0s timeout: 1m0s
url: https://stefanprodan.github.io/podinfo url: https://stefanprodan.github.io/podinfo
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
name: flux-system name: flux-system

View File

@@ -1,5 +1,5 @@
--- ---
apiVersion: notification.toolkit.fluxcd.io/v1beta3 apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Provider kind: Provider
metadata: metadata:
name: slack name: slack

View File

@@ -1,2 +1,2 @@
NAME REVISION SUSPENDED READY MESSAGE NAME REVISION SUSPENDED READY MESSAGE
thrfg 6.3.5 False True Helm install succeeded for release thrfg-1/thrfg.v1 with chart podinfo@6.3.5 thrfg 6.3.5 False True Release reconciliation succeeded

View File

@@ -34,7 +34,7 @@ spec:
command: [ "echo hello world" ] command: [ "echo hello world" ]
image: busybox image: busybox
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
labels: labels:

View File

@@ -9,7 +9,7 @@ kind: Namespace
metadata: metadata:
name: {{ .ns }} name: {{ .ns }}
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
labels: labels:

View File

@@ -9,7 +9,7 @@ kind: Namespace
metadata: metadata:
name: {{ .ns }} name: {{ .ns }}
--- ---
apiVersion: helm.toolkit.fluxcd.io/v2beta2 apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease kind: HelmRelease
metadata: metadata:
labels: labels:

View File

@@ -33,14 +33,13 @@ import (
"k8s.io/cli-runtime/pkg/resource" "k8s.io/cli-runtime/pkg/resource"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" "github.com/fluxcd/flux2/v2/internal/utils"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
fluxmeta "github.com/fluxcd/pkg/apis/meta" fluxmeta "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/oci" "github.com/fluxcd/pkg/oci"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/flux2/v2/internal/utils"
) )
var traceCmd = &cobra.Command{ var traceCmd = &cobra.Command{
@@ -64,7 +63,7 @@ You can also trace multiple objects with different resource kinds using <resourc
# API Version and Kind can also be specified explicitly # API Version and Kind can also be specified explicitly
# Note that either both, kind and api-version, or neither have to be specified. # Note that either both, kind and api-version, or neither have to be specified.
flux trace redis --kind=helmrelease --api-version=helm.toolkit.fluxcd.io/v2beta2 -n redis`, flux trace redis --kind=helmrelease --api-version=helm.toolkit.fluxcd.io/v2beta1 -n redis`,
RunE: traceCmdRun, RunE: traceCmdRun,
} }

View File

@@ -47,7 +47,7 @@ func TestTrace(t *testing.T) {
}, },
{ {
"HelmRelease", "HelmRelease",
"trace podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta2", "trace podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta1",
"testdata/trace/helmrelease.yaml", "testdata/trace/helmrelease.yaml",
"testdata/trace/helmrelease.golden", "testdata/trace/helmrelease.golden",
map[string]string{ map[string]string{
@@ -59,7 +59,7 @@ func TestTrace(t *testing.T) {
}, },
{ {
"HelmRelease from OCI registry", "HelmRelease from OCI registry",
"trace podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta2", "trace podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta1",
"testdata/trace/helmrelease-oci.yaml", "testdata/trace/helmrelease-oci.yaml",
"testdata/trace/helmrelease-oci.golden", "testdata/trace/helmrelease-oci.golden",
map[string]string{ map[string]string{

View File

@@ -32,11 +32,10 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
"github.com/fluxcd/cli-utils/pkg/object" "github.com/fluxcd/cli-utils/pkg/object"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/ssa" "github.com/fluxcd/pkg/ssa"
@@ -209,16 +208,27 @@ func getHelmReleaseInventory(ctx context.Context, objectKey client.ObjectKey, ku
return nil, nil return nil, nil
} }
storageNamespace := hr.Status.StorageNamespace storageNamespace := hr.GetNamespace()
latest := hr.Status.History.Latest() if hr.Spec.StorageNamespace != "" {
if len(storageNamespace) == 0 || latest == nil { storageNamespace = hr.Spec.StorageNamespace
// Skip release if it has no current }
storageName := hr.GetName()
if hr.Spec.ReleaseName != "" {
storageName = hr.Spec.ReleaseName
} else if hr.Spec.TargetNamespace != "" {
storageName = strings.Join([]string{hr.Spec.TargetNamespace, hr.Name}, "-")
}
storageVersion := hr.Status.LastReleaseRevision
// skip release if it failed to install
if storageVersion < 1 {
return nil, nil return nil, nil
} }
storageKey := client.ObjectKey{ storageKey := client.ObjectKey{
Namespace: storageNamespace, Namespace: storageNamespace,
Name: fmt.Sprintf("sh.helm.release.v1.%s.v%v", latest.Name, latest.Version), Name: fmt.Sprintf("sh.helm.release.v1.%s.v%v", storageName, storageVersion),
} }
storageSecret := &corev1.Secret{} storageSecret := &corev1.Secret{}
@@ -269,8 +279,12 @@ func getHelmReleaseInventory(ctx context.Context, objectKey client.ObjectKey, ku
// set the namespace on namespaced objects // set the namespace on namespaced objects
for _, obj := range objects { for _, obj := range objects {
if obj.GetNamespace() == "" { if obj.GetNamespace() == "" {
if isNamespaced, _ := apiutil.IsObjectNamespaced(obj, kubeClient.Scheme(), kubeClient.RESTMapper()); isNamespaced { if isNamespaced, _ := utils.IsAPINamespaced(obj, kubeClient.Scheme(), kubeClient.RESTMapper()); isNamespaced {
obj.SetNamespace(latest.Namespace) if hr.Spec.TargetNamespace != "" {
obj.SetNamespace(hr.Spec.TargetNamespace)
} else {
obj.SetNamespace(hr.GetNamespace())
}
} }
} }
} }

View File

@@ -25,9 +25,8 @@ import (
"github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/name"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml/goyaml.v2" "sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
"github.com/fluxcd/flux2/v2/pkg/manifestgen" "github.com/fluxcd/flux2/v2/pkg/manifestgen"
@@ -56,12 +55,6 @@ type versionFlags struct {
var versionArgs versionFlags var versionArgs versionFlags
type versionInfo struct {
Flux string `yaml:"flux"`
Distribution string `yaml:"distribution,omitempty"`
Controller map[string]string `yaml:"controller,inline"`
}
func init() { func init() {
versionCmd.Flags().BoolVar(&versionArgs.client, "client", false, versionCmd.Flags().BoolVar(&versionArgs.client, "client", false,
"print only client version") "print only client version")
@@ -78,12 +71,8 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel() defer cancel()
// versionInfo struct and goyaml is used because we care about the order. info := map[string]string{}
// Without this `distribution` is printed before `flux` when the struct is marshalled. info["flux"] = rootArgs.defaults.Version
info := &versionInfo{
Controller: map[string]string{},
}
info.Flux = rootArgs.defaults.Version
if !versionArgs.client { if !versionArgs.client {
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions) kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
@@ -91,16 +80,6 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
return err return err
} }
clusterInfo, err := getFluxClusterInfo(ctx, kubeClient)
// ignoring not found errors because it means that the GitRepository CRD isn't installed but a user might
// have other controllers(e.g notification-controller), and we want to still return information for them.
if err != nil && !errors.IsNotFound(err) {
return err
}
if clusterInfo.distribution() != "" {
info.Distribution = clusterInfo.distribution()
}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue} selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list v1.DeploymentList var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err != nil { if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err != nil {
@@ -117,7 +96,7 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
info.Controller[name] = tag info[name] = tag
} }
} }
} }
@@ -126,7 +105,7 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
var err error var err error
if versionArgs.output == "json" { if versionArgs.output == "json" {
marshalled, err = info.toJSON() marshalled, err = json.MarshalIndent(&info, "", " ")
marshalled = append(marshalled, "\n"...) marshalled = append(marshalled, "\n"...)
} else { } else {
marshalled, err = yaml.Marshal(&info) marshalled, err = yaml.Marshal(&info)
@@ -140,20 +119,6 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (info versionInfo) toJSON() ([]byte, error) {
mapInfo := map[string]string{
"flux": info.Flux,
}
if info.Distribution != "" {
mapInfo["distribution"] = info.Distribution
}
for k, v := range info.Controller {
mapInfo[k] = v
}
return json.MarshalIndent(&mapInfo, "", " ")
}
func splitImageStr(image string) (string, string, error) { func splitImageStr(image string) (string, string, error) {
ref, err := name.ParseReference(image) ref, err := name.ParseReference(image)
if err != nil { if err != nil {

122
go.mod
View File

@@ -10,32 +10,32 @@ require (
github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e
github.com/cyphar/filepath-securejoin v0.2.4 github.com/cyphar/filepath-securejoin v0.2.4
github.com/distribution/distribution/v3 v3.0.0-20230823142118-4f7424c8eb41 github.com/distribution/distribution/v3 v3.0.0-20230823142118-4f7424c8eb41
github.com/fluxcd/cli-utils v0.36.0-flux.2 github.com/fluxcd/cli-utils v0.36.0-flux.1
github.com/fluxcd/go-git-providers v0.19.2 github.com/fluxcd/go-git-providers v0.19.1
github.com/fluxcd/helm-controller/api v0.37.1 github.com/fluxcd/helm-controller/api v0.36.2
github.com/fluxcd/image-automation-controller/api v0.37.0 github.com/fluxcd/image-automation-controller/api v0.36.1
github.com/fluxcd/image-reflector-controller/api v0.31.1 github.com/fluxcd/image-reflector-controller/api v0.30.0
github.com/fluxcd/kustomize-controller/api v1.2.1 github.com/fluxcd/kustomize-controller/api v1.1.1
github.com/fluxcd/notification-controller/api v1.2.3 github.com/fluxcd/notification-controller/api v1.1.0
github.com/fluxcd/pkg/apis/event v0.6.0 github.com/fluxcd/pkg/apis/event v0.6.0
github.com/fluxcd/pkg/apis/meta v1.2.0 github.com/fluxcd/pkg/apis/meta v1.2.0
github.com/fluxcd/pkg/git v0.16.0 github.com/fluxcd/pkg/git v0.15.0
github.com/fluxcd/pkg/git/gogit v0.16.1 github.com/fluxcd/pkg/git/gogit v0.15.0
github.com/fluxcd/pkg/kustomize v1.5.0 github.com/fluxcd/pkg/kustomize v1.4.0
github.com/fluxcd/pkg/oci v0.33.3 github.com/fluxcd/pkg/oci v0.33.0
github.com/fluxcd/pkg/runtime v0.43.2 github.com/fluxcd/pkg/runtime v0.43.0
github.com/fluxcd/pkg/sourceignore v0.4.0 github.com/fluxcd/pkg/sourceignore v0.3.5
github.com/fluxcd/pkg/ssa v0.35.0 github.com/fluxcd/pkg/ssa v0.34.0
github.com/fluxcd/pkg/ssh v0.10.0 github.com/fluxcd/pkg/ssh v0.9.0
github.com/fluxcd/pkg/tar v0.4.0 github.com/fluxcd/pkg/tar v0.4.0
github.com/fluxcd/pkg/version v0.2.2 github.com/fluxcd/pkg/version v0.2.2
github.com/fluxcd/source-controller/api v1.2.3 github.com/fluxcd/source-controller/api v1.1.2
github.com/go-git/go-git/v5 v5.11.0 github.com/go-git/go-git/v5 v5.10.0
github.com/go-logr/logr v1.3.0 github.com/go-logr/logr v1.3.0
github.com/gonvenience/bunt v1.3.5 github.com/gonvenience/bunt v1.3.5
github.com/gonvenience/ytbx v1.4.4 github.com/gonvenience/ytbx v1.4.4
github.com/google/go-cmp v0.6.0 github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.17.0 github.com/google/go-containerregistry v0.16.1
github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-cleanhttp v0.5.2
github.com/homeport/dyff v1.6.0 github.com/homeport/dyff v1.6.0
github.com/lucasb-eyer/go-colorful v1.2.0 github.com/lucasb-eyer/go-colorful v1.2.0
@@ -47,8 +47,8 @@ require (
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/theckman/yacspin v0.13.12 github.com/theckman/yacspin v0.13.12
golang.org/x/crypto v0.16.0 golang.org/x/crypto v0.15.0
golang.org/x/term v0.15.0 golang.org/x/term v0.14.0
golang.org/x/text v0.14.0 golang.org/x/text v0.14.0
k8s.io/api v0.28.4 k8s.io/api v0.28.4
k8s.io/apiextensions-apiserver v0.28.4 k8s.io/apiextensions-apiserver v0.28.4
@@ -57,36 +57,36 @@ require (
k8s.io/client-go v0.28.4 k8s.io/client-go v0.28.4
k8s.io/kubectl v0.28.4 k8s.io/kubectl v0.28.4
sigs.k8s.io/controller-runtime v0.16.3 sigs.k8s.io/controller-runtime v0.16.3
sigs.k8s.io/kustomize/api v0.16.0 sigs.k8s.io/kustomize/api v0.15.0
sigs.k8s.io/kustomize/kyaml v0.16.0 sigs.k8s.io/kustomize/kyaml v0.15.0
sigs.k8s.io/yaml v1.4.0 sigs.k8s.io/yaml v1.4.0
) )
require ( require (
code.gitea.io/sdk/gitea v0.17.0 // indirect code.gitea.io/sdk/gitea v0.16.0 // indirect
dario.cat/mergo v1.0.0 // indirect dario.cat/mergo v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect github.com/aws/aws-sdk-go-v2 v1.21.0 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect github.com/aws/aws-sdk-go-v2/config v1.18.36 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.5 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.19.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect
github.com/aws/smithy-go v1.19.0 // indirect github.com/aws/smithy-go v1.14.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -114,14 +114,14 @@ require (
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.2.0 // indirect github.com/fluxcd/pkg/apis/kustomize v1.2.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect github.com/go-errors/errors v1.4.2 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@@ -133,7 +133,7 @@ require (
github.com/gonvenience/wrap v1.1.2 // indirect github.com/gonvenience/wrap v1.1.2 // indirect
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-github/v57 v57.0.0 // indirect github.com/google/go-github/v55 v55.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
@@ -144,10 +144,10 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/go-version v1.5.0 // indirect
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -191,30 +191,30 @@ require (
github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect github.com/vbatts/tar-split v0.11.3 // indirect
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect
github.com/xanzy/go-gitlab v0.95.1 // indirect github.com/xanzy/go-gitlab v0.93.1 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/mod v0.14.0 // indirect golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect golang.org/x/net v0.18.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/oauth2 v0.14.0 // indirect
golang.org/x/sync v0.5.0 // indirect golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect golang.org/x/sys v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.4.0 // indirect
golang.org/x/tools v0.16.0 // indirect golang.org/x/tools v0.15.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.8 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/evanphx/json-patch.v5 v5.7.0 // indirect gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.28.4 // indirect k8s.io/component-base v0.28.4 // indirect
k8s.io/klog/v2 v2.110.1 // indirect k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 // indirect k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e // indirect
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
) )

312
go.sum
View File

@@ -1,18 +1,20 @@
code.gitea.io/sdk/gitea v0.17.0 h1:8JPBss4+Jf7AE1YcfyiGrngTXE8dFSG3si/bypsTH34= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
code.gitea.io/sdk/gitea v0.17.0/go.mod h1:ndkDk99BnfiUCCYEUhpNzi0lpmApXlwRFqClBlOlEBg= code.gitea.io/sdk/gitea v0.16.0 h1:gAfssETO1Hv9QbE+/nhWu7EjoFQYKt6kPoyDytQgw00=
code.gitea.io/sdk/gitea v0.16.0/go.mod h1:ndkDk99BnfiUCCYEUhpNzi0lpmApXlwRFqClBlOlEBg=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 h1:LNHhpdK7hzUcx/k1LIcuh5k7k1LGIWLQfCjaneSj7Fc=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1/go.mod h1:uE9zaUfEQT/nbQjVi2IblCG9iaLtZsuYZ8ne+PuQ02M=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 h1:d81/ng9rET2YqdVkVwkb6EXeRrLJIwyGnJcAlAWKwhs= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
@@ -25,38 +27,38 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e h1:NfjGPY2A8SSRJvXny111ZPoB57LT5lWgX4XiUjW10eY= github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e h1:NfjGPY2A8SSRJvXny111ZPoB57LT5lWgX4XiUjW10eY=
github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e/go.mod h1:K4vciqCJaZ1Ghw/SvtJbEAM4soEtwDCNVqkdQIIujwU= github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e/go.mod h1:K4vciqCJaZ1Ghw/SvtJbEAM4soEtwDCNVqkdQIIujwU=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk= github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc=
github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M=
github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.18.36 h1:mLNA12PWU1Y+ueOO79QgQfKIPhc1MYKl44RmvASkJ7Q=
github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= github.com/aws/aws-sdk-go-v2/config v1.18.36/go.mod h1:8AnEFxW9/XGKCbjYDCJy7iltVNyEI9Iu9qC21UzhhgQ=
github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.13.35 h1:QpsNitYJu0GgvMBLUIYu9H4yryA5kMksjeIVQfgXrt8=
github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= github.com/aws/aws-sdk-go-v2/credentials v1.13.35/go.mod h1:o7rCaLtvK0hUggAGclf76mNGGkaG5a9KWlp+d9IpcV8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 h1:GPUcE/Yq7Ur8YSUk6lVkoIMWnJNO0HT18GUzCWCgCI0=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo=
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.5 h1:wLPDAUFT50NEXGXpywRU3AA74pg35RJjWol/68ruvQQ= github.com/aws/aws-sdk-go-v2/service/ecr v1.19.5 h1:hg2/a7rE9dwYr+/DPNzHQ+IsHXLNt1NsQVUecBtA8os=
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.5/go.mod h1:AOHmGMoPtSY9Zm2zBuwUJQBisIvYAZeA1n7b6f4e880= github.com/aws/aws-sdk-go-v2/service/ecr v1.19.5/go.mod h1:pGwmNL8hN0jpBfKfTbmu+Rl0bJkDhaGl+9PQLrZ4KLo=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJR8CSImIVCONRi4g0Su3J+TSTbS7G0pUeMU= github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 h1:oCvTFSDi67AX0pOX3PuPdGFewvLRU2zzFSrTsgURNo0=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/sso v1.13.5/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 h1:dnInJb4S0oy8aQuri1mV6ipLlnZPfnsDNB9BGO9PDNY=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvTZW2S44Lt9Mk2aYQ=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -64,6 +66,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
@@ -74,6 +77,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
@@ -115,6 +119,8 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc=
@@ -126,21 +132,21 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxcd/cli-utils v0.36.0-flux.2 h1:7nlXfAJ7iaDF34IdbyId+wBf7beL2qvzDBLmVBJSDVo= github.com/fluxcd/cli-utils v0.36.0-flux.1 h1:004HtB/p47xqkTCGZhc1vVuXNzef7+N3wT364eFk7WA=
github.com/fluxcd/cli-utils v0.36.0-flux.2/go.mod h1:TQtgRf9OjQBzE5FJ9UDV6WNz9Po3pzAtk3NQmQEN5l8= github.com/fluxcd/cli-utils v0.36.0-flux.1/go.mod h1:c+uMMDqGg8WKwBNeWKDDFEuDDHICDWAHthzosAKF2PA=
github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg=
github.com/fluxcd/go-git-providers v0.19.2 h1:G/O0z4WUlgChV6o3YrZ1GP1ZgZSd8ZJWACIW0ICqxMo= github.com/fluxcd/go-git-providers v0.19.1 h1:LXRFpHdPCmO+Uegw2MvAU3KiEHn1PRV2c//ii/HhpeY=
github.com/fluxcd/go-git-providers v0.19.2/go.mod h1:V44pmhFqoZ8heFJEBU1PS+OHTwLWOfoj0nKpFAqik6Y= github.com/fluxcd/go-git-providers v0.19.1/go.mod h1:eN0JpfkQqS/6yJ1I6DW3z1XLCC2JZK+55Ues+0Ur3Ds=
github.com/fluxcd/helm-controller/api v0.37.1 h1:cDUX79wGpNoSrDgirQswdN8X6gKmWVrpMMBn1BKdXAc= github.com/fluxcd/helm-controller/api v0.36.2 h1:9JaTc91yocG1oQkM/GMfpZ/nGPpliRjZBNwyAsW5584=
github.com/fluxcd/helm-controller/api v0.37.1/go.mod h1:BuXZhAX9blQviil6yUN5zNM4RB753yhyBTJXxXff7Mo= github.com/fluxcd/helm-controller/api v0.36.2/go.mod h1:zkcRy3PxG0NoxSY5SjiSA5tWOGa6spIbWsChQY8FXqM=
github.com/fluxcd/image-automation-controller/api v0.37.0 h1:0L8kzX3zaYfg4wQ2Mx3G56atLMNeDGjy5qMGP4tDKRs= github.com/fluxcd/image-automation-controller/api v0.36.1 h1:Knd4SSm/bJ0iqvYcQq87uDaT/mW9poM1jOvHpJ/4tzk=
github.com/fluxcd/image-automation-controller/api v0.37.0/go.mod h1:B2EbmiY69mE2bGOENPNUXr6klwrVe7FwVoB2iE1q08E= github.com/fluxcd/image-automation-controller/api v0.36.1/go.mod h1:IsjdBtgm71KHRGDTZZZiGYdWGoJ5VjenE9F4ueADM/o=
github.com/fluxcd/image-reflector-controller/api v0.31.1 h1:nc44G0JjLgSvqglJSiXQJZcrRw+eY01j7fHRUDB3FMw= github.com/fluxcd/image-reflector-controller/api v0.30.0 h1:DiWj+4tcbnaSqZs1Pfkyt3uSy47wg3dsNMgbFE50pYc=
github.com/fluxcd/image-reflector-controller/api v0.31.1/go.mod h1:KopMbC92Cw2ypZZeMytzTLr3EfOj2hoL6MizrdpBDhc= github.com/fluxcd/image-reflector-controller/api v0.30.0/go.mod h1:hv57KwIzoPyy7Vu4PFcIf21eu0N3p/HbijygcuNgf8c=
github.com/fluxcd/kustomize-controller/api v1.2.1 h1:+WgQOU7jpqz9bA4djPWmaeYAp9cG7c/TdcIYku3Jrzk= github.com/fluxcd/kustomize-controller/api v1.1.1 h1:pQcAzvBC3cFGOCgk0zrcsO1Kjtal1tvd6rHXkyp2R78=
github.com/fluxcd/kustomize-controller/api v1.2.1/go.mod h1:0Kgc4uYnr5jCm4H8JwArkR0v4WTmXeX/9KgoDbxluVc= github.com/fluxcd/kustomize-controller/api v1.1.1/go.mod h1:FHJTX6c0+CznUNGMol5+Uc4lQsYRxWgpmIRK/xDCghA=
github.com/fluxcd/notification-controller/api v1.2.3 h1:vXVMg2PmTjmRC5+ULZfbmBEm/CsJaM9yjNJzRdI0JMs= github.com/fluxcd/notification-controller/api v1.1.0 h1:qx5t5DmArfPLxG2bsYZXIqDXLnijUddlHeRfciALwQw=
github.com/fluxcd/notification-controller/api v1.2.3/go.mod h1:A0VkH3mswQAeGKsmzq81jAUN+zNJt9SPXjwe8mvnnaw= github.com/fluxcd/notification-controller/api v1.1.0/go.mod h1:6MqWVQeI5yrYR7zp0GFqsfXitNPGJrnfOWxO2w3jylg=
github.com/fluxcd/pkg/apis/acl v0.1.0 h1:EoAl377hDQYL3WqanWCdifauXqXbMyFuK82NnX6pH4Q= github.com/fluxcd/pkg/apis/acl v0.1.0 h1:EoAl377hDQYL3WqanWCdifauXqXbMyFuK82NnX6pH4Q=
github.com/fluxcd/pkg/apis/acl v0.1.0/go.mod h1:zfEZzz169Oap034EsDhmCAGgnWlcWmIObZjYMusoXS8= github.com/fluxcd/pkg/apis/acl v0.1.0/go.mod h1:zfEZzz169Oap034EsDhmCAGgnWlcWmIObZjYMusoXS8=
github.com/fluxcd/pkg/apis/event v0.6.0 h1:AUaeee1CGWb65BLqVximHXG8Gcu6vWuYONIq6tVpjgo= github.com/fluxcd/pkg/apis/event v0.6.0 h1:AUaeee1CGWb65BLqVximHXG8Gcu6vWuYONIq6tVpjgo=
@@ -149,34 +155,34 @@ github.com/fluxcd/pkg/apis/kustomize v1.2.0 h1:vkVs+OumxaWso0jNCqdgFFfMHdh+qtZhy
github.com/fluxcd/pkg/apis/kustomize v1.2.0/go.mod h1:VF7tR/WuVFeum+HaMTHwp+eCtsHiiQlY6ihgqtAnW/M= github.com/fluxcd/pkg/apis/kustomize v1.2.0/go.mod h1:VF7tR/WuVFeum+HaMTHwp+eCtsHiiQlY6ihgqtAnW/M=
github.com/fluxcd/pkg/apis/meta v1.2.0 h1:O766PzGAdMdQKybSflGL8oV0+GgCNIkdsxfalRyzeO8= github.com/fluxcd/pkg/apis/meta v1.2.0 h1:O766PzGAdMdQKybSflGL8oV0+GgCNIkdsxfalRyzeO8=
github.com/fluxcd/pkg/apis/meta v1.2.0/go.mod h1:fU/Az9AoVyIxC0oI4ihG0NVMNnvrcCzdEym3wxjIQsc= github.com/fluxcd/pkg/apis/meta v1.2.0/go.mod h1:fU/Az9AoVyIxC0oI4ihG0NVMNnvrcCzdEym3wxjIQsc=
github.com/fluxcd/pkg/git v0.16.0 h1:xgfMpgsVaxGLechKNaSUif9jnt2Ji/HkwIwxXeDoADk= github.com/fluxcd/pkg/git v0.15.0 h1:QPqv+b4sQXXpWQhigf/sPE5qzK4BrQhkltnYuEy4AYw=
github.com/fluxcd/pkg/git v0.16.0/go.mod h1:ZsaxXDBHIUjNeRf+3qDGyHD22KpqbjuNPCbHy2Xid5U= github.com/fluxcd/pkg/git v0.15.0/go.mod h1:zqmLfw4d+mS77bMRkeQ+8dmFSgxB/c2ZDkafIyY6bAQ=
github.com/fluxcd/pkg/git/gogit v0.16.1 h1:byimVk7VLbERRxJDkVktithN03GC0y7fyc8Ur9Uka8U= github.com/fluxcd/pkg/git/gogit v0.15.0 h1:GV8XaRp7CtlRuDallrJgMR6s1YHIMZi5+zyXMOJsS0c=
github.com/fluxcd/pkg/git/gogit v0.16.1/go.mod h1:nx3PumOFe5e3fMsh2HPLSlAeOk2wC+jVg7H9BTRKEmg= github.com/fluxcd/pkg/git/gogit v0.15.0/go.mod h1:9KBhXE1czARGT6QqHYVMfr2RbvPpguKwCdm4LgkP3nY=
github.com/fluxcd/pkg/gittestserver v0.9.0 h1:OthMahtKmmpwCRw8LmSGrceqVhHywGg/QiytxHGSgeY= github.com/fluxcd/pkg/gittestserver v0.8.6 h1:YM8prVKB3LC9LBBe+a2p7l1BlfV9erXCgC1em9sbqW4=
github.com/fluxcd/pkg/kustomize v1.5.0 h1:Q2kynQzF4coKlOJq/XaLM+gVmVloaInkoa+vsor6Hho= github.com/fluxcd/pkg/kustomize v1.4.0 h1:1c9dwLkccFGEVkE+CvCYqybtBoInYq6OePTkkgTfLzQ=
github.com/fluxcd/pkg/kustomize v1.5.0/go.mod h1:QgFwpteTedb7oio5+yN+h+rhSgm253OIjmtoTow+a5c= github.com/fluxcd/pkg/kustomize v1.4.0/go.mod h1:o0UgMmAjyCwsUSdBIDJ9NgXfOEJ6Iojs5PQ2agIRapc=
github.com/fluxcd/pkg/oci v0.33.3 h1:dj5IuF2O9/0r37tOWoOoKX/0emytjEiJ6sXy9FUkHww= github.com/fluxcd/pkg/oci v0.33.0 h1:OC9eJzazldcUAyWS5Ul1XvUISpfJBRzDZqLjYyyNG2g=
github.com/fluxcd/pkg/oci v0.33.3/go.mod h1:6+vIgdqP6AkFitvlyGx2W9f4s8q5Oguw9SNeN494MCY= github.com/fluxcd/pkg/oci v0.33.0/go.mod h1:XNxj6Pr1ddmC5EVSo+R3Nlr5droAV0LxZ9HJ3V1GNwI=
github.com/fluxcd/pkg/runtime v0.43.2 h1:xH2BvttUqJ7wS0zjuBETr2pLXG62QY6f0mdxg5UQKio= github.com/fluxcd/pkg/runtime v0.43.0 h1:dU4cWct5VTpddGzJUU80zxNl80jbbVEN5Y5rbt4YUnw=
github.com/fluxcd/pkg/runtime v0.43.2/go.mod h1:dhhNV45B3tekg7qPzATFTuWOulvUzMoO1bV+vc2pSts= github.com/fluxcd/pkg/runtime v0.43.0/go.mod h1:RuqJ9VEXELjzgurK2+UXBBgVN1vS0hZ7CYVG2xBAEVM=
github.com/fluxcd/pkg/sourceignore v0.4.0 h1:99Ikoi8qMirlBK4yjnoKa5vx9YFQ/BSSK3Axi+yDg9s= github.com/fluxcd/pkg/sourceignore v0.3.5 h1:omcHTH5X5tlPr9w1b9T7WuJTOP+o/KdVdarYb4kgkCU=
github.com/fluxcd/pkg/sourceignore v0.4.0/go.mod h1:j1BRQE+R0TJmPYPUnEd/0gm8KcpajlX6mDv3z7s8YFQ= github.com/fluxcd/pkg/sourceignore v0.3.5/go.mod h1:6Xz3jErz8RsidsdrjUBBUGKes24rbdp/F38MnTGibEw=
github.com/fluxcd/pkg/ssa v0.35.0 h1:8T3WY4P9SQWApa2hq1rU1u2WE8oqP3MMTsAiEWwhmfo= github.com/fluxcd/pkg/ssa v0.34.0 h1:hpMo0D7G3faieRYH39e9YD8Jl+aC2hTgUep8ojG5+LE=
github.com/fluxcd/pkg/ssa v0.35.0/go.mod h1:rhVh0EtYVUOznKXlz6E7JOSgdc8xWbIwA4L5HVtJRLA= github.com/fluxcd/pkg/ssa v0.34.0/go.mod h1:rhVh0EtYVUOznKXlz6E7JOSgdc8xWbIwA4L5HVtJRLA=
github.com/fluxcd/pkg/ssh v0.10.0 h1:JFz0u/CPEf3hXvmrEvUvXsc70eKh8xphqjXxZuSby9g= github.com/fluxcd/pkg/ssh v0.9.0 h1:egRvg4AKarObFKXsBDZ5oBZ5PCjmQ4Q6hX+6GmrdbH0=
github.com/fluxcd/pkg/ssh v0.10.0/go.mod h1:1lFTj3MhU9xQuaJ5PJJoh/FyRYzK54ll9NY/s2KqOZM= github.com/fluxcd/pkg/ssh v0.9.0/go.mod h1:3KKbfcFn4l+HqYdHKqcu2LO8RvFv0Kh6tYRSUtONC/8=
github.com/fluxcd/pkg/tar v0.4.0 h1:SuXpfXBIcSJ5R/yqQi2CBxBmV/i/LH0agqNAh2PWBZg= github.com/fluxcd/pkg/tar v0.4.0 h1:SuXpfXBIcSJ5R/yqQi2CBxBmV/i/LH0agqNAh2PWBZg=
github.com/fluxcd/pkg/tar v0.4.0/go.mod h1:SyJBaQvuv2VA/rv4d1OHhCV6R8+9QKc9np193EzNHBc= github.com/fluxcd/pkg/tar v0.4.0/go.mod h1:SyJBaQvuv2VA/rv4d1OHhCV6R8+9QKc9np193EzNHBc=
github.com/fluxcd/pkg/version v0.2.2 h1:ZpVXECeLA5hIQMft11iLp6gN3cKcz6UNuVTQPw/bRdI= github.com/fluxcd/pkg/version v0.2.2 h1:ZpVXECeLA5hIQMft11iLp6gN3cKcz6UNuVTQPw/bRdI=
github.com/fluxcd/pkg/version v0.2.2/go.mod h1:NGnh/no8S6PyfCDxRFrPY3T5BUnqP48MxfxNRU0z8C0= github.com/fluxcd/pkg/version v0.2.2/go.mod h1:NGnh/no8S6PyfCDxRFrPY3T5BUnqP48MxfxNRU0z8C0=
github.com/fluxcd/source-controller/api v1.2.3 h1:71mXv3Qg9HEhcpqOq1ObmoE+P/HuZNaAvxfI7dqZMo8= github.com/fluxcd/source-controller/api v1.1.2 h1:FfKDKVWnopo+Q2pOAxgHEjrtr4MP41L8aapR4mqBhBk=
github.com/fluxcd/source-controller/api v1.2.3/go.mod h1:5gaIVVH7hgb8p3HKFp8P6hGmZEC8fKSt4EcrG3g5vZI= github.com/fluxcd/source-controller/api v1.1.2/go.mod h1:ZLkaUd1KQIjtLPCvO63Ni5zpnSTVBAkeRgFBzMItbDQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
@@ -184,22 +190,21 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= github.com/go-git/go-git/v5 v5.10.0 h1:F0x3xXrAWmhwtzoCokU4IMPcBdncG+HAAqi9FcOOjbQ=
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-git/go-git/v5 v5.10.0/go.mod h1:1FOZ/pQnqw24ghP2n7cunVl0ON55BsjPYvhWHvZGhoo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
@@ -208,13 +213,20 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
@@ -237,15 +249,20 @@ github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvR
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.17.0 h1:5p+zYs/R4VGHkhyvgWurWrpJ2hW4Vv9fQI+GzdcwXLk= github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
github.com/google/go-containerregistry v0.17.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg=
github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -274,17 +291,16 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/homeport/dyff v1.6.0 h1:AN+ikld0Fy+qx34YE7655b/bpWuxS6cL9k852pE2GUc= github.com/homeport/dyff v1.6.0 h1:AN+ikld0Fy+qx34YE7655b/bpWuxS6cL9k852pE2GUc=
github.com/homeport/dyff v1.6.0/go.mod h1:FlAOFYzeKvxmU5nTrnG+qrlJVWpsFew7pt8L99p5q8k= github.com/homeport/dyff v1.6.0/go.mod h1:FlAOFYzeKvxmU5nTrnG+qrlJVWpsFew7pt8L99p5q8k=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -325,6 +341,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk=
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -370,7 +388,7 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -398,6 +416,7 @@ github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -451,8 +470,8 @@ github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RV
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo=
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c=
github.com/xanzy/go-gitlab v0.95.1 h1:rQjcmX5Au2Lz9bc3QLTdtSK5ZHdTXLnmhz3CAB/G5So= github.com/xanzy/go-gitlab v0.93.1 h1:f7J33cw/P9b/8paIOoH0F3H+TFrswvWHs6yUgoTp9LY=
github.com/xanzy/go-gitlab v0.95.1/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/go-gitlab v0.93.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
@@ -460,9 +479,9 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.starlark.net v0.0.0-20231121155337-90ade8b19d09 h1:hzy3LFnSN8kuQK8h9tHl4ndF6UruMj47OqwqsS+/Ai4= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
go.starlark.net v0.0.0-20231121155337-90ade8b19d09/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -475,18 +494,27 @@ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -497,10 +525,12 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -510,6 +540,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -532,48 +563,70 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
@@ -583,8 +636,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v5 v5.7.0 h1:dGKGylPlZ/jus2g1YqhhyzfH0gPy2R8/MYUpW/OslTY= gopkg.in/evanphx/json-patch.v5 v5.6.0 h1:BMT6KIwBD9CaU91PJCZIe46bDmBWa9ynTQgJIOpfQBk=
gopkg.in/evanphx/json-patch.v5 v5.7.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk= gopkg.in/evanphx/json-patch.v5 v5.6.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -597,7 +650,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU=
@@ -610,22 +666,22 @@ k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo=
k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU=
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 h1:vzKzxN5uyJZLY8HL1/OovW7BJefnsBIWt8T7Gjh2boQ= k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e h1:snPmy96t93RredGRjKfMFt+gvxuVAncqSAyBveJtr4Q=
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ= k8s.io/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ=
k8s.io/kubectl v0.28.4/go.mod h1:CKOccVx3l+3MmDbkXtIUtibq93nN2hkDR99XDCn7c/c= k8s.io/kubectl v0.28.4/go.mod h1:CKOccVx3l+3MmDbkXtIUtibq93nN2hkDR99XDCn7c/c=
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g= sigs.k8s.io/kustomize/api v0.15.0 h1:6Ca88kEOBVotHDw+y2IsIMYtg9Pvv7MKpW9JMyF/OH4=
sigs.k8s.io/kustomize/api v0.16.0/go.mod h1:MnFZ7IP2YqVyVwMWoRxPtgl/5hpA+eCCrQR/866cm5c= sigs.k8s.io/kustomize/api v0.15.0/go.mod h1:p19kb+E14gN7zcIBR/nhByJDAfUa7N8mp6ZdH/mMXbg=
sigs.k8s.io/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= sigs.k8s.io/kustomize/kyaml v0.15.0 h1:ynlLMAxDhrY9otSg5GYE2TcIz31XkGZ2Pkj7SdolD84=
sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= sigs.k8s.io/kustomize/kyaml v0.15.0/go.mod h1:+uMkBahdU1KNOj78Uta4rrXH+iH7wvg+nW7+GULvREA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=

View File

@@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"strings" "strings"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
) )

View File

@@ -0,0 +1,63 @@
/*
Copyright 2023 The Flux authors
Copyright 2018 The Kubernetes 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.
*/
// TODO: Remove this when
// https://github.com/kubernetes-sigs/controller-runtime/blob/c783d2527a7da76332a2d8d563a6ca0b80c12122/pkg/client/apiutil/apimachinery.go#L76-L104
// is included in a semver release.
package utils
import (
"errors"
"fmt"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
)
// IsAPINamespaced returns true if the object is namespace scoped.
// For unstructured objects the gvk is found from the object itself.
func IsAPINamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) {
gvk, err := apiutil.GVKForObject(obj, scheme)
if err != nil {
return false, err
}
return IsAPINamespacedWithGVK(gvk, scheme, restmapper)
}
// IsAPINamespacedWithGVK returns true if the object having the provided
// GVK is namespace scoped.
func IsAPINamespacedWithGVK(gk schema.GroupVersionKind, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) {
restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gk.Group, Kind: gk.Kind})
if err != nil {
return false, fmt.Errorf("failed to get restmapping: %w", err)
}
scope := restmapping.Scope.Name()
if scope == "" {
return false, errors.New("scope cannot be identified, empty scope returned")
}
if scope != apimeta.RESTScopeNameRoot {
return true, nil
}
return false, nil
}

View File

@@ -41,12 +41,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta2" helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
imageautov1 "github.com/fluxcd/image-automation-controller/api/v1beta1" imageautov1 "github.com/fluxcd/image-automation-controller/api/v1beta1"
imagereflectv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2" imagereflectv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1" notificationv1 "github.com/fluxcd/notification-controller/api/v1"
notificationv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" notificationv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
runclient "github.com/fluxcd/pkg/runtime/client" runclient "github.com/fluxcd/pkg/runtime/client"
"github.com/fluxcd/pkg/version" "github.com/fluxcd/pkg/version"
@@ -133,7 +133,7 @@ func NewScheme() *apiruntime.Scheme {
_ = kustomizev1.AddToScheme(scheme) _ = kustomizev1.AddToScheme(scheme)
_ = helmv2.AddToScheme(scheme) _ = helmv2.AddToScheme(scheme)
_ = notificationv1.AddToScheme(scheme) _ = notificationv1.AddToScheme(scheme)
_ = notificationv1b3.AddToScheme(scheme) _ = notificationv1b2.AddToScheme(scheme)
_ = imagereflectv1.AddToScheme(scheme) _ = imagereflectv1.AddToScheme(scheme)
_ = imageautov1.AddToScheme(scheme) _ = imageautov1.AddToScheme(scheme)
return scheme return scheme

View File

@@ -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/helm-controller/releases/download/v0.37.1/helm-controller.crds.yaml - https://github.com/fluxcd/helm-controller/releases/download/v0.36.2/helm-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.37.1/helm-controller.deployment.yaml - https://github.com/fluxcd/helm-controller/releases/download/v0.36.2/helm-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -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/image-automation-controller/releases/download/v0.37.0/image-automation-controller.crds.yaml - https://github.com/fluxcd/image-automation-controller/releases/download/v0.36.1/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.37.0/image-automation-controller.deployment.yaml - https://github.com/fluxcd/image-automation-controller/releases/download/v0.36.1/image-automation-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -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/image-reflector-controller/releases/download/v0.31.1/image-reflector-controller.crds.yaml - https://github.com/fluxcd/image-reflector-controller/releases/download/v0.30.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.31.1/image-reflector-controller.deployment.yaml - https://github.com/fluxcd/image-reflector-controller/releases/download/v0.30.0/image-reflector-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -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/kustomize-controller/releases/download/v1.2.1/kustomize-controller.crds.yaml - https://github.com/fluxcd/kustomize-controller/releases/download/v1.1.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.2.1/kustomize-controller.deployment.yaml - https://github.com/fluxcd/kustomize-controller/releases/download/v1.1.1/kustomize-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -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/notification-controller/releases/download/v1.2.3/notification-controller.crds.yaml - https://github.com/fluxcd/notification-controller/releases/download/v1.1.0/notification-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v1.2.3/notification-controller.deployment.yaml - https://github.com/fluxcd/notification-controller/releases/download/v1.1.0/notification-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -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/v1.2.3/source-controller.crds.yaml - https://github.com/fluxcd/source-controller/releases/download/v1.1.2/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v1.2.3/source-controller.deployment.yaml - https://github.com/fluxcd/source-controller/releases/download/v1.1.2/source-controller.deployment.yaml
- account.yaml - account.yaml
transformers: transformers:
- labels.yaml - labels.yaml

View File

@@ -1,9 +1,9 @@
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/v1.2.3/source-controller.crds.yaml - https://github.com/fluxcd/source-controller/releases/download/v1.1.2/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.2.1/kustomize-controller.crds.yaml - https://github.com/fluxcd/kustomize-controller/releases/download/v1.1.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.37.1/helm-controller.crds.yaml - https://github.com/fluxcd/helm-controller/releases/download/v0.36.2/helm-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v1.2.3/notification-controller.crds.yaml - https://github.com/fluxcd/notification-controller/releases/download/v1.1.0/notification-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.31.1/image-reflector-controller.crds.yaml - https://github.com/fluxcd/image-reflector-controller/releases/download/v0.30.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.37.0/image-automation-controller.crds.yaml - https://github.com/fluxcd/image-automation-controller/releases/download/v0.36.1/image-automation-controller.crds.yaml

View File

@@ -20,6 +20,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"k8s.io/apimachinery/pkg/util/wait"
"strings" "strings"
"time" "time"
@@ -27,17 +28,12 @@ import (
apierr "k8s.io/apimachinery/pkg/api/errors" apierr "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta" apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
apierrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/flux2/v2/pkg/manifestgen/install" "github.com/fluxcd/flux2/v2/pkg/manifestgen/install"
"github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret" "github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret"
@@ -48,11 +44,6 @@ var (
ErrReconciledWithWarning = errors.New("reconciled with warning") ErrReconciledWithWarning = errors.New("reconciled with warning")
) )
// Reconciler reconciles and reports the health of different
// components and kubernetes resources involved in the installation of Flux.
//
// It is recommended use the `ReconcilerWithSyncCheck` interface that also
// reports the health of the GitRepository.
type Reconciler interface { type Reconciler interface {
// ReconcileComponents reconciles the components by generating the // ReconcileComponents reconciles the components by generating the
// manifests with the provided values, committing them to Git and // manifests with the provided values, committing them to Git and
@@ -85,14 +76,6 @@ type RepositoryReconciler interface {
ReconcileRepository(ctx context.Context) error ReconcileRepository(ctx context.Context) error
} }
// ReconcilerWithSyncCheck extends the Reconciler interface to also report the health of the GitReposiotry
// that syncs Flux on the cluster
type ReconcilerWithSyncCheck interface {
Reconciler
// ReportGitRepoHealth reports about the health of the GitRepository synchronizing the components.
ReportGitRepoHealth(ctx context.Context, options sync.Options, pollInterval, timeout time.Duration) error
}
type PostGenerateSecretFunc func(ctx context.Context, secret corev1.Secret, options sourcesecret.Options) error type PostGenerateSecretFunc func(ctx context.Context, secret corev1.Secret, options sourcesecret.Options) error
func Run(ctx context.Context, reconciler Reconciler, manifestsBase string, func Run(ctx context.Context, reconciler Reconciler, manifestsBase string,
@@ -116,22 +99,18 @@ func Run(ctx context.Context, reconciler Reconciler, manifestsBase string,
return err return err
} }
var errs []error var healthErrCount int
if r, ok := reconciler.(ReconcilerWithSyncCheck); ok {
if err := r.ReportGitRepoHealth(ctx, syncOpts, pollInterval, timeout); err != nil {
errs = append(errs, err)
}
}
if err := reconciler.ReportKustomizationHealth(ctx, syncOpts, pollInterval, timeout); err != nil { if err := reconciler.ReportKustomizationHealth(ctx, syncOpts, pollInterval, timeout); err != nil {
errs = append(errs, err) healthErrCount++
} }
if err := reconciler.ReportComponentsHealth(ctx, installOpts, timeout); err != nil { if err := reconciler.ReportComponentsHealth(ctx, installOpts, timeout); err != nil {
errs = append(errs, err) healthErrCount++
} }
if len(errs) > 0 { if healthErrCount > 0 {
err = fmt.Errorf("bootstrap failed with %d health check failure(s): %w", len(errs), apierrors.NewAggregate(errs)) // Composing a "smart" error message here from the returned
// errors does not result in any useful information for the
// user, as both methods log the failures they run into.
err = fmt.Errorf("bootstrap failed with %d health check failure(s)", healthErrCount)
} }
return err return err
@@ -194,47 +173,32 @@ func kustomizationPathDiffers(ctx context.Context, kube client.Client, objKey cl
return k.Spec.Path, nil return k.Spec.Path, nil
} }
type objectWithConditions interface { func kustomizationReconciled(kube client.Client, objKey client.ObjectKey, kustomization *kustomizev1.Kustomization, expectRevision string) wait.ConditionWithContextFunc {
client.Object
GetConditions() []metav1.Condition
}
func objectReconciled(kube client.Client, objKey client.ObjectKey, clientObject objectWithConditions, expectRevision string) wait.ConditionWithContextFunc {
return func(ctx context.Context) (bool, error) { return func(ctx context.Context) (bool, error) {
// for some reason, TypeMeta gets unset after kube.Get so we want to store the GVK and set it after if err := kube.Get(ctx, objKey, kustomization); err != nil {
// ref https://github.com/kubernetes-sigs/controller-runtime/issues/1517#issuecomment-844703142
gvk := clientObject.GetObjectKind().GroupVersionKind()
if err := kube.Get(ctx, objKey, clientObject); err != nil {
return false, err
}
clientObject.GetObjectKind().SetGroupVersionKind(gvk)
kind := gvk.Kind
obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(clientObject)
if err != nil {
return false, err return false, err
} }
// Detect suspended object, as this would result in an endless wait // Detect suspended Kustomization, as this would result in an endless wait
if suspended, ok, _ := unstructured.NestedBool(obj, "spec", "suspend"); ok && suspended { if kustomization.Spec.Suspend {
return false, fmt.Errorf("%s '%s' is suspended", kind, objKey.String()) return false, fmt.Errorf("Kustomization is suspended")
} }
// Confirm the state we are observing is for the current generation // Confirm the state we are observing is for the current generation
if generation, ok, _ := unstructured.NestedInt64(obj, "status", "observedGeneration"); ok && generation != clientObject.GetGeneration() { if kustomization.Generation != kustomization.Status.ObservedGeneration {
return false, nil
}
// Confirm the given revision has been attempted by the controller
if sourcev1.TransformLegacyRevision(kustomization.Status.LastAttemptedRevision) != expectRevision {
return false, nil return false, nil
} }
// Confirm the resource is healthy // Confirm the resource is healthy
if c := apimeta.FindStatusCondition(clientObject.GetConditions(), meta.ReadyCondition); c != nil { if c := apimeta.FindStatusCondition(kustomization.Status.Conditions, meta.ReadyCondition); c != nil {
switch c.Status { switch c.Status {
case metav1.ConditionTrue: case metav1.ConditionTrue:
// Confirm the given revision has been attempted by the controller return true, nil
hasRev, err := hasRevision(kind, obj, expectRevision)
if err != nil {
return false, err
}
return hasRev, nil
case metav1.ConditionFalse: case metav1.ConditionFalse:
return false, fmt.Errorf(c.Message) return false, fmt.Errorf(c.Message)
} }
@@ -243,21 +207,6 @@ func objectReconciled(kube client.Client, objKey client.ObjectKey, clientObject
} }
} }
// hasRevision checks that the reconciled revision (for Kustomization this is `.status.lastAttemptedRevision`
// and for Source APIs, it is stored in `.status.artifact.revision`) is the same as the expectedRev
func hasRevision(kind string, obj map[string]interface{}, expectedRev string) (bool, error) {
var rev string
switch kind {
case sourcev1.GitRepositoryKind, sourcev1b2.OCIRepositoryKind, sourcev1b2.BucketKind, sourcev1b2.HelmChartKind:
rev, _, _ = unstructured.NestedString(obj, "status", "artifact", "revision")
case kustomizev1.KustomizationKind:
rev, _, _ = unstructured.NestedString(obj, "status", "lastAttemptedRevision")
default:
return false, fmt.Errorf("cannot get status revision for kind: '%s'", kind)
}
return sourcev1b2.TransformLegacyRevision(rev) == expectedRev, nil
}
func retry(retries int, wait time.Duration, fn func() error) (err error) { func retry(retries int, wait time.Duration, fn func() error) (err error) {
for i := 0; ; i++ { for i := 0; ; i++ {
err = fn() err = fn()

View File

@@ -29,8 +29,6 @@ import (
"github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp"
gogit "github.com/go-git/go-git/v5" gogit "github.com/go-git/go-git/v5"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
@@ -40,12 +38,10 @@ import (
"github.com/fluxcd/cli-utils/pkg/object" "github.com/fluxcd/cli-utils/pkg/object"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/repository" "github.com/fluxcd/pkg/git/repository"
"github.com/fluxcd/pkg/kustomize/filesys" "github.com/fluxcd/pkg/kustomize/filesys"
runclient "github.com/fluxcd/pkg/runtime/client" runclient "github.com/fluxcd/pkg/runtime/client"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
"github.com/fluxcd/flux2/v2/pkg/log" "github.com/fluxcd/flux2/v2/pkg/log"
@@ -174,11 +170,11 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
manifests.Path: strings.NewReader(manifests.Content), manifests.Path: strings.NewReader(manifests.Content),
}), repository.WithSigner(signer)) }), repository.WithSigner(signer))
if err != nil && err != git.ErrNoStagedFiles { if err != nil && err != git.ErrNoStagedFiles {
return fmt.Errorf("failed to commit component manifests: %w", err) return fmt.Errorf("failed to commit sync manifests: %w", err)
} }
if err == nil { if err == nil {
b.logger.Successf("committed component manifests to %q (%q)", b.branch, commit) b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit)
b.logger.Actionf("pushing component manifests to %q", b.url) b.logger.Actionf("pushing component manifests to %q", b.url)
if err = b.gitClient.Push(ctx, repository.PushConfig{}); err != nil { if err = b.gitClient.Push(ctx, repository.PushConfig{}); err != nil {
return fmt.Errorf("failed to push manifests: %w", err) return fmt.Errorf("failed to push manifests: %w", err)
@@ -401,62 +397,20 @@ func (b *PlainGitBootstrapper) ReportKustomizationHealth(ctx context.Context, op
objKey := client.ObjectKey{Name: options.Name, Namespace: options.Namespace} objKey := client.ObjectKey{Name: options.Name, Namespace: options.Namespace}
expectRevision := fmt.Sprintf("%s@%s", options.Branch, git.Hash(head).Digest())
b.logger.Waitingf("waiting for Kustomization %q to be reconciled", objKey.String()) b.logger.Waitingf("waiting for Kustomization %q to be reconciled", objKey.String())
k := &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{ expectRevision := fmt.Sprintf("%s@%s", options.Branch, git.Hash(head).Digest())
Kind: kustomizev1.KustomizationKind, var k kustomizev1.Kustomization
},
}
if err := wait.PollUntilContextTimeout(ctx, pollInterval, timeout, true, if err := wait.PollUntilContextTimeout(ctx, pollInterval, timeout, true,
objectReconciled(b.kube, objKey, k, expectRevision)); err != nil { kustomizationReconciled(b.kube, objKey, &k, expectRevision)); err != nil {
// If the poll timed out, we want to log the ready condition message as
// that likely contains the reason
if errors.Is(err, context.DeadlineExceeded) {
readyCondition := apimeta.FindStatusCondition(k.Status.Conditions, meta.ReadyCondition)
if readyCondition != nil && readyCondition.Status != metav1.ConditionTrue {
err = fmt.Errorf("kustomization '%s' not ready: '%s'", objKey, readyCondition.Message)
}
}
b.logger.Failuref(err.Error()) b.logger.Failuref(err.Error())
return fmt.Errorf("error while waiting for Kustomization to be ready: '%s'", err) return err
} }
b.logger.Successf("Kustomization reconciled successfully") b.logger.Successf("Kustomization reconciled successfully")
return nil return nil
} }
func (b *PlainGitBootstrapper) ReportGitRepoHealth(ctx context.Context, options sync.Options, pollInterval, timeout time.Duration) error {
head, err := b.gitClient.Head()
if err != nil {
return err
}
objKey := client.ObjectKey{Name: options.Name, Namespace: options.Namespace}
b.logger.Waitingf("waiting for GitRepository %q to be reconciled", objKey.String())
expectRevision := fmt.Sprintf("%s@%s", options.Branch, git.Hash(head).Digest())
g := &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
}
if err := wait.PollUntilContextTimeout(ctx, pollInterval, timeout, true,
objectReconciled(b.kube, objKey, g, expectRevision)); err != nil {
// If the poll timed out, we want to log the ready condition message as
// that likely contains the reason
if errors.Is(err, context.DeadlineExceeded) {
readyCondition := apimeta.FindStatusCondition(g.Status.Conditions, meta.ReadyCondition)
if readyCondition != nil && readyCondition.Status != metav1.ConditionTrue {
err = fmt.Errorf("gitrepository '%s' not ready: '%s'", objKey, readyCondition.Message)
}
}
b.logger.Failuref(err.Error())
return fmt.Errorf("error while waiting for GitRepository to be ready: '%s'", err)
}
b.logger.Successf("GitRepsoitory reconciled successfully")
return nil
}
func (b *PlainGitBootstrapper) ReportComponentsHealth(ctx context.Context, install install.Options, timeout time.Duration) error { func (b *PlainGitBootstrapper) ReportComponentsHealth(ctx context.Context, install install.Options, timeout time.Duration) error {
cfg, err := utils.KubeConfig(b.restClientGetter, b.restClientOptions) cfg, err := utils.KubeConfig(b.restClientGetter, b.restClientOptions)
if err != nil { if err != nil {

View File

@@ -1,469 +0,0 @@
/*
Copyright 2023 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 bootstrap
import (
"context"
"testing"
"github.com/fluxcd/pkg/apis/meta"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/fluxcd/flux2/v2/internal/utils"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
)
func Test_hasRevision(t *testing.T) {
var revision = "main@sha1:5bf3a8f9bb0aa5ae8afd6208f43757ab73fc033a"
tests := []struct {
name string
obj objectWithConditions
rev string
expectErr bool
expectedBool bool
}{
{
name: "Kustomization revision",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
},
Status: kustomizev1.KustomizationStatus{
LastAttemptedRevision: "main@sha1:5bf3a8f9bb0aa5ae8afd6208f43757ab73fc033a",
},
},
expectedBool: true,
},
{
name: "GitRepository revision",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
Status: sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Revision: "main@sha1:5bf3a8f9bb0aa5ae8afd6208f43757ab73fc033a",
},
},
},
expectedBool: true,
},
{
name: "GitRepository revision (wrong revision)",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
Status: sourcev1.GitRepositoryStatus{
Artifact: &sourcev1.Artifact{
Revision: "main@sha1:e7f3a8f9bb0aa5ae8afd6208f43757ab73fc043a",
},
},
},
},
{
name: "Kustomization revision (empty revision)",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
},
Status: kustomizev1.KustomizationStatus{
LastAttemptedRevision: "",
},
},
},
{
name: "OCIRepository revision",
obj: &sourcev1b2.OCIRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1b2.OCIRepositoryKind,
},
Status: sourcev1b2.OCIRepositoryStatus{
Artifact: &sourcev1.Artifact{
Revision: "main@sha1:5bf3a8f9bb0aa5ae8afd6208f43757ab73fc033a",
},
},
},
expectedBool: true,
},
{
name: "Alert revision(Not supported)",
obj: &notificationv1.Alert{
TypeMeta: metav1.TypeMeta{
Kind: notificationv1.AlertKind,
},
Status: notificationv1.AlertStatus{
ObservedGeneration: 1,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tt.obj)
g.Expect(err).To(BeNil())
got, err := hasRevision(tt.obj.GetObjectKind().GroupVersionKind().Kind, obj, revision)
if tt.expectErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(got).To(Equal(tt.expectedBool))
})
}
}
func Test_objectReconciled(t *testing.T) {
expectedRev := "main@sha1:5bf3a8f9bb0aa5ae8afd6208f43757ab73fc033a"
type updateStatus struct {
statusFn func(o client.Object)
expectedErr bool
expectedBool bool
}
tests := []struct {
name string
obj objectWithConditions
statuses []updateStatus
}{
{
name: "GitRepository with no status",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "suspended Kustomization",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
APIVersion: kustomizev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
},
Spec: kustomizev1.KustomizationSpec{
Suspend: true,
},
},
statuses: []updateStatus{
{
expectedErr: true,
},
},
},
{
name: "Kustomization - status with old generation",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
APIVersion: kustomizev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: kustomizev1.KustomizationStatus{
ObservedGeneration: -1,
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "GitRepository - status with same generation but no conditions",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "GitRepository - status with conditions but no ready condition",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReconcilingCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Progressing", Message: "Progressing"},
},
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "Kustomization - status with false ready condition",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
APIVersion: kustomizev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: kustomizev1.KustomizationStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionFalse, ObservedGeneration: 1, Reason: "Failing", Message: "Failed to clone"},
},
},
},
statuses: []updateStatus{
{
expectedErr: true,
expectedBool: false,
},
},
},
{
name: "Kustomization - status with true ready condition but different revision",
obj: &kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: kustomizev1.KustomizationKind,
APIVersion: kustomizev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: kustomizev1.KustomizationStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Passing", Message: "Applied revision"},
},
LastAttemptedRevision: "main@sha1:e7f3a8f9bb0aa5ae8afd6208f43757ab73fc043a",
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "GitRepository - status with true ready condition but different revision",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Readyyy", Message: "Cloned successfully"},
},
Artifact: &sourcev1.Artifact{
Revision: "main@sha1:e7f3a8f9bb0aa5ae8afd6208f43757ab73fc043a",
},
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: false,
},
},
},
{
name: "GitRepository - ready with right revision",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
Status: sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Readyyy", Message: "Cloned successfully"},
},
Artifact: &sourcev1.Artifact{
Revision: expectedRev,
},
},
},
statuses: []updateStatus{
{
expectedErr: false,
expectedBool: true,
},
},
},
{
name: "GitRepository - sequence of status updates before ready",
obj: &sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: sourcev1.GitRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "flux-system",
Namespace: "flux-system",
Generation: 1,
},
},
statuses: []updateStatus{
{
// observed gen different
statusFn: func(o client.Object) {
gitRepo := o.(*sourcev1.GitRepository)
gitRepo.Status = sourcev1.GitRepositoryStatus{
ObservedGeneration: -1,
}
},
},
{
// ready failing
statusFn: func(o client.Object) {
gitRepo := o.(*sourcev1.GitRepository)
gitRepo.Status = sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionFalse, ObservedGeneration: 1, Reason: "Not Ready", Message: "Transient connection issue"},
},
}
},
expectedErr: true,
},
{
// updated to a different revision
statusFn: func(o client.Object) {
gitRepo := o.(*sourcev1.GitRepository)
gitRepo.Status = sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Readyyy", Message: "Cloned successfully"},
},
Artifact: &sourcev1.Artifact{
Revision: "wrong rev",
},
}
},
},
{
// updated to the expected revision
statusFn: func(o client.Object) {
gitRepo := o.(*sourcev1.GitRepository)
gitRepo.Status = sourcev1.GitRepositoryStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{
{Type: meta.ReadyCondition, Status: metav1.ConditionTrue, ObservedGeneration: 1, Reason: "Readyyy", Message: "Cloned successfully"},
},
Artifact: &sourcev1.Artifact{
Revision: expectedRev,
},
}
},
expectedBool: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
builder := fake.NewClientBuilder().WithScheme(utils.NewScheme())
builder.WithObjects(tt.obj)
kubeClient := builder.Build()
for _, updates := range tt.statuses {
if updates.statusFn != nil {
updates.statusFn(tt.obj)
g.Expect(kubeClient.Update(context.TODO(), tt.obj)).To(Succeed())
}
waitFunc := objectReconciled(kubeClient, client.ObjectKeyFromObject(tt.obj), tt.obj, expectedRev)
got, err := waitFunc(context.TODO())
g.Expect(err != nil).To(Equal(updates.expectedErr))
g.Expect(got).To(Equal(updates.expectedBool))
}
})
}
}

Some files were not shown because too many files have changed in this diff Show More