Compare commits
1 Commits
v2.2.1
...
flux-audit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f79b4dd57 |
2
.github/workflows/backport.yaml
vendored
2
.github/workflows/backport.yaml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/e2e-arm64.yaml
vendored
4
.github/workflows/e2e-arm64.yaml
vendored
@@ -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: |
|
||||||
|
|||||||
6
.github/workflows/e2e-azure.yaml
vendored
6
.github/workflows/e2e-azure.yaml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/e2e-bootstrap.yaml
vendored
2
.github/workflows/e2e-bootstrap.yaml
vendored
@@ -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: |
|
||||||
|
|||||||
6
.github/workflows/e2e-gcp.yaml
vendored
6
.github/workflows/e2e-gcp.yaml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/e2e.yaml
vendored
2
.github/workflows/e2e.yaml
vendored
@@ -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: |
|
||||||
|
|||||||
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -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
|
||||||
|
|||||||
6
.github/workflows/scan.yaml
vendored
6
.github/workflows/scan.yaml
vendored
@@ -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: |
|
||||||
|
|||||||
2
.github/workflows/update.yaml
vendored
2
.github/workflows/update.yaml
vendored
@@ -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: |
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
195
cmd/flux/audit.go
Normal 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)
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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()
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{¬ificationv1b3.ProviderList{}},
|
list: alertProviderListAdapter{¬ificationv1b2.ProviderList{}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
apiType: alertType,
|
apiType: alertType,
|
||||||
list: &alertListAdapter{¬ificationv1b3.AlertList{}},
|
list: &alertListAdapter{¬ificationv1b2.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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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 := ¬ificationv1.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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
44
cmd/flux/reconcile_alert.go
Normal file
44
cmd/flux/reconcile_alert.go
Normal 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{¬ificationv1.Alert{}},
|
||||||
|
}.run,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
reconcileCmd.AddCommand(reconcileAlertCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj alertAdapter) lastHandledReconcileRequest() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
93
cmd/flux/reconcile_alertprovider.go
Normal file
93
cmd/flux/reconcile_alertprovider.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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{¬ificationv1.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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -84,7 +84,3 @@ func (obj helmChartAdapter) getSource() (reconcileSource, types.NamespacedName)
|
|||||||
Namespace: obj.Namespace,
|
Namespace: obj.Namespace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj helmChartAdapter) isStatic() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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]}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{¬ificationv1.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]}
|
|
||||||
}
|
|
||||||
@@ -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{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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{¬ificationv1.Provider{}},
|
|
||||||
list: &alertProviderListAdapter{¬ificationv1.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]}
|
|
||||||
}
|
|
||||||
@@ -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{
|
||||||
|
|||||||
2
cmd/flux/testdata/check/check_pre.golden
vendored
2
cmd/flux/testdata/check/check_pre.golden
vendored
@@ -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
|
||||||
|
|||||||
2
cmd/flux/testdata/export/alert.yaml
vendored
2
cmd/flux/testdata/export/alert.yaml
vendored
@@ -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
|
||||||
|
|||||||
2
cmd/flux/testdata/export/helm-release.yaml
vendored
2
cmd/flux/testdata/export/helm-release.yaml
vendored
@@ -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
|
||||||
|
|||||||
6
cmd/flux/testdata/export/objects.yaml
vendored
6
cmd/flux/testdata/export/objects.yaml
vendored
@@ -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
|
||||||
|
|||||||
2
cmd/flux/testdata/export/provider.yaml
vendored
2
cmd/flux/testdata/export/provider.yaml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
2
cmd/flux/testdata/trace/deployment.yaml
vendored
2
cmd/flux/testdata/trace/deployment.yaml
vendored
@@ -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:
|
||||||
|
|||||||
2
cmd/flux/testdata/trace/helmrelease-oci.yaml
vendored
2
cmd/flux/testdata/trace/helmrelease-oci.yaml
vendored
@@ -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:
|
||||||
|
|||||||
2
cmd/flux/testdata/trace/helmrelease.yaml
vendored
2
cmd/flux/testdata/trace/helmrelease.yaml
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
122
go.mod
@@ -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
312
go.sum
@@ -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=
|
||||||
|
|||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|||||||
63
internal/utils/objectutil.go
Normal file
63
internal/utils/objectutil.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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: ¬ificationv1.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
Reference in New Issue
Block a user