Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30008de400 | ||
|
|
a5fa731545 | ||
|
|
493ee3c956 | ||
|
|
3dd574ee51 | ||
|
|
5416c19b2e | ||
|
|
2f31d80c7a | ||
|
|
27d1833854 | ||
|
|
84ed716908 | ||
|
|
6c9c9c7578 | ||
|
|
cc7b7b0689 | ||
|
|
5df8e05d1a | ||
|
|
b3b224b0ca | ||
|
|
75ab28ee5d | ||
|
|
aa9ea2b4ab | ||
|
|
1e6be99c36 | ||
|
|
49fb396bf8 | ||
|
|
e055c9ddc1 | ||
|
|
c708e390a7 | ||
|
|
d5ad26c934 | ||
|
|
144b7cd922 | ||
|
|
9e86fbb311 | ||
|
|
b528428d02 | ||
|
|
b3d7730e79 | ||
|
|
f2ba567ca4 | ||
|
|
8342f77087 | ||
|
|
7cade1b98f | ||
|
|
ee4c1fb36c | ||
|
|
dbc4e537fe | ||
|
|
e28990b96c | ||
|
|
408cf92c04 | ||
|
|
425af2e0dc | ||
|
|
22df860eca | ||
|
|
f395044d65 | ||
|
|
afe0ddcd84 | ||
|
|
2c0323684c | ||
|
|
6d5ffdea57 | ||
|
|
648af6e645 | ||
|
|
e1895a4e21 | ||
|
|
d5f45800ae | ||
|
|
51f9d249ff | ||
|
|
6f525356cb | ||
|
|
5008f9064e | ||
|
|
cff96ed7ca | ||
|
|
4e8a600f34 | ||
|
|
4fd5684277 | ||
|
|
06bf469ba7 | ||
|
|
b8a215230c | ||
|
|
2460cfcf1c | ||
|
|
364242c857 | ||
|
|
29e2900f59 | ||
|
|
61e1fb770e | ||
|
|
2d3fcbdea3 | ||
|
|
47e15cee3d | ||
|
|
adeb3e3f42 | ||
|
|
fb1278285b | ||
|
|
e371610849 | ||
|
|
424de63bd1 | ||
|
|
832c925d39 | ||
|
|
378f118d51 | ||
|
|
d651777122 | ||
|
|
65d8ebabb8 | ||
|
|
9195ed9a1b | ||
|
|
5df8f7313c | ||
|
|
25ed6ca0a4 | ||
|
|
9f972995bd |
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve Flux v2
|
||||
title: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
Find out more about your support options and getting help at
|
||||
|
||||
https://fluxcd.io/support/
|
||||
|
||||
-->
|
||||
|
||||
### Describe the bug
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
### To Reproduce
|
||||
|
||||
Steps to reproduce the behaviour:
|
||||
|
||||
1. Provide Flux install instructions
|
||||
2. Provide a GitHub repository with Kubernetes manifests
|
||||
|
||||
### Expected behavior
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
### Additional context
|
||||
|
||||
- Kubernetes version:
|
||||
- Git provider:
|
||||
- Container registry provider:
|
||||
|
||||
Below please provide the output of the following commands:
|
||||
|
||||
```cli
|
||||
flux --version
|
||||
flux check
|
||||
kubectl -n <namespace> get all
|
||||
kubectl -n <namespace> logs deploy/source-controller
|
||||
kubectl -n <namespace> logs deploy/kustomize-controller
|
||||
```
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/fluxcd/flux2/discussions
|
||||
about: Please ask and answer questions here.
|
||||
5
.github/kind/config.yaml
vendored
Normal file
5
.github/kind/config.yaml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
networking:
|
||||
disableDefaultCNI: true # disable kindnet
|
||||
podSubnet: 192.168.0.0/16 # set to Calico's default subnet
|
||||
17
.github/workflows/e2e.yaml
vendored
17
.github/workflows/e2e.yaml
vendored
@@ -26,7 +26,13 @@ jobs:
|
||||
- name: Setup Kubernetes
|
||||
uses: engineerd/setup-kind@v0.5.0
|
||||
with:
|
||||
image: kindest/node:v1.16.9
|
||||
version: "v0.10.0"
|
||||
image: kindest/node:v1.20.2@sha256:8f7ea6e7642c0da54f04a7ee10431549c0257315b3a634f6ef2fecaaedb19bab
|
||||
config: .github/kind/config.yaml # disable KIND-net
|
||||
- name: Setup Calico for network policy
|
||||
run: |
|
||||
kubectl apply -f https://docs.projectcalico.org/v3.16/manifests/calico.yaml
|
||||
kubectl -n kube-system set env daemonset/calico-node FELIX_IGNORELOOSERPF=true
|
||||
- name: Run test
|
||||
run: make test
|
||||
- name: Check if working tree is dirty
|
||||
@@ -44,6 +50,15 @@ jobs:
|
||||
- name: flux install --manifests
|
||||
run: |
|
||||
./bin/flux install --manifests ./manifests/install/
|
||||
- name: flux create secret
|
||||
run: |
|
||||
./bin/flux create secret git git-ssh-test \
|
||||
--url ssh://git@github.com/stefanprodan/podinfo
|
||||
./bin/flux create secret git git-https-test \
|
||||
--url https://github.com/stefanprodan/podinfo \
|
||||
--username=test --password=test
|
||||
./bin/flux create secret helm helm-test \
|
||||
--username=test --password=test
|
||||
- name: flux create source git
|
||||
run: |
|
||||
./bin/flux create source git podinfo \
|
||||
|
||||
20
.github/workflows/update.yml
vendored
20
.github/workflows/update.yml
vendored
@@ -32,7 +32,8 @@ jobs:
|
||||
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
|
||||
fi
|
||||
|
||||
PR_BODY="$PR_BODY- $1 to ${RELEASE_VERSION}%0A"
|
||||
# NB: special URL encoded formatting required for newlines
|
||||
PR_BODY="$PR_BODY- $1 to ${RELEASE_VERSION}%0A https://github.com/fluxcd/$1/blob/${RELEASE_VERSION}/CHANGELOG.md%0A"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ jobs:
|
||||
# diff change
|
||||
git diff
|
||||
|
||||
# export PR_BODY for PR
|
||||
# export PR_BODY for PR and commit
|
||||
echo "::set-output name=pr_body::$PR_BODY"
|
||||
}
|
||||
|
||||
@@ -60,19 +61,22 @@ jobs:
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
commit-message: Update toolkit components
|
||||
commit-message: |
|
||||
Update toolkit components
|
||||
|
||||
${{ steps.update.outputs.pr_body }}
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: fluxcdbot <fluxcdbot@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: update-components
|
||||
title: Update toolkit components
|
||||
body: |
|
||||
${{ steps.update.outputs.pr_body }}
|
||||
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
branch: update-components
|
||||
labels: |
|
||||
area/build
|
||||
reviewers: ${{ secrets.ASSIGNEES }}
|
||||
|
||||
- name: Check output
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
||||
|
||||
22
README.md
22
README.md
@@ -66,6 +66,8 @@ the following guides:
|
||||
- [Setup Notifications](https://toolkit.fluxcd.io/guides/notifications/)
|
||||
- [Setup Webhook Receivers](https://toolkit.fluxcd.io/guides/webhook-receivers/)
|
||||
|
||||
If you should need help, please refer to our **[Support page](https://fluxcd.io/support/)**.
|
||||
|
||||
## GitOps Toolkit
|
||||
|
||||
The GitOps Toolkit is the set of APIs and controllers that make up the
|
||||
@@ -97,15 +99,19 @@ guides](https://toolkit.fluxcd.io/dev-guides/source-watcher/).
|
||||
|
||||
## Community
|
||||
|
||||
The Flux project is always looking for new contributors and there are a multitude of ways to get involved.
|
||||
Depending on what you want to do, some of the following bits might be your first steps:
|
||||
Need help or want to contribute? Please see the links below. The Flux project is always looking for new contributors and there are a multitude of ways to get involved.
|
||||
|
||||
- Join our upcoming dev meetings ([meeting access and agenda](https://docs.google.com/document/d/1l_M0om0qUEN_NNiGgpqJ2tvsF2iioHkaARDeh6b70B0/view))
|
||||
- Talk to us in the #flux channel on [CNCF Slack](https://slack.cncf.io/)
|
||||
- Ask questions and propose features on our [GH Discussions page](https://github.com/fluxcd/flux2/discussions)
|
||||
- And if you are completely new to Flux and the GitOps Toolkit, take a look at our [Get Started guide](https://toolkit.fluxcd.io/get-started/) and give us feedback
|
||||
- To be part of the conversation about Flux's development, [join the flux-dev mailing list](https://lists.cncf.io/g/cncf-flux-dev).
|
||||
- Check out [how to contribute](CONTRIBUTING.md) to the project
|
||||
- Getting Started?
|
||||
- Look at our [Get Started guide](https://toolkit.fluxcd.io/get-started/) and give us feedback
|
||||
- Need help?
|
||||
- First: Ask questions on our [GH Discussions page](https://github.com/fluxcd/flux2/discussions)
|
||||
- Second: Talk to us in the #flux channel on [CNCF Slack](https://slack.cncf.io/)
|
||||
- Please follow our [Support Guidelines](https://fluxcd.io/support/) (in short: be nice, be respectful of volunteers' time, understand that maintainers and contributors cannot respond to all DMs, and keep discussions in the public #flux channel as much as possible).
|
||||
- Have feature proposals or want to contribute?
|
||||
- Propose features on our [GH Discussions page](https://github.com/fluxcd/flux2/discussions)
|
||||
- Join our upcoming dev meetings ([meeting access and agenda](https://docs.google.com/document/d/1l_M0om0qUEN_NNiGgpqJ2tvsF2iioHkaARDeh6b70B0/view))
|
||||
- [Join the flux-dev mailing list](https://lists.cncf.io/g/cncf-flux-dev).
|
||||
- Check out [how to contribute](CONTRIBUTING.md) to the project
|
||||
|
||||
### Events
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Note that this action can only be used on GitHub **Linux AMD64** runners.
|
||||
|
||||
### Automate Flux updates
|
||||
|
||||
Example workflow for updating Flux's components generated with `flux bootstrap --arch=amd64 --path=clusters/production`:
|
||||
Example workflow for updating Flux's components generated with `flux bootstrap --path=clusters/production`:
|
||||
|
||||
```yaml
|
||||
name: update-flux
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
- name: Check for updates
|
||||
id: update
|
||||
run: |
|
||||
flux install --arch=amd64 \
|
||||
flux install \
|
||||
--export > ./clusters/production/flux-system/gotk-components.yaml
|
||||
|
||||
VERSION="$(flux -v)"
|
||||
|
||||
@@ -126,7 +126,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes
|
||||
opts := install.Options{
|
||||
BaseURL: localManifests,
|
||||
Version: bootstrapArgs.version,
|
||||
Namespace: rootArgs.namespace,
|
||||
Namespace: namespace,
|
||||
Components: bootstrapComponents(),
|
||||
Registry: bootstrapArgs.registry,
|
||||
ImagePullSecret: bootstrapArgs.imagePullSecret,
|
||||
@@ -162,12 +162,16 @@ func applyInstallManifests(ctx context.Context, manifestPath string, components
|
||||
return fmt.Errorf("install failed")
|
||||
}
|
||||
|
||||
for _, deployment := range components {
|
||||
kubectlArgs = []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()}
|
||||
if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||
return fmt.Errorf("install failed")
|
||||
}
|
||||
statusChecker, err := NewStatusChecker(time.Second, time.Minute)
|
||||
if err != nil {
|
||||
return fmt.Errorf("install failed: %w", err)
|
||||
}
|
||||
|
||||
logger.Waitingf("verifying installation")
|
||||
if err := statusChecker.Assess(components...); err != nil {
|
||||
return fmt.Errorf("install failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
@@ -45,8 +46,9 @@ the local environment is configured correctly and if the installed components ar
|
||||
}
|
||||
|
||||
type checkFlags struct {
|
||||
pre bool
|
||||
components []string
|
||||
pre bool
|
||||
components []string
|
||||
extraComponents []string
|
||||
}
|
||||
|
||||
type kubectlVersion struct {
|
||||
@@ -60,6 +62,8 @@ func init() {
|
||||
"only run pre-installation checks")
|
||||
checkCmd.Flags().StringSliceVar(&checkArgs.components, "components", rootArgs.defaults.Components,
|
||||
"list of components, accepts comma-separated values")
|
||||
checkCmd.Flags().StringSliceVar(&checkArgs.extraComponents, "components-extra", nil,
|
||||
"list of components in addition to those supplied or defaulted, accepts comma-separated values")
|
||||
rootCmd.AddCommand(checkCmd)
|
||||
}
|
||||
|
||||
@@ -172,16 +176,21 @@ func componentsCheck() bool {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
statusChecker, err := NewStatusChecker(time.Second, 30*time.Second)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
ok := true
|
||||
for _, deployment := range checkArgs.components {
|
||||
kubectlArgs := []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()}
|
||||
if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||
logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
|
||||
deployments := append(checkArgs.components, checkArgs.extraComponents...)
|
||||
for _, deployment := range deployments {
|
||||
if err := statusChecker.Assess(deployment); err != nil {
|
||||
ok = false
|
||||
} else {
|
||||
logger.Successf("%s is healthy", deployment)
|
||||
logger.Successf("%s: healthy", deployment)
|
||||
}
|
||||
kubectlArgs = []string{"-n", rootArgs.namespace, "get", "deployment", deployment, "-o", "jsonpath=\"{..image}\""}
|
||||
|
||||
kubectlArgs := []string{"-n", rootArgs.namespace, "get", "deployment", deployment, "-o", "jsonpath=\"{..image}\""}
|
||||
if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err == nil {
|
||||
logger.Actionf(strings.TrimPrefix(strings.TrimSuffix(output, "\""), "\""))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
@@ -62,11 +63,12 @@ var createHelmReleaseCmd = &cobra.Command{
|
||||
--source=Bucket/podinfo \
|
||||
--chart=./charts/podinfo
|
||||
|
||||
# Create a HelmRelease with values from a local YAML file
|
||||
# Create a HelmRelease with values from local YAML files
|
||||
flux create hr podinfo \
|
||||
--source=HelmRepository/podinfo \
|
||||
--chart=podinfo \
|
||||
--values=./my-values.yaml
|
||||
--values=./my-values1.yaml \
|
||||
--values=./my-values2.yaml
|
||||
|
||||
# Create a HelmRelease with values from a Kubernetes secret
|
||||
kubectl -n app create secret generic my-secret-values \
|
||||
@@ -105,7 +107,7 @@ type helmReleaseFlags struct {
|
||||
chart string
|
||||
chartVersion string
|
||||
targetNamespace string
|
||||
valuesFile string
|
||||
valuesFile []string
|
||||
valuesFrom flags.HelmReleaseValuesFrom
|
||||
saName string
|
||||
}
|
||||
@@ -120,7 +122,7 @@ func init() {
|
||||
createHelmReleaseCmd.Flags().StringArrayVar(&helmReleaseArgs.dependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed, supported formats '<name>' and '<namespace>/<name>'")
|
||||
createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.targetNamespace, "target-namespace", "", "namespace to install this release, defaults to the HelmRelease namespace")
|
||||
createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.saName, "service-account", "", "the name of the service account to impersonate when reconciling this HelmRelease")
|
||||
createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.valuesFile, "values", "", "local path to the values.yaml file")
|
||||
createHelmReleaseCmd.Flags().StringArrayVar(&helmReleaseArgs.valuesFile, "values", nil, "local path to values.yaml files")
|
||||
createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.valuesFrom, "values-from", helmReleaseArgs.valuesFrom.Description())
|
||||
createCmd.AddCommand(createHelmReleaseCmd)
|
||||
}
|
||||
@@ -175,18 +177,37 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
||||
helmRelease.Spec.ServiceAccountName = helmReleaseArgs.saName
|
||||
}
|
||||
|
||||
if helmReleaseArgs.valuesFile != "" {
|
||||
data, err := ioutil.ReadFile(helmReleaseArgs.valuesFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading values from %s failed: %w", helmReleaseArgs.valuesFile, err)
|
||||
if len(helmReleaseArgs.valuesFile) > 0 {
|
||||
var valuesMap map[string]interface{}
|
||||
for _, v := range helmReleaseArgs.valuesFile {
|
||||
data, err := ioutil.ReadFile(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading values from %s failed: %w", v, err)
|
||||
}
|
||||
|
||||
jsonBytes, err := yaml.YAMLToJSON(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting values to JSON from %s failed: %w", v, err)
|
||||
}
|
||||
|
||||
jsonMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal(jsonBytes, &jsonMap); err != nil {
|
||||
return fmt.Errorf("unmarshaling values from %s failed: %w", v, err)
|
||||
}
|
||||
|
||||
if valuesMap == nil {
|
||||
valuesMap = jsonMap
|
||||
} else {
|
||||
valuesMap = utils.MergeMaps(valuesMap, jsonMap)
|
||||
}
|
||||
}
|
||||
|
||||
json, err := yaml.YAMLToJSON(data)
|
||||
jsonRaw, err := json.Marshal(valuesMap)
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting values to JSON from %s failed: %w", helmReleaseArgs.valuesFile, err)
|
||||
return fmt.Errorf("marshaling values failed: %w", err)
|
||||
}
|
||||
|
||||
helmRelease.Spec.Values = &apiextensionsv1.JSON{Raw: json}
|
||||
helmRelease.Spec.Values = &apiextensionsv1.JSON{Raw: jsonRaw}
|
||||
}
|
||||
|
||||
if helmReleaseArgs.valuesFrom.String() != "" {
|
||||
|
||||
@@ -34,13 +34,39 @@ var createImageRepositoryCmd = &cobra.Command{
|
||||
Short: "Create or update an ImageRepository object",
|
||||
Long: `The create image repository command generates an ImageRepository resource.
|
||||
An ImageRepository object specifies an image repository to scan.`,
|
||||
Example: ` # Create an ImageRepository object to scan the alpine image repository:
|
||||
flux create image repository alpine-repo --image alpine --interval 20m
|
||||
|
||||
# Create an image repository that uses an image pull secret (assumed to
|
||||
# have been created already):
|
||||
flux create image repository myapp-repo \
|
||||
--secret-ref image-pull \
|
||||
--image ghcr.io/example.com/myapp --interval 5m
|
||||
|
||||
# Create a TLS secret for a local image registry using a self-signed
|
||||
# host certificate, and use it to scan an image. ca.pem is a file
|
||||
# containing the CA certificate used to sign the host certificate.
|
||||
flux create secret tls local-registry-cert --ca-file ./ca.pem
|
||||
flux create image repository app-repo \
|
||||
--cert-secret-ref local-registry-cert \
|
||||
--image local-registry:5000/app --interval 5m
|
||||
|
||||
# Create a TLS secret with a client certificate and key, and use it
|
||||
# to scan a private image registry.
|
||||
flux create secret tls client-cert \
|
||||
--cert-file client.crt --key-file client.key
|
||||
flux create image repository app-repo \
|
||||
--cert-secret-ref client-cert \
|
||||
--image registry.example.com/private/app --interval 5m
|
||||
`,
|
||||
RunE: createImageRepositoryRun,
|
||||
}
|
||||
|
||||
type imageRepoFlags struct {
|
||||
image string
|
||||
secretRef string
|
||||
timeout time.Duration
|
||||
image string
|
||||
secretRef string
|
||||
certSecretRef string
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var imageRepoArgs = imageRepoFlags{}
|
||||
@@ -49,6 +75,7 @@ func init() {
|
||||
flags := createImageRepositoryCmd.Flags()
|
||||
flags.StringVar(&imageRepoArgs.image, "image", "", "the image repository to scan; e.g., library/alpine")
|
||||
flags.StringVar(&imageRepoArgs.secretRef, "secret-ref", "", "the name of a docker-registry secret to use for credentials")
|
||||
flags.StringVar(&imageRepoArgs.certSecretRef, "cert-ref", "", "the name of a secret to use for TLS certificates")
|
||||
// NB there is already a --timeout in the global flags, for
|
||||
// controlling timeout on operations while e.g., creating objects.
|
||||
flags.DurationVar(&imageRepoArgs.timeout, "scan-timeout", 0, "a timeout for scanning; this defaults to the interval if not set")
|
||||
@@ -94,6 +121,11 @@ func createImageRepositoryRun(cmd *cobra.Command, args []string) error {
|
||||
Name: imageRepoArgs.secretRef,
|
||||
}
|
||||
}
|
||||
if imageRepoArgs.certSecretRef != "" {
|
||||
repo.Spec.CertSecretRef = &meta.LocalObjectReference{
|
||||
Name: imageRepoArgs.certSecretRef,
|
||||
}
|
||||
}
|
||||
|
||||
if createArgs.export {
|
||||
return printExport(exportImageRepository(&repo))
|
||||
|
||||
@@ -70,7 +70,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if imageUpdateArgs.branch == "" {
|
||||
return fmt.Errorf("the Git repoistory branch is required (--branch)")
|
||||
return fmt.Errorf("the Git repository branch is required (--branch)")
|
||||
}
|
||||
|
||||
labels, err := parseLabels()
|
||||
|
||||
@@ -51,6 +51,8 @@ func makeSecret(name string) (corev1.Secret, error) {
|
||||
Namespace: rootArgs.namespace,
|
||||
Labels: secretLabels,
|
||||
},
|
||||
StringData: map[string]string{},
|
||||
Data: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -133,10 +133,10 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
secret.Data = map[string][]byte{
|
||||
"identity": pair.PrivateKey,
|
||||
"identity.pub": pair.PublicKey,
|
||||
"known_hosts": hostKey,
|
||||
secret.StringData = map[string]string{
|
||||
"identity": string(pair.PrivateKey),
|
||||
"identity.pub": string(pair.PublicKey),
|
||||
"known_hosts": string(hostKey),
|
||||
}
|
||||
|
||||
if !createArgs.export {
|
||||
@@ -148,9 +148,9 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// TODO: add cert data when it's implemented in source-controller
|
||||
secret.Data = map[string][]byte{
|
||||
"username": []byte(secretGitArgs.username),
|
||||
"password": []byte(secretGitArgs.password),
|
||||
secret.StringData = map[string]string{
|
||||
"username": secretGitArgs.username,
|
||||
"password": secretGitArgs.password,
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme)
|
||||
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var deleteAutoCmd = &cobra.Command{
|
||||
Use: "auto",
|
||||
Short: "Delete automation objects",
|
||||
Long: "The delete auto sub-commands delete automation objects.",
|
||||
var deleteImageCmd = &cobra.Command{
|
||||
Use: "image",
|
||||
Short: "Delete image automation objects",
|
||||
Long: "The delete image sub-commands delete image automation objects.",
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteCmd.AddCommand(deleteAutoCmd)
|
||||
deleteCmd.AddCommand(deleteImageCmd)
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ import (
|
||||
)
|
||||
|
||||
var deleteImagePolicyCmd = &cobra.Command{
|
||||
Use: "image-policy [name]",
|
||||
Use: "policy [name]",
|
||||
Short: "Delete an ImagePolicy object",
|
||||
Long: "The delete auto image-policy command deletes the given ImagePolicy from the cluster.",
|
||||
Long: "The delete image policy command deletes the given ImagePolicy from the cluster.",
|
||||
Example: ` # Delete an image policy
|
||||
flux delete auto image-policy alpine3.x
|
||||
flux delete image policy alpine3.x
|
||||
`,
|
||||
RunE: deleteCommand{
|
||||
apiType: imagePolicyType,
|
||||
@@ -36,5 +36,5 @@ var deleteImagePolicyCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteAutoCmd.AddCommand(deleteImagePolicyCmd)
|
||||
deleteImageCmd.AddCommand(deleteImagePolicyCmd)
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ import (
|
||||
)
|
||||
|
||||
var deleteImageRepositoryCmd = &cobra.Command{
|
||||
Use: "image-repository [name]",
|
||||
Use: "repository [name]",
|
||||
Short: "Delete an ImageRepository object",
|
||||
Long: "The delete auto image-repository command deletes the given ImageRepository from the cluster.",
|
||||
Long: "The delete image repository command deletes the given ImageRepository from the cluster.",
|
||||
Example: ` # Delete an image repository
|
||||
flux delete auto image-repository alpine
|
||||
flux delete image repository alpine
|
||||
`,
|
||||
RunE: deleteCommand{
|
||||
apiType: imageRepositoryType,
|
||||
@@ -36,5 +36,5 @@ var deleteImageRepositoryCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteAutoCmd.AddCommand(deleteImageRepositoryCmd)
|
||||
deleteImageCmd.AddCommand(deleteImageRepositoryCmd)
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ import (
|
||||
)
|
||||
|
||||
var deleteImageUpdateCmd = &cobra.Command{
|
||||
Use: "image-update [name]",
|
||||
Use: "update [name]",
|
||||
Short: "Delete an ImageUpdateAutomation object",
|
||||
Long: "The delete auto image-update command deletes the given ImageUpdateAutomation from the cluster.",
|
||||
Long: "The delete image update command deletes the given ImageUpdateAutomation from the cluster.",
|
||||
Example: ` # Delete an image update automation
|
||||
flux delete auto image-update latest-images
|
||||
flux delete image update latest-images
|
||||
`,
|
||||
RunE: deleteCommand{
|
||||
apiType: imageUpdateAutomationType,
|
||||
@@ -36,5 +36,5 @@ var deleteImageUpdateCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteAutoCmd.AddCommand(deleteImageUpdateCmd)
|
||||
deleteImageCmd.AddCommand(deleteImageUpdateCmd)
|
||||
}
|
||||
|
||||
@@ -90,6 +90,11 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
|
||||
if !getArgs.allNamespaces {
|
||||
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace))
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
listOpts = append(listOpts, client.MatchingFields{"metadata.name": args[0]})
|
||||
}
|
||||
|
||||
err = kubeClient.List(ctx, get.list.asClientList(), listOpts...)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -33,9 +33,10 @@ import (
|
||||
)
|
||||
|
||||
var getAlertCmd = &cobra.Command{
|
||||
Use: "alerts",
|
||||
Short: "Get Alert statuses",
|
||||
Long: "The get alert command prints the statuses of the resources.",
|
||||
Use: "alerts",
|
||||
Aliases: []string{"alert"},
|
||||
Short: "Get Alert statuses",
|
||||
Long: "The get alert command prints the statuses of the resources.",
|
||||
Example: ` # List all Alerts and their status
|
||||
flux get alerts
|
||||
`,
|
||||
|
||||
@@ -31,9 +31,10 @@ import (
|
||||
)
|
||||
|
||||
var getAlertProviderCmd = &cobra.Command{
|
||||
Use: "alert-providers",
|
||||
Short: "Get Provider statuses",
|
||||
Long: "The get alert-provider command prints the statuses of the resources.",
|
||||
Use: "alert-providers",
|
||||
Aliases: []string{"alert-provider"},
|
||||
Short: "Get Provider statuses",
|
||||
Long: "The get alert-provider command prints the statuses of the resources.",
|
||||
Example: ` # List all Providers and their status
|
||||
flux get alert-providers
|
||||
`,
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
var getHelmReleaseCmd = &cobra.Command{
|
||||
Use: "helmreleases",
|
||||
Aliases: []string{"hr"},
|
||||
Aliases: []string{"hr", "helmrelease"},
|
||||
Short: "Get HelmRelease statuses",
|
||||
Long: "The get helmreleases command prints the statuses of the resources.",
|
||||
Example: ` # List all Helm releases and their status
|
||||
|
||||
@@ -21,9 +21,10 @@ import (
|
||||
)
|
||||
|
||||
var getImageCmd = &cobra.Command{
|
||||
Use: "image",
|
||||
Short: "Get image automation object status",
|
||||
Long: "The get image sub-commands print the status of image automation objects.",
|
||||
Use: "images",
|
||||
Aliases: []string{"image"},
|
||||
Short: "Get image automation object status",
|
||||
Long: "The get image sub-commands print the status of image automation objects.",
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
var getKsCmd = &cobra.Command{
|
||||
Use: "kustomizations",
|
||||
Aliases: []string{"ks"},
|
||||
Aliases: []string{"ks", "kustomization"},
|
||||
Short: "Get Kustomization statuses",
|
||||
Long: "The get kustomizations command prints the statuses of the resources.",
|
||||
Example: ` # List all kustomizations and their status
|
||||
|
||||
@@ -33,9 +33,10 @@ import (
|
||||
)
|
||||
|
||||
var getReceiverCmd = &cobra.Command{
|
||||
Use: "receivers",
|
||||
Short: "Get Receiver statuses",
|
||||
Long: "The get receiver command prints the statuses of the resources.",
|
||||
Use: "receivers",
|
||||
Aliases: []string{"receiver"},
|
||||
Short: "Get Receiver statuses",
|
||||
Long: "The get receiver command prints the statuses of the resources.",
|
||||
Example: ` # List all Receiver and their status
|
||||
flux get receivers
|
||||
`,
|
||||
|
||||
@@ -21,9 +21,10 @@ import (
|
||||
)
|
||||
|
||||
var getSourceCmd = &cobra.Command{
|
||||
Use: "sources",
|
||||
Short: "Get source statuses",
|
||||
Long: "The get source sub-commands print the statuses of the sources.",
|
||||
Use: "sources",
|
||||
Aliases: []string{"source"},
|
||||
Short: "Get source statuses",
|
||||
Long: "The get source sub-commands print the statuses of the sources.",
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -174,18 +175,16 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if installDryRun {
|
||||
logger.Successf("install dry-run finished")
|
||||
return nil
|
||||
} else {
|
||||
logger.Successf("install completed")
|
||||
}
|
||||
|
||||
statusChecker, err := NewStatusChecker(time.Second, time.Minute)
|
||||
if err != nil {
|
||||
return fmt.Errorf("install failed: %w", err)
|
||||
}
|
||||
|
||||
logger.Waitingf("verifying installation")
|
||||
for _, deployment := range components {
|
||||
kubectlArgs = []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()}
|
||||
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||
return fmt.Errorf("install failed")
|
||||
} else {
|
||||
logger.Successf("%s ready", deployment)
|
||||
}
|
||||
if err := statusChecker.Assess(components...); err != nil {
|
||||
return fmt.Errorf("install failed")
|
||||
}
|
||||
|
||||
logger.Successf("install finished")
|
||||
|
||||
@@ -99,11 +99,20 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
switch helmRelease.Spec.Chart.Spec.SourceRef.Kind {
|
||||
case sourcev1.HelmRepositoryKind:
|
||||
err = reconcileSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
err = reconcileCommand{
|
||||
apiType: helmRepositoryType,
|
||||
object: helmRepositoryAdapter{&sourcev1.HelmRepository{}},
|
||||
}.run(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
case sourcev1.GitRepositoryKind:
|
||||
err = reconcileSourceGitCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
err = reconcileCommand{
|
||||
apiType: gitRepositoryType,
|
||||
object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
|
||||
}.run(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
case sourcev1.BucketKind:
|
||||
err = reconcileSourceBucketCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
err = reconcileCommand{
|
||||
apiType: bucketType,
|
||||
object: bucketAdapter{&sourcev1.Bucket{}},
|
||||
}.run(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -97,9 +97,15 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
switch kustomization.Spec.SourceRef.Kind {
|
||||
case sourcev1.GitRepositoryKind:
|
||||
err = reconcileSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
|
||||
err = reconcileCommand{
|
||||
apiType: gitRepositoryType,
|
||||
object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
|
||||
}.run(nil, []string{kustomization.Spec.SourceRef.Name})
|
||||
case sourcev1.BucketKind:
|
||||
err = reconcileSourceBucketCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
|
||||
err = reconcileCommand{
|
||||
apiType: bucketType,
|
||||
object: bucketAdapter{&sourcev1.Bucket{}},
|
||||
}.run(nil, []string{kustomization.Spec.SourceRef.Name})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -19,13 +19,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"k8s.io/client-go/util/retry"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -43,64 +37,16 @@ var reconcileSourceBucketCmd = &cobra.Command{
|
||||
Example: ` # Trigger a reconciliation for an existing source
|
||||
flux reconcile source bucket podinfo
|
||||
`,
|
||||
RunE: reconcileSourceBucketCmdRun,
|
||||
RunE: reconcileCommand{
|
||||
apiType: bucketType,
|
||||
object: bucketAdapter{&sourcev1.Bucket{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
reconcileSourceCmd.AddCommand(reconcileSourceBucketCmd)
|
||||
}
|
||||
|
||||
func reconcileSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var bucket sourcev1.Bucket
|
||||
err = kubeClient.Get(ctx, namespacedName, &bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if bucket.Spec.Suspend {
|
||||
return fmt.Errorf("resource is suspended")
|
||||
}
|
||||
|
||||
lastHandledReconcileAt := bucket.Status.LastHandledReconcileAt
|
||||
logger.Actionf("annotating Bucket source %s in %s namespace", name, rootArgs.namespace)
|
||||
if err := requestBucketReconciliation(ctx, kubeClient, namespacedName, &bucket); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("Bucket source annotated")
|
||||
|
||||
logger.Waitingf("waiting for Bucket source reconciliation")
|
||||
if err := wait.PollImmediate(
|
||||
rootArgs.pollInterval, rootArgs.timeout,
|
||||
bucketReconciliationHandled(ctx, kubeClient, namespacedName, &bucket, lastHandledReconcileAt),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("Bucket source reconciliation completed")
|
||||
|
||||
if apimeta.IsStatusConditionFalse(bucket.Status.Conditions, meta.ReadyCondition) {
|
||||
return fmt.Errorf("Bucket source reconciliation failed")
|
||||
}
|
||||
logger.Successf("fetched revision %s", bucket.Status.Artifact.Revision)
|
||||
return nil
|
||||
}
|
||||
|
||||
func isBucketReady(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, bucket *sourcev1.Bucket) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
@@ -126,30 +72,10 @@ func isBucketReady(ctx context.Context, kubeClient client.Client,
|
||||
}
|
||||
}
|
||||
|
||||
func bucketReconciliationHandled(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, bucket *sourcev1.Bucket, lastHandledReconcileAt string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, bucket)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return bucket.Status.LastHandledReconcileAt != lastHandledReconcileAt, nil
|
||||
}
|
||||
func (obj bucketAdapter) lastHandledReconcileRequest() string {
|
||||
return obj.Status.GetLastHandledReconcileRequest()
|
||||
}
|
||||
|
||||
func requestBucketReconciliation(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, bucket *sourcev1.Bucket) error {
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err := kubeClient.Get(ctx, namespacedName, bucket); err != nil {
|
||||
return err
|
||||
}
|
||||
if bucket.Annotations == nil {
|
||||
bucket.Annotations = map[string]string{
|
||||
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
bucket.Annotations[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
return kubeClient.Update(ctx, bucket)
|
||||
})
|
||||
func (obj bucketAdapter) successMessage() string {
|
||||
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
|
||||
}
|
||||
|
||||
@@ -17,21 +17,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var reconcileSourceGitCmd = &cobra.Command{
|
||||
@@ -41,86 +29,20 @@ var reconcileSourceGitCmd = &cobra.Command{
|
||||
Example: ` # Trigger a git pull for an existing source
|
||||
flux reconcile source git podinfo
|
||||
`,
|
||||
RunE: reconcileSourceGitCmdRun,
|
||||
RunE: reconcileCommand{
|
||||
apiType: gitRepositoryType,
|
||||
object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
reconcileSourceCmd.AddCommand(reconcileSourceGitCmd)
|
||||
}
|
||||
|
||||
func reconcileSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.GitRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if repository.Spec.Suspend {
|
||||
return fmt.Errorf("resource is suspended")
|
||||
}
|
||||
|
||||
logger.Actionf("annotating GitRepository source %s in %s namespace", name, rootArgs.namespace)
|
||||
if err := requestGitRepositoryReconciliation(ctx, kubeClient, namespacedName, &repository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("GitRepository source annotated")
|
||||
|
||||
lastHandledReconcileAt := repository.Status.LastHandledReconcileAt
|
||||
logger.Waitingf("waiting for GitRepository source reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
gitRepositoryReconciliationHandled(ctx, kubeClient, namespacedName, &repository, lastHandledReconcileAt)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("GitRepository source reconciliation completed")
|
||||
|
||||
if apimeta.IsStatusConditionFalse(repository.Status.Conditions, meta.ReadyCondition) {
|
||||
return fmt.Errorf("GitRepository source reconciliation failed")
|
||||
}
|
||||
logger.Successf("fetched revision %s", repository.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj gitRepositoryAdapter) lastHandledReconcileRequest() string {
|
||||
return obj.Status.GetLastHandledReconcileRequest()
|
||||
}
|
||||
|
||||
func gitRepositoryReconciliationHandled(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.GitRepository, lastHandledReconcileAt string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, repository)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return repository.Status.LastHandledReconcileAt != lastHandledReconcileAt, nil
|
||||
}
|
||||
}
|
||||
|
||||
func requestGitRepositoryReconciliation(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.GitRepository) error {
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err := kubeClient.Get(ctx, namespacedName, repository); err != nil {
|
||||
return err
|
||||
}
|
||||
if repository.Annotations == nil {
|
||||
repository.Annotations = map[string]string{
|
||||
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
repository.Annotations[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
return kubeClient.Update(ctx, repository)
|
||||
})
|
||||
func (obj gitRepositoryAdapter) successMessage() string {
|
||||
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
|
||||
}
|
||||
|
||||
@@ -17,22 +17,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"k8s.io/client-go/util/retry"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
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"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var reconcileSourceHelmCmd = &cobra.Command{
|
||||
@@ -42,86 +29,20 @@ var reconcileSourceHelmCmd = &cobra.Command{
|
||||
Example: ` # Trigger a reconciliation for an existing source
|
||||
flux reconcile source helm podinfo
|
||||
`,
|
||||
RunE: reconcileSourceHelmCmdRun,
|
||||
RunE: reconcileCommand{
|
||||
apiType: helmRepositoryType,
|
||||
object: helmRepositoryAdapter{&sourcev1.HelmRepository{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
reconcileSourceCmd.AddCommand(reconcileSourceHelmCmd)
|
||||
}
|
||||
|
||||
func reconcileSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("HelmRepository source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.HelmRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if repository.Spec.Suspend {
|
||||
return fmt.Errorf("resource is suspended")
|
||||
}
|
||||
|
||||
logger.Actionf("annotating HelmRepository source %s in %s namespace", name, rootArgs.namespace)
|
||||
if err := requestHelmRepositoryReconciliation(ctx, kubeClient, namespacedName, &repository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRepository source annotated")
|
||||
|
||||
lastHandledReconcileAt := repository.Status.LastHandledReconcileAt
|
||||
logger.Waitingf("waiting for HelmRepository source reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
helmRepositoryReconciliationHandled(ctx, kubeClient, namespacedName, &repository, lastHandledReconcileAt)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRepository source reconciliation completed")
|
||||
|
||||
if apimeta.IsStatusConditionFalse(repository.Status.Conditions, meta.ReadyCondition) {
|
||||
return fmt.Errorf("HelmRepository source reconciliation failed")
|
||||
}
|
||||
logger.Successf("fetched revision %s", repository.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj helmRepositoryAdapter) lastHandledReconcileRequest() string {
|
||||
return obj.Status.GetLastHandledReconcileRequest()
|
||||
}
|
||||
|
||||
func helmRepositoryReconciliationHandled(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.HelmRepository, lastHandledReconcileAt string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, repository)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return repository.Status.LastHandledReconcileAt != lastHandledReconcileAt, nil
|
||||
}
|
||||
}
|
||||
|
||||
func requestHelmRepositoryReconciliation(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.HelmRepository) error {
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err := kubeClient.Get(ctx, namespacedName, repository); err != nil {
|
||||
return err
|
||||
}
|
||||
if repository.Annotations == nil {
|
||||
repository.Annotations = map[string]string{
|
||||
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
repository.Annotations[meta.ReconcileRequestAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
return kubeClient.Update(ctx, repository)
|
||||
})
|
||||
func (obj helmRepositoryAdapter) successMessage() string {
|
||||
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
|
||||
}
|
||||
|
||||
@@ -17,20 +17,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var resumeHrCmd = &cobra.Command{
|
||||
@@ -42,76 +31,24 @@ finish the apply.`,
|
||||
Example: ` # Resume reconciliation for an existing Helm release
|
||||
flux resume hr podinfo
|
||||
`,
|
||||
RunE: resumeHrCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: helmReleaseType,
|
||||
object: helmReleaseAdapter{&helmv2.HelmRelease{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeCmd.AddCommand(resumeHrCmd)
|
||||
}
|
||||
|
||||
func resumeHrCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("HelmRelease name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming HelmRelease %s in %s namespace", name, rootArgs.namespace)
|
||||
helmRelease.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRelease resumed")
|
||||
|
||||
logger.Waitingf("waiting for HelmRelease reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isHelmReleaseResumed(ctx, kubeClient, namespacedName, &helmRelease)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRelease reconciliation completed")
|
||||
|
||||
logger.Successf("applied revision %s", helmRelease.Status.LastAppliedRevision)
|
||||
return nil
|
||||
func (obj helmReleaseAdapter) getObservedGeneration() int64 {
|
||||
return obj.HelmRelease.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isHelmReleaseResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, helmRelease *helmv2.HelmRelease) wait.ConditionFunc {
|
||||
return func() (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, err
|
||||
}
|
||||
|
||||
if c := apimeta.FindStatusCondition(helmRelease.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
|
||||
}
|
||||
func (obj helmReleaseAdapter) setUnsuspended() {
|
||||
obj.HelmRelease.Spec.Suspend = false
|
||||
}
|
||||
|
||||
func (obj helmReleaseAdapter) successMessage() string {
|
||||
return fmt.Sprintf("applied revision %s", obj.Status.LastAppliedRevision)
|
||||
}
|
||||
|
||||
@@ -17,19 +17,10 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var resumeKsCmd = &cobra.Command{
|
||||
@@ -41,76 +32,24 @@ finish the apply.`,
|
||||
Example: ` # Resume reconciliation for an existing Kustomization
|
||||
flux resume ks podinfo
|
||||
`,
|
||||
RunE: resumeKsCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: kustomizationType,
|
||||
object: kustomizationAdapter{&kustomizev1.Kustomization{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeCmd.AddCommand(resumeKsCmd)
|
||||
}
|
||||
|
||||
func resumeKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("Kustomization name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var kustomization kustomizev1.Kustomization
|
||||
err = kubeClient.Get(ctx, namespacedName, &kustomization)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming Kustomization %s in %s namespace", name, rootArgs.namespace)
|
||||
kustomization.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &kustomization); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("Kustomization resumed")
|
||||
|
||||
logger.Waitingf("waiting for Kustomization reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isKustomizationResumed(ctx, kubeClient, namespacedName, &kustomization)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("Kustomization reconciliation completed")
|
||||
|
||||
logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision)
|
||||
return nil
|
||||
func (obj kustomizationAdapter) getObservedGeneration() int64 {
|
||||
return obj.Kustomization.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isKustomizationResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, kustomization *kustomizev1.Kustomization) wait.ConditionFunc {
|
||||
return func() (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
|
||||
}
|
||||
func (obj kustomizationAdapter) setUnsuspended() {
|
||||
obj.Kustomization.Spec.Suspend = false
|
||||
}
|
||||
|
||||
func (obj kustomizationAdapter) successMessage() string {
|
||||
return fmt.Sprintf("applied revision %s", obj.Status.LastAppliedRevision)
|
||||
}
|
||||
|
||||
@@ -17,20 +17,8 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var resumeSourceBucketCmd = &cobra.Command{
|
||||
@@ -40,76 +28,20 @@ var resumeSourceBucketCmd = &cobra.Command{
|
||||
Example: ` # Resume reconciliation for an existing Bucket
|
||||
flux resume source bucket podinfo
|
||||
`,
|
||||
RunE: resumeSourceBucketCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: bucketType,
|
||||
object: &bucketAdapter{&sourcev1.Bucket{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeSourceCmd.AddCommand(resumeSourceBucketCmd)
|
||||
}
|
||||
|
||||
func resumeSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var bucket sourcev1.Bucket
|
||||
err = kubeClient.Get(ctx, namespacedName, &bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace)
|
||||
bucket.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &bucket); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source resumed")
|
||||
|
||||
logger.Waitingf("waiting for Bucket reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isBucketResumed(ctx, kubeClient, namespacedName, &bucket)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("Bucket reconciliation completed")
|
||||
|
||||
logger.Successf("fetched revision %s", bucket.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj bucketAdapter) getObservedGeneration() int64 {
|
||||
return obj.Bucket.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isBucketResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, bucket *sourcev1.Bucket) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, bucket)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Confirm the state we are observing is for the current generation
|
||||
if bucket.Generation != bucket.Status.ObservedGeneration {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if c := apimeta.FindStatusCondition(bucket.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
|
||||
}
|
||||
func (obj bucketAdapter) setUnsuspended() {
|
||||
obj.Bucket.Spec.Suspend = false
|
||||
}
|
||||
|
||||
@@ -17,20 +17,10 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var resumeSourceHelmChartCmd = &cobra.Command{
|
||||
@@ -40,76 +30,24 @@ var resumeSourceHelmChartCmd = &cobra.Command{
|
||||
Example: ` # Resume reconciliation for an existing HelmChart
|
||||
flux resume source chart podinfo
|
||||
`,
|
||||
RunE: resumeSourceHelmChartCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: helmChartType,
|
||||
object: &helmChartAdapter{&sourcev1.HelmChart{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeSourceCmd.AddCommand(resumeSourceHelmChartCmd)
|
||||
}
|
||||
|
||||
func resumeSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.HelmChart
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace)
|
||||
repository.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &repository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source resumed")
|
||||
|
||||
logger.Waitingf("waiting for HelmChart reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isHelmChartResumed(ctx, kubeClient, namespacedName, &repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmChart reconciliation completed")
|
||||
|
||||
logger.Successf("fetched revision %s", repository.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj helmChartAdapter) getObservedGeneration() int64 {
|
||||
return obj.HelmChart.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isHelmChartResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, chart *sourcev1.HelmChart) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, chart)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Confirm the state we are observing is for the current generation
|
||||
if chart.Generation != chart.Status.ObservedGeneration {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if c := apimeta.FindStatusCondition(chart.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
|
||||
}
|
||||
func (obj helmChartAdapter) setUnsuspended() {
|
||||
obj.HelmChart.Spec.Suspend = false
|
||||
}
|
||||
|
||||
func (obj helmChartAdapter) successMessage() string {
|
||||
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
|
||||
}
|
||||
|
||||
@@ -17,20 +17,8 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var resumeSourceGitCmd = &cobra.Command{
|
||||
@@ -40,76 +28,20 @@ var resumeSourceGitCmd = &cobra.Command{
|
||||
Example: ` # Resume reconciliation for an existing GitRepository
|
||||
flux resume source git podinfo
|
||||
`,
|
||||
RunE: resumeSourceGitCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: gitRepositoryType,
|
||||
object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeSourceCmd.AddCommand(resumeSourceGitCmd)
|
||||
}
|
||||
|
||||
func resumeSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.GitRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace)
|
||||
repository.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &repository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source resumed")
|
||||
|
||||
logger.Waitingf("waiting for GitRepository reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isGitRepositoryResumed(ctx, kubeClient, namespacedName, &repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("GitRepository reconciliation completed")
|
||||
|
||||
logger.Successf("fetched revision %s", repository.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj gitRepositoryAdapter) getObservedGeneration() int64 {
|
||||
return obj.GitRepository.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isGitRepositoryResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.GitRepository) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, repository)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Confirm the state we are observing is for the current generation
|
||||
if repository.Generation != repository.Status.ObservedGeneration {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if c := apimeta.FindStatusCondition(repository.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
|
||||
}
|
||||
func (obj gitRepositoryAdapter) setUnsuspended() {
|
||||
obj.GitRepository.Spec.Suspend = false
|
||||
}
|
||||
|
||||
@@ -17,20 +17,8 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var resumeSourceHelmCmd = &cobra.Command{
|
||||
@@ -40,76 +28,20 @@ var resumeSourceHelmCmd = &cobra.Command{
|
||||
Example: ` # Resume reconciliation for an existing HelmRepository
|
||||
flux resume source helm bitnami
|
||||
`,
|
||||
RunE: resumeSourceHelmCmdRun,
|
||||
RunE: resumeCommand{
|
||||
apiType: helmRepositoryType,
|
||||
object: helmRepositoryAdapter{&sourcev1.HelmRepository{}},
|
||||
}.run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeSourceCmd.AddCommand(resumeSourceHelmCmd)
|
||||
}
|
||||
|
||||
func resumeSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: rootArgs.namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.HelmRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace)
|
||||
repository.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &repository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source resumed")
|
||||
|
||||
logger.Waitingf("waiting for HelmRepository reconciliation")
|
||||
if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout,
|
||||
isHelmRepositoryResumed(ctx, kubeClient, namespacedName, &repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRepository reconciliation completed")
|
||||
|
||||
logger.Successf("fetched revision %s", repository.Status.Artifact.Revision)
|
||||
return nil
|
||||
func (obj helmRepositoryAdapter) getObservedGeneration() int64 {
|
||||
return obj.HelmRepository.Status.ObservedGeneration
|
||||
}
|
||||
|
||||
func isHelmRepositoryResumed(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, repository *sourcev1.HelmRepository) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
err := kubeClient.Get(ctx, namespacedName, repository)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Confirm the state we are observing is for the current generation
|
||||
if repository.Generation != repository.Status.ObservedGeneration {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if c := apimeta.FindStatusCondition(repository.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
|
||||
}
|
||||
func (obj helmRepositoryAdapter) setUnsuspended() {
|
||||
obj.HelmRepository.Spec.Suspend = false
|
||||
}
|
||||
|
||||
@@ -19,13 +19,24 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/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/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
"sigs.k8s.io/cli-utils/pkg/object"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
)
|
||||
|
||||
@@ -39,6 +50,13 @@ type statusable interface {
|
||||
GetStatusConditions() *[]metav1.Condition
|
||||
}
|
||||
|
||||
type StatusChecker struct {
|
||||
pollInterval time.Duration
|
||||
timeout time.Duration
|
||||
client client.Client
|
||||
statusPoller *polling.StatusPoller
|
||||
}
|
||||
|
||||
func isReady(ctx context.Context, kubeClient client.Client,
|
||||
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
@@ -63,3 +81,99 @@ func isReady(ctx context.Context, kubeClient client.Client,
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func NewStatusChecker(pollInterval time.Duration, timeout time.Duration) (*StatusChecker, error) {
|
||||
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
restMapper, err := apiutil.NewDynamicRESTMapper(kubeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := client.New(kubeConfig, client.Options{Mapper: restMapper})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &StatusChecker{
|
||||
pollInterval: pollInterval,
|
||||
timeout: timeout,
|
||||
client: client,
|
||||
statusPoller: polling.NewStatusPoller(client, restMapper),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (sc *StatusChecker) Assess(components ...string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
||||
defer cancel()
|
||||
|
||||
objRefs, err := sc.getObjectRefs(components)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts := polling.Options{PollInterval: sc.pollInterval, UseCache: true}
|
||||
eventsChan := sc.statusPoller.Poll(ctx, objRefs, opts)
|
||||
|
||||
coll := collector.NewResourceStatusCollector(objRefs)
|
||||
done := coll.ListenWithObserver(eventsChan, collector.ObserverFunc(
|
||||
func(statusCollector *collector.ResourceStatusCollector, e event.Event) {
|
||||
var rss []*event.ResourceStatus
|
||||
for _, rs := range statusCollector.ResourceStatuses {
|
||||
rss = append(rss, rs)
|
||||
}
|
||||
desired := status.CurrentStatus
|
||||
aggStatus := aggregator.AggregateStatus(rss, desired)
|
||||
if aggStatus == desired {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
}),
|
||||
)
|
||||
<-done
|
||||
|
||||
if coll.Error != nil || ctx.Err() == context.DeadlineExceeded {
|
||||
for _, rs := range coll.ResourceStatuses {
|
||||
if rs.Status != status.CurrentStatus {
|
||||
if !sc.deploymentExists(rs.Identifier) {
|
||||
logger.Failuref("%s: deployment not found", rs.Identifier.Name)
|
||||
} else {
|
||||
logger.Failuref("%s: unhealthy (timed out waiting for rollout)", rs.Identifier.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("timed out waiting for condition")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *StatusChecker) getObjectRefs(components []string) ([]object.ObjMetadata, error) {
|
||||
var objRefs []object.ObjMetadata
|
||||
for _, deployment := range components {
|
||||
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
objRefs = append(objRefs, objMeta)
|
||||
}
|
||||
return objRefs, nil
|
||||
}
|
||||
|
||||
func (sc *StatusChecker) objMetadataToString(om object.ObjMetadata) string {
|
||||
return fmt.Sprintf("%s '%s/%s'", om.GroupKind.Kind, om.Namespace, om.Name)
|
||||
}
|
||||
|
||||
func (sc *StatusChecker) deploymentExists(om object.ObjMetadata) bool {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
||||
defer cancel()
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: om.Namespace,
|
||||
Name: om.Name,
|
||||
}
|
||||
var existing appsv1.Deployment
|
||||
err := sc.client.Get(ctx, namespacedName, &existing)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -25,9 +25,10 @@ flux check [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
-h, --help help for check
|
||||
--pre only run pre-installation checks
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
--components-extra strings list of components in addition to those supplied or defaulted, accepts comma-separated values
|
||||
-h, --help help for check
|
||||
--pre only run pre-installation checks
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
@@ -32,11 +32,12 @@ flux create helmrelease [name] [flags]
|
||||
--source=Bucket/podinfo \
|
||||
--chart=./charts/podinfo
|
||||
|
||||
# Create a HelmRelease with values from a local YAML file
|
||||
# Create a HelmRelease with values from local YAML files
|
||||
flux create hr podinfo \
|
||||
--source=HelmRepository/podinfo \
|
||||
--chart=podinfo \
|
||||
--values=./my-values.yaml
|
||||
--values=./my-values1.yaml \
|
||||
--values=./my-values2.yaml
|
||||
|
||||
# Create a HelmRelease with values from a Kubernetes secret
|
||||
kubectl -n app create secret generic my-secret-values \
|
||||
@@ -78,7 +79,7 @@ flux create helmrelease [name] [flags]
|
||||
--service-account string the name of the service account to impersonate when reconciling this HelmRelease
|
||||
--source helmChartSource source that contains the chart in the format '<kind>/<name>', where kind must be one of: (HelmRepository, GitRepository, Bucket)
|
||||
--target-namespace string namespace to install this release, defaults to the HelmRelease namespace
|
||||
--values string local path to the values.yaml file
|
||||
--values stringArray local path to values.yaml files
|
||||
--values-from helmReleaseValuesFrom Kubernetes object reference that contains the values.yaml data key in the format '<kind>/<name>', where kind must be one of: (Secret, ConfigMap)
|
||||
```
|
||||
|
||||
|
||||
@@ -11,9 +11,40 @@ An ImageRepository object specifies an image repository to scan.
|
||||
flux create image repository <name> [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Create an ImageRepository object to scan the alpine image repository:
|
||||
flux create image repository alpine-repo --image alpine --interval 20m
|
||||
|
||||
# Create an image repository that uses an image pull secret (assumed to
|
||||
# have been created already):
|
||||
flux create image repository myapp-repo \
|
||||
--secret-ref image-pull \
|
||||
--image ghcr.io/example.com/myapp --interval 5m
|
||||
|
||||
# Create a TLS secret for a local image registry using a self-signed
|
||||
# host certificate, and use it to scan an image. ca.pem is a file
|
||||
# containing the CA certificate used to sign the host certificate.
|
||||
flux create secret tls local-registry-cert --ca-file ./ca.pem
|
||||
flux create image repository app-repo \
|
||||
--cert-secret-ref local-registry-cert \
|
||||
--image local-registry:5000/app --interval 5m
|
||||
|
||||
# Create a TLS secret with a client certificate and key, and use it
|
||||
# to scan a private image registry.
|
||||
flux create secret tls client-cert \
|
||||
--cert-file client.crt --key-file client.key
|
||||
flux create image repository app-repo \
|
||||
--cert-secret-ref client-cert \
|
||||
--image registry.example.com/private/app --interval 5m
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--cert-ref string the name of a secret to use for TLS certificates
|
||||
-h, --help help for repository
|
||||
--image string the image repository to scan; e.g., library/alpine
|
||||
--scan-timeout duration a timeout for scanning; this defaults to the interval if not set
|
||||
|
||||
@@ -28,8 +28,8 @@ The delete sub-commands delete sources and resources.
|
||||
* [flux](flux.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [flux delete alert](flux_delete_alert.md) - Delete a Alert resource
|
||||
* [flux delete alert-provider](flux_delete_alert-provider.md) - Delete a Provider resource
|
||||
* [flux delete auto](flux_delete_auto.md) - Delete automation objects
|
||||
* [flux delete helmrelease](flux_delete_helmrelease.md) - Delete a HelmRelease resource
|
||||
* [flux delete image](flux_delete_image.md) - Delete image automation objects
|
||||
* [flux delete kustomization](flux_delete_kustomization.md) - Delete a Kustomization resource
|
||||
* [flux delete receiver](flux_delete_receiver.md) - Delete a Receiver resource
|
||||
* [flux delete source](flux_delete_source.md) - Delete sources
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
## flux delete auto
|
||||
## flux delete image
|
||||
|
||||
Delete automation objects
|
||||
Delete image automation objects
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete auto sub-commands delete automation objects.
|
||||
The delete image sub-commands delete image automation objects.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for auto
|
||||
-h, --help help for image
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -26,7 +26,7 @@ The delete auto sub-commands delete automation objects.
|
||||
### SEE ALSO
|
||||
|
||||
* [flux delete](flux_delete.md) - Delete sources and resources
|
||||
* [flux delete auto image-policy](flux_delete_auto_image-policy.md) - Delete an ImagePolicy object
|
||||
* [flux delete auto image-repository](flux_delete_auto_image-repository.md) - Delete an ImageRepository object
|
||||
* [flux delete auto image-update](flux_delete_auto_image-update.md) - Delete an ImageUpdateAutomation object
|
||||
* [flux delete image policy](flux_delete_image_policy.md) - Delete an ImagePolicy object
|
||||
* [flux delete image repository](flux_delete_image_repository.md) - Delete an ImageRepository object
|
||||
* [flux delete image update](flux_delete_image_update.md) - Delete an ImageUpdateAutomation object
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
## flux delete auto image-policy
|
||||
## flux delete image policy
|
||||
|
||||
Delete an ImagePolicy object
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete auto image-policy command deletes the given ImagePolicy from the cluster.
|
||||
The delete image policy command deletes the given ImagePolicy from the cluster.
|
||||
|
||||
```
|
||||
flux delete auto image-policy [name] [flags]
|
||||
flux delete image policy [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete an image policy
|
||||
flux delete auto image-policy alpine3.x
|
||||
flux delete image policy alpine3.x
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for image-policy
|
||||
-h, --help help for policy
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -37,5 +37,5 @@ flux delete auto image-policy [name] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux delete auto](flux_delete_auto.md) - Delete automation objects
|
||||
* [flux delete image](flux_delete_image.md) - Delete image automation objects
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
## flux delete auto image-repository
|
||||
## flux delete image repository
|
||||
|
||||
Delete an ImageRepository object
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete auto image-repository command deletes the given ImageRepository from the cluster.
|
||||
The delete image repository command deletes the given ImageRepository from the cluster.
|
||||
|
||||
```
|
||||
flux delete auto image-repository [name] [flags]
|
||||
flux delete image repository [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete an image repository
|
||||
flux delete auto image-repository alpine
|
||||
flux delete image repository alpine
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for image-repository
|
||||
-h, --help help for repository
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -37,5 +37,5 @@ flux delete auto image-repository [name] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux delete auto](flux_delete_auto.md) - Delete automation objects
|
||||
* [flux delete image](flux_delete_image.md) - Delete image automation objects
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
## flux delete auto image-update
|
||||
## flux delete image update
|
||||
|
||||
Delete an ImageUpdateAutomation object
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete auto image-update command deletes the given ImageUpdateAutomation from the cluster.
|
||||
The delete image update command deletes the given ImageUpdateAutomation from the cluster.
|
||||
|
||||
```
|
||||
flux delete auto image-update [name] [flags]
|
||||
flux delete image update [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete an image update automation
|
||||
flux delete auto image-update latest-images
|
||||
flux delete image update latest-images
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for image-update
|
||||
-h, --help help for update
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -37,5 +37,5 @@ flux delete auto image-update [name] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux delete auto](flux_delete_auto.md) - Delete automation objects
|
||||
* [flux delete image](flux_delete_image.md) - Delete image automation objects
|
||||
|
||||
@@ -29,7 +29,7 @@ The get sub-commands print the statuses of sources and resources.
|
||||
* [flux get alert-providers](flux_get_alert-providers.md) - Get Provider statuses
|
||||
* [flux get alerts](flux_get_alerts.md) - Get Alert statuses
|
||||
* [flux get helmreleases](flux_get_helmreleases.md) - Get HelmRelease statuses
|
||||
* [flux get image](flux_get_image.md) - Get image automation object status
|
||||
* [flux get images](flux_get_images.md) - Get image automation object status
|
||||
* [flux get kustomizations](flux_get_kustomizations.md) - Get Kustomization statuses
|
||||
* [flux get receivers](flux_get_receivers.md) - Get Receiver statuses
|
||||
* [flux get sources](flux_get_sources.md) - Get source statuses
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## flux get image
|
||||
## flux get images
|
||||
|
||||
Get image automation object status
|
||||
|
||||
@@ -9,7 +9,7 @@ The get image sub-commands print the status of image automation objects.
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for image
|
||||
-h, --help help for images
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -26,7 +26,7 @@ The get image sub-commands print the status of image automation objects.
|
||||
### SEE ALSO
|
||||
|
||||
* [flux get](flux_get.md) - Get sources and resources
|
||||
* [flux get image policy](flux_get_image_policy.md) - Get ImagePolicy status
|
||||
* [flux get image repository](flux_get_image_repository.md) - Get ImageRepository status
|
||||
* [flux get image update](flux_get_image_update.md) - Get ImageUpdateAutomation status
|
||||
* [flux get images policy](flux_get_images_policy.md) - Get ImagePolicy status
|
||||
* [flux get images repository](flux_get_images_repository.md) - Get ImageRepository status
|
||||
* [flux get images update](flux_get_images_update.md) - Get ImageUpdateAutomation status
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## flux get image policy
|
||||
## flux get images policy
|
||||
|
||||
Get ImagePolicy status
|
||||
|
||||
@@ -7,7 +7,7 @@ Get ImagePolicy status
|
||||
The get image policy command prints the status of ImagePolicy objects.
|
||||
|
||||
```
|
||||
flux get image policy [flags]
|
||||
flux get images policy [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
@@ -40,5 +40,5 @@ flux get image policy [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux get image](flux_get_image.md) - Get image automation object status
|
||||
* [flux get images](flux_get_images.md) - Get image automation object status
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## flux get image repository
|
||||
## flux get images repository
|
||||
|
||||
Get ImageRepository status
|
||||
|
||||
@@ -7,7 +7,7 @@ Get ImageRepository status
|
||||
The get image repository command prints the status of ImageRepository objects.
|
||||
|
||||
```
|
||||
flux get image repository [flags]
|
||||
flux get images repository [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
@@ -40,5 +40,5 @@ flux get image repository [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux get image](flux_get_image.md) - Get image automation object status
|
||||
* [flux get images](flux_get_images.md) - Get image automation object status
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## flux get image update
|
||||
## flux get images update
|
||||
|
||||
Get ImageUpdateAutomation status
|
||||
|
||||
@@ -7,7 +7,7 @@ Get ImageUpdateAutomation status
|
||||
The get image update command prints the status of ImageUpdateAutomation objects.
|
||||
|
||||
```
|
||||
flux get image update [flags]
|
||||
flux get images update [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
@@ -40,5 +40,5 @@ flux get image update [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [flux get image](flux_get_image.md) - Get image automation object status
|
||||
* [flux get images](flux_get_images.md) - Get image automation object status
|
||||
|
||||
@@ -1,98 +1,5 @@
|
||||
# Frequently asked questions
|
||||
|
||||
## General questions
|
||||
|
||||
### What does Flux v2 mean for Flux?
|
||||
|
||||
Flux v1 is a monolithic do-it-all operator; Flux v2 separates the functionalities into specialized controllers, collectively called the GitOps Toolkit.
|
||||
|
||||
You can install and operate Flux v2 simply using the `flux` command. You can easily pick and choose the functionality you need and extend it to serve your own purposes.
|
||||
|
||||
The timeline we are looking at right now is:
|
||||
|
||||
1. Put Flux v1 into maintenance mode (no new features being added; bugfixes and CVEs patched only).
|
||||
1. Continue work on the [Flux v2 roadmap](https://toolkit.fluxcd.io/roadmap/).
|
||||
1. We will provide transition guides for specific user groups, e.g. users of Flux v1 in read-only mode, or of Helm Operator v1, etc. once the functionality is integrated into Flux v2 and it's deemed "ready".
|
||||
1. Once the use-cases of Flux v1 are covered, we will continue supporting Flux v1 for 6 months. This will be the transition period before it's considered unsupported.
|
||||
|
||||
### Why did you rewrite Flux?
|
||||
|
||||
Flux v2 implements its functionality in individual controllers, which allowed us to address long-standing feature requests much more easily.
|
||||
|
||||
By basing these controllers on modern Kubernetes tooling (`controller-runtime` libraries), they can be dynamically configured with Kubernetes custom resources either by cluster admins or by other automated tools -- and you get greatly increased observability.
|
||||
|
||||
This gave us the opportunity to build Flux v2 with the top Flux v1 feature requests in mind:
|
||||
|
||||
- Supporting multiple source Git repositories
|
||||
- Operational insight through health checks, events and alerts
|
||||
- Multi-tenancy capabilities, like applying each source repository with its own set of permissions
|
||||
|
||||
On top of that, testing the individual components and understanding the codebase becomes a lot easier.
|
||||
|
||||
### What are significant new differences between Flux v1 and Flux v2?
|
||||
|
||||
#### Reconciliation
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Limited to a single Git repository | Multiple Git repositories
|
||||
Declarative config via arguments in the Flux deployment | `GitRepository` custom resource, which produces an artifact which can be reconciled by other controllers
|
||||
Follow `HEAD` of Git branches | Supports Git branches, pinning on commits and tags, follow SemVer tag ranges
|
||||
Suspending of reconciliation by downscaling Flux deployment | Reconciliation can be paused per resource by suspending the `GitRepository`
|
||||
Credentials config via Arguments and/or Secret volume mounts in the Flux pod | Credentials config per `GitRepository` resource: SSH private key, HTTP/S username/password/token, OpenPGP public keys
|
||||
|
||||
#### `kustomize` support
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config through `.flux.yaml` files in the Git repository | Declarative config through a `Kustomization` custom resource, consuming the artifact from the GitRepository
|
||||
Manifests are generated via shell exec and then reconciled by `fluxd` | Generation, server-side validation, and reconciliation is handled by a specialised `kustomize-controller`
|
||||
Reconciliation using the service account of the Flux deployment | Support for service account impersonation
|
||||
Garbage collection needs cluster role binding for Flux to query the Kubernetes discovery API | Garbage collection needs no cluster role binding or access to Kubernetes discovery API
|
||||
Support for custom commands and generators executed by fluxd in a POSIX shell | No support for custom commands
|
||||
|
||||
#### Helm integration
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config in a single Helm custom resource | Declarative config through `HelmRepository`, `GitRepository`, `Bucket`, `HelmChart` and `HelmRelease` custom resources
|
||||
Chart synchronisation embedded in the operator | Extensive release configuration options, and a reconciliation interval per source
|
||||
Support for fixed SemVer versions from Helm repositories | Support for SemVer ranges for `HelmChart` resources
|
||||
Git repository synchronisation on a global interval | Planned support for charts from GitRepository sources
|
||||
Limited observability via the status object of the HelmRelease resource | Better observability via the HelmRelease status object, Kubernetes events, and notifications
|
||||
Resource heavy, relatively slow | Better performance
|
||||
Chart changes from Git sources are determined from Git metadata | Chart changes must be accompanied by a version bump in `Chart.yaml` to produce a new artifact
|
||||
|
||||
#### Notifications, webhooks, observability
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Emits "custom Flux events" to a webhook endpoint | Emits Kubernetes events for included custom resources
|
||||
RPC endpoint can be configured to a 3rd party solution like FluxCloud to be forwarded as notifications to e.g. Slack | Flux v2 components can be configured to POST the events to a `notification-controller` endpoint. Selective forwarding of POSTed events as notifications using `Provider` and `Alert` custom resources.
|
||||
Webhook receiver is a side-project | Webhook receiver, handling a wide range of platforms, is included
|
||||
Unstructured logging | Structured logging for all components
|
||||
Custom Prometheus metrics | Generic / common `controller-runtime` Prometheus metrics
|
||||
|
||||
### How can I get involved?
|
||||
|
||||
There are a variety of ways and we look forward to having you on board building the future of GitOps together:
|
||||
|
||||
- [Discuss the direction](https://github.com/fluxcd/flux2/discussions) of Flux v2 with us
|
||||
- Join us in #flux-dev on the [CNCF Slack](https://slack.cncf.io)
|
||||
- Check out our [contributor docs](https://toolkit.fluxcd.io/contributing/)
|
||||
- Take a look at the [roadmap for Flux v2](https://toolkit.fluxcd.io/roadmap/)
|
||||
|
||||
### Are there any breaking changes?
|
||||
|
||||
- In Flux v1 Kustomize support was implemented through `.flux.yaml` files in the Git repository. As indicated in the comparison table above, while this approach worked, we found it to be error-prone and hard to debug. The new [Kustomization CR](https://github.com/fluxcd/kustomize-controller/blob/master/docs/spec/v1alpha1/kustomization.md) should make troubleshooting much easier. Unfortunately we needed to drop the support for custom commands as running arbitrary shell scripts in-cluster poses serious security concerns.
|
||||
- Helm users: we redesigned the `HelmRelease` API and the automation will work quite differently, so upgrading to `HelmRelease` v2 will require a little work from you, but you will gain more flexibility, better observability and performance.
|
||||
|
||||
### Is the GitOps Toolkit related to the GitOps Engine?
|
||||
|
||||
In an announcement in August 2019, the expectation was set that the Flux project would integrate the GitOps Engine, then being factored out of ArgoCD. Since the result would be backward-incompatible, it would require a major version bump: Flux v2.
|
||||
|
||||
After experimentation and considerable thought, we (the maintainers) have found a path to Flux v2 that we think better serves our vision of GitOps: the GitOps Toolkit. In consequence, we do not now plan to integrate GitOps Engine into Flux.
|
||||
|
||||
## Kustomize questions
|
||||
|
||||
### Are there two Kustomization types?
|
||||
@@ -242,3 +149,127 @@ The kustomize-controller creates `kustomization.yaml` files similar to:
|
||||
```sh
|
||||
cd ./deploy/prod && kustomize create --autodetect --recursive
|
||||
```
|
||||
|
||||
## Helm questions
|
||||
|
||||
### How to debug "not ready" errors?
|
||||
|
||||
Misconfiguring the `HelmRelease.spec.chart`, like a typo in the chart name, version or chart source URL
|
||||
would result in a "HelmChart is not ready" error displayed by:
|
||||
|
||||
```console
|
||||
$ flux get helmreleases --all-namespaces
|
||||
NAMESPACE NAME READY MESSAGE
|
||||
default podinfo False HelmChart 'default/default-podinfo' is not ready
|
||||
```
|
||||
|
||||
In order to get to the root cause, first make sure the source e.g. the `HelmRepository`
|
||||
is configured properly and has access to the remote `index.yaml`:
|
||||
|
||||
```console
|
||||
$ flux get sources helm --all-namespaces
|
||||
NAMESPACE NAME READY MESSAGE
|
||||
default podinfo False failed to fetch https://stefanprodan.github.io/podinfo2/index.yaml : 404 Not Found
|
||||
```
|
||||
|
||||
If the source is `Ready`, then the error must be caused by the chart,
|
||||
for example due to an invalid chart name or non-existing version:
|
||||
|
||||
```console
|
||||
$ flux get sources chart --all-namespaces
|
||||
NAMESPACE NAME READY MESSAGE
|
||||
default default-podinfo False no chart version found for podinfo-9.0.0
|
||||
```
|
||||
|
||||
## Flux v1 vs v2 questions
|
||||
|
||||
### What does Flux v2 mean for Flux?
|
||||
|
||||
Flux v1 is a monolithic do-it-all operator; Flux v2 separates the functionalities into specialized controllers, collectively called the GitOps Toolkit.
|
||||
|
||||
You can install and operate Flux v2 simply using the `flux` command. You can easily pick and choose the functionality you need and extend it to serve your own purposes.
|
||||
|
||||
The timeline we are looking at right now is:
|
||||
|
||||
1. Put Flux v1 into maintenance mode (no new features being added; bugfixes and CVEs patched only).
|
||||
1. Continue work on the [Flux v2 roadmap](https://toolkit.fluxcd.io/roadmap/).
|
||||
1. We will provide transition guides for specific user groups, e.g. users of Flux v1 in read-only mode, or of Helm Operator v1, etc. once the functionality is integrated into Flux v2 and it's deemed "ready".
|
||||
1. Once the use-cases of Flux v1 are covered, we will continue supporting Flux v1 for 6 months. This will be the transition period before it's considered unsupported.
|
||||
|
||||
### Why did you rewrite Flux?
|
||||
|
||||
Flux v2 implements its functionality in individual controllers, which allowed us to address long-standing feature requests much more easily.
|
||||
|
||||
By basing these controllers on modern Kubernetes tooling (`controller-runtime` libraries), they can be dynamically configured with Kubernetes custom resources either by cluster admins or by other automated tools -- and you get greatly increased observability.
|
||||
|
||||
This gave us the opportunity to build Flux v2 with the top Flux v1 feature requests in mind:
|
||||
|
||||
- Supporting multiple source Git repositories
|
||||
- Operational insight through health checks, events and alerts
|
||||
- Multi-tenancy capabilities, like applying each source repository with its own set of permissions
|
||||
|
||||
On top of that, testing the individual components and understanding the codebase becomes a lot easier.
|
||||
|
||||
### What are significant new differences between Flux v1 and Flux v2?
|
||||
|
||||
#### Reconciliation
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Limited to a single Git repository | Multiple Git repositories
|
||||
Declarative config via arguments in the Flux deployment | `GitRepository` custom resource, which produces an artifact which can be reconciled by other controllers
|
||||
Follow `HEAD` of Git branches | Supports Git branches, pinning on commits and tags, follow SemVer tag ranges
|
||||
Suspending of reconciliation by downscaling Flux deployment | Reconciliation can be paused per resource by suspending the `GitRepository`
|
||||
Credentials config via Arguments and/or Secret volume mounts in the Flux pod | Credentials config per `GitRepository` resource: SSH private key, HTTP/S username/password/token, OpenPGP public keys
|
||||
|
||||
#### `kustomize` support
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config through `.flux.yaml` files in the Git repository | Declarative config through a `Kustomization` custom resource, consuming the artifact from the GitRepository
|
||||
Manifests are generated via shell exec and then reconciled by `fluxd` | Generation, server-side validation, and reconciliation is handled by a specialised `kustomize-controller`
|
||||
Reconciliation using the service account of the Flux deployment | Support for service account impersonation
|
||||
Garbage collection needs cluster role binding for Flux to query the Kubernetes discovery API | Garbage collection needs no cluster role binding or access to Kubernetes discovery API
|
||||
Support for custom commands and generators executed by fluxd in a POSIX shell | No support for custom commands
|
||||
|
||||
#### Helm integration
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config in a single Helm custom resource | Declarative config through `HelmRepository`, `GitRepository`, `Bucket`, `HelmChart` and `HelmRelease` custom resources
|
||||
Chart synchronisation embedded in the operator | Extensive release configuration options, and a reconciliation interval per source
|
||||
Support for fixed SemVer versions from Helm repositories | Support for SemVer ranges for `HelmChart` resources
|
||||
Git repository synchronisation on a global interval | Planned support for charts from GitRepository sources
|
||||
Limited observability via the status object of the HelmRelease resource | Better observability via the HelmRelease status object, Kubernetes events, and notifications
|
||||
Resource heavy, relatively slow | Better performance
|
||||
Chart changes from Git sources are determined from Git metadata | Chart changes must be accompanied by a version bump in `Chart.yaml` to produce a new artifact
|
||||
|
||||
#### Notifications, webhooks, observability
|
||||
|
||||
Flux v1 | Flux v2
|
||||
---------------------------------- | ----------------------------------
|
||||
Emits "custom Flux events" to a webhook endpoint | Emits Kubernetes events for included custom resources
|
||||
RPC endpoint can be configured to a 3rd party solution like FluxCloud to be forwarded as notifications to e.g. Slack | Flux v2 components can be configured to POST the events to a `notification-controller` endpoint. Selective forwarding of POSTed events as notifications using `Provider` and `Alert` custom resources.
|
||||
Webhook receiver is a side-project | Webhook receiver, handling a wide range of platforms, is included
|
||||
Unstructured logging | Structured logging for all components
|
||||
Custom Prometheus metrics | Generic / common `controller-runtime` Prometheus metrics
|
||||
|
||||
### How can I get involved?
|
||||
|
||||
There are a variety of ways and we look forward to having you on board building the future of GitOps together:
|
||||
|
||||
- [Discuss the direction](https://github.com/fluxcd/flux2/discussions) of Flux v2 with us
|
||||
- Join us in #flux-dev on the [CNCF Slack](https://slack.cncf.io)
|
||||
- Check out our [contributor docs](https://toolkit.fluxcd.io/contributing/)
|
||||
- Take a look at the [roadmap for Flux v2](https://toolkit.fluxcd.io/roadmap/)
|
||||
|
||||
### Are there any breaking changes?
|
||||
|
||||
- In Flux v1 Kustomize support was implemented through `.flux.yaml` files in the Git repository. As indicated in the comparison table above, while this approach worked, we found it to be error-prone and hard to debug. The new [Kustomization CR](https://github.com/fluxcd/kustomize-controller/blob/master/docs/spec/v1alpha1/kustomization.md) should make troubleshooting much easier. Unfortunately we needed to drop the support for custom commands as running arbitrary shell scripts in-cluster poses serious security concerns.
|
||||
- Helm users: we redesigned the `HelmRelease` API and the automation will work quite differently, so upgrading to `HelmRelease` v2 will require a little work from you, but you will gain more flexibility, better observability and performance.
|
||||
|
||||
### Is the GitOps Toolkit related to the GitOps Engine?
|
||||
|
||||
In an announcement in August 2019, the expectation was set that the Flux project would integrate the GitOps Engine, then being factored out of ArgoCD. Since the result would be backward-incompatible, it would require a major version bump: Flux v2.
|
||||
|
||||
After experimentation and considerable thought, we (the maintainers) have found a path to Flux v2 that we think better serves our vision of GitOps: the GitOps Toolkit. In consequence, we do not now plan to integrate GitOps Engine into Flux.
|
||||
|
||||
@@ -5,7 +5,7 @@ This guide walks you through configuring container image scanning and deployment
|
||||
For a container image you can configure Flux to:
|
||||
|
||||
- scan the container registry and fetch the image tags
|
||||
- select the latest tag based on a semver range
|
||||
- select the latest tag based on the defined policy (semver, calver, regex)
|
||||
- replace the tag in Kubernetes manifests (YAML format)
|
||||
- checkout a branch, commit and push the changes to the remote Git repository
|
||||
- apply the changes in-cluster and rollout the container image
|
||||
@@ -17,10 +17,7 @@ For a container image you can configure Flux to:
|
||||
For production environments, this feature allows you to automatically deploy application patches
|
||||
(CVEs and bug fixes), and keep a record of all deployments in Git history.
|
||||
|
||||
For staging environments, this features allow you to deploy the latest prerelease of an application,
|
||||
without having to manually edit its deployment manifests in Git.
|
||||
|
||||
Production CI/CD workflow:
|
||||
**Production CI/CD workflow**
|
||||
|
||||
* DEV: push a bug fix to the app repository
|
||||
* DEV: bump the patch version and release e.g. `v1.0.1`
|
||||
@@ -29,6 +26,17 @@ Production CI/CD workflow:
|
||||
* CD: update the image tag in the app manifest to `v1.0.1` (Flux cluster to Git reconciliation)
|
||||
* CD: deploy `v1.0.1` to production clusters (Flux Git to cluster reconciliation)
|
||||
|
||||
For staging environments, this features allow you to deploy the latest build of a branch,
|
||||
without having to manually edit the app deployment manifest in Git.
|
||||
|
||||
**Staging CI/CD workflow**
|
||||
|
||||
* DEV: push code changes to the app repository `main` branch
|
||||
* CI: build and push a container image tagged as `${GIT_BRANCH}-${GIT_SHA:0:7}-$(date +%s)`
|
||||
* CD: pull the latest image metadata from the app registry (Flux image scanning)
|
||||
* CD: update the image tag in the app manifest to `main-2d3fcbd-1611906956` (Flux cluster to Git reconciliation)
|
||||
* CD: deploy `main-2d3fcbd-1611906956` to staging clusters (Flux Git to cluster reconciliation)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need a Kubernetes cluster version 1.16 or newer and kubectl version 1.18.
|
||||
@@ -48,6 +56,11 @@ export GITHUB_USER=<your-username>
|
||||
|
||||
## Install Flux
|
||||
|
||||
!!! hint "Enable image automation components"
|
||||
If you bootstrapped Flux before without the `--components-extra=` argument, you need to add
|
||||
`--components-extra=image-reflector-controller,image-automation-controller` to your
|
||||
bootstrapping routine as image automation components are not installed by default.
|
||||
|
||||
Install Flux with the image automation components:
|
||||
|
||||
```sh
|
||||
@@ -260,7 +273,7 @@ spec:
|
||||
messageTemplate: '[ci skip] update image'
|
||||
interval: 1m0s
|
||||
update:
|
||||
setters: {}
|
||||
strategy: Setters
|
||||
```
|
||||
|
||||
Commit and push changes to main branch:
|
||||
@@ -362,6 +375,60 @@ images:
|
||||
newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
|
||||
```
|
||||
|
||||
## Trigger image updates with webhooks
|
||||
|
||||
You may want to trigger a deployment
|
||||
as soon as a new image tag is pushed to your container registry.
|
||||
In order to notify the image-reflector-controller about new images,
|
||||
you can [setup webhook receivers](webhook-receivers.md).
|
||||
|
||||
First generate a random string and create a secret with a `token` field:
|
||||
|
||||
```sh
|
||||
TOKEN=$(head -c 12 /dev/urandom | shasum | cut -d ' ' -f1)
|
||||
echo $TOKEN
|
||||
|
||||
kubectl -n flux-system create secret generic webhook-token \
|
||||
--from-literal=token=$TOKEN
|
||||
```
|
||||
|
||||
Define a receiver for DockerHub:
|
||||
|
||||
```yaml
|
||||
apiVersion: notification.toolkit.fluxcd.io/v1beta1
|
||||
kind: Receiver
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
type: dockerhub
|
||||
secretRef:
|
||||
name: webhook-token
|
||||
resources:
|
||||
- kind: ImageRepository
|
||||
name: podinfo
|
||||
```
|
||||
|
||||
The notification-controller generates a unique URL using the provided token and the receiver name/namespace.
|
||||
|
||||
Find the URL with:
|
||||
|
||||
```console
|
||||
$ kubectl -n flux-system get receiver/podinfo
|
||||
|
||||
NAME READY STATUS
|
||||
podinfo True Receiver initialised with URL: /hook/bed6d00b5555b1603e1f59b94d7fdbca58089cb5663633fb83f2815dc626d92b
|
||||
```
|
||||
|
||||
Log in to DockerHub web interface, go to your image registry Settings and select Webhooks.
|
||||
Fill the form "Webhook URL" by composing the address using the receiver
|
||||
LB and the generated URL `http://<LoadBalancerAddress>/<ReceiverURL>`.
|
||||
|
||||
!!! hint "Note"
|
||||
Besides DockerHub, you can define receivers for **Harbor**, **Quay**, **Nexus**, **GCR**,
|
||||
and any other system that supports webhooks e.g. GitHub Actions, Jenkins, CircleCI, etc.
|
||||
See the [Receiver CRD docs](../components/notification/receiver.md) for more details.
|
||||
|
||||
## ImageRepository cloud providers authentication
|
||||
|
||||
If relying on a cloud provider image repository, you might need to do some extra
|
||||
@@ -417,6 +484,7 @@ apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ecr-credentials-sync
|
||||
namespace: flux-system
|
||||
# Uncomment and edit if using IRSA
|
||||
# annotations:
|
||||
# eks.amazonaws.com/role-arn: <role arn>
|
||||
@@ -466,8 +534,8 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: SECRET_NAME
|
||||
value: <secret name> # this is the generated Secret name
|
||||
- name:
|
||||
value: ecr-credentials
|
||||
- name: ECR_REGISTRY
|
||||
value: <account id>.dkr.ecr.<region>.amazonaws.com # fill in the account id and region
|
||||
volumeMounts:
|
||||
- mountPath: /token
|
||||
@@ -496,15 +564,26 @@ you can manually create an init job using the following command:
|
||||
$ kubectl create job --from=cronjob/ecr-credentials-sync -n flux-system ecr-credentials-sync-init
|
||||
```
|
||||
|
||||
After the job runs, a secret named `ecr-credentials` should be created. Use this
|
||||
name in your ECR ImageRepository resource manifest as the value for
|
||||
`.spec.secretRef.name`.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
secretRef:
|
||||
name: ecr-credentials
|
||||
```
|
||||
|
||||
### GCP Container Registry
|
||||
|
||||
#### Using access token [short-lived]
|
||||
|
||||
!!!note "Workload Identity"
|
||||
Please ensure that you enable workload identity for your cluster, create a GCP service account that has access to the container registry and create an IAM policy binding between the GCP service account and the Kubernetes service account so that the pods created by the cronjob can access GCP APIs and get the token.
|
||||
Please ensure that you enable workload identity for your cluster, create a GCP service account that has
|
||||
access to the container registry and create an IAM policy binding between the GCP service account and
|
||||
the Kubernetes service account so that the pods created by the cronjob can access GCP APIs and get the token.
|
||||
Take a look at [this guide](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
|
||||
|
||||
|
||||
The access token for GCR expires hourly.
|
||||
Considering this limitation, one needs to ensure the credentials are being
|
||||
refreshed before expiration so that the controller can rely on them for
|
||||
@@ -573,7 +652,7 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: SECRET_NAME
|
||||
value: <SECRET_NAME> # this is the generated Secret name
|
||||
value: gcr-credentials
|
||||
- name: GCR_REGISTRY
|
||||
value: <REGISTRY_NAME> # fill in the registry name e.g gcr.io, eu.gcr.io
|
||||
command:
|
||||
@@ -594,18 +673,37 @@ you can manually create an init job using the following command:
|
||||
$ kubectl create job --from=cronjob/gcr-credentials-sync -n flux-system gcr-credentials-sync-init
|
||||
```
|
||||
|
||||
After the job runs, a secret named `gcr-credentials` should be created. Use this
|
||||
name in your GCR ImageRepository resource manifest as the value for
|
||||
`.spec.secretRef.name`.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
secretRef:
|
||||
name: gcr-credentials
|
||||
```
|
||||
|
||||
#### Using a JSON key [long-lived]
|
||||
|
||||
!!! warning "Less secure option"
|
||||
From [Google documentation on authenticating container registry](https://cloud.google.com/container-registry/docs/advanced-authentication#json-key)
|
||||
> A user-managed key-pair that you can use as a credential for a service account. Because the credential is long-lived, it is the least secure option of all the available authentication methods. When possible, use an access token or another available authentication method to reduce the risk of unauthorized access to your artifacts. If you must use a service account key, ensure that you follow best practices for managing credentials.
|
||||
> A user-managed key-pair that you can use as a credential for a service account.
|
||||
> Because the credential is long-lived, it is the least secure option of all the available authentication methods.
|
||||
> When possible, use an access token or another available authentication method to reduce the risk of
|
||||
> unauthorized access to your artifacts. If you must use a service account key,
|
||||
> ensure that you follow best practices for managing credentials.
|
||||
|
||||
A Json key doesn't expire, so we don't need a cronjob,
|
||||
we just need to create the secret and reference it in the ImagePolicy.
|
||||
|
||||
Json keys doesn't expire so we don't need a cronjob, we just need to create the secret and reference it in the ImagePolicy.
|
||||
First, create a json key file by following this
|
||||
[documentation](https://cloud.google.com/container-registry/docs/advanced-authentication).
|
||||
Grant the service account the role of `Container Registry Service Agent`
|
||||
so that it can access GCR and download the json file.
|
||||
|
||||
First, create a json key file by following this [documentation](https://cloud.google.com/container-registry/docs/advanced-authentication). Grant the service account the role of `Container Registry Service Agent` so that it can access GCR and download the json file.
|
||||
Then create a secret, encrypt it using [Mozilla SOPS](mozilla-sops.md)
|
||||
or [Sealed Secrets](sealed-secrets.md) , commit and push the encypted file to git.
|
||||
|
||||
Then create a secret, encrypt it using [Mozilla SOPS](mozilla-sops.md) or [Sealed Secrets](sealed-secrets.md) , commit and push the encypted file to git.
|
||||
```
|
||||
kubectl create secret docker-registry <secret-name> \
|
||||
--docker-server=<GCR-REGISTRY> \ # e.g gcr.io
|
||||
@@ -615,4 +713,4 @@ Then create a secret, encrypt it using [Mozilla SOPS](mozilla-sops.md) or [Seale
|
||||
|
||||
### Azure Container Registry
|
||||
|
||||
TODO
|
||||
TODO
|
||||
|
||||
@@ -200,11 +200,11 @@ flux bootstrap gitlab \
|
||||
to your repository, otherwise your GitLab personal token will be used to
|
||||
authenticate against the HTTPS endpoint instead.
|
||||
|
||||
Run the bootstrap for a repository owned by a GitLab group:
|
||||
Run the bootstrap for a repository owned by a GitLab (sub)group:
|
||||
|
||||
```sh
|
||||
flux bootstrap gitlab \
|
||||
--owner=my-gitlab-group \
|
||||
--owner=my-gitlab-group/my-gitlab-subgroup \
|
||||
--repository=my-repository \
|
||||
--branch=master \
|
||||
--path=clusters/my-cluster
|
||||
@@ -512,6 +512,10 @@ flux create helmrelease nginx \
|
||||
|
||||
## Upgrade
|
||||
|
||||
!!! note "Patch versions"
|
||||
It is safe and advised to use the latest PATCH version when upgrading to a
|
||||
new MINOR version.
|
||||
|
||||
Update Flux CLI to the latest release with `brew upgrade fluxcd/tap/flux` or by
|
||||
downloading the binary from [GitHub](https://github.com/fluxcd/flux2/releases).
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ groups:
|
||||
- name: GitOpsToolkit
|
||||
rules:
|
||||
- alert: ReconciliationFailure
|
||||
expr: gotk_reconcile_condition{type="Ready",status="False"} == 1
|
||||
expr: max(gotk_reconcile_condition{status="False",type="Ready"}) by (namespace, name, kind) + on(namespace, name, kind) (max(gotk_reconcile_condition{status="Deleted"}) by (namespace, name, kind)) * 2 == 1
|
||||
for: 10m
|
||||
labels:
|
||||
severity: page
|
||||
|
||||
@@ -53,6 +53,8 @@ the API.
|
||||
After installing the `flux` CLI and running a couple of very simple commands,
|
||||
you will have a GitOps workflow setup which involves a staging and a production cluster.
|
||||
|
||||
If you should need help, please refer to our **[Support page](https://fluxcd.io/support/)**.
|
||||
|
||||
## More detail on what's in Flux
|
||||
|
||||
Features:
|
||||
|
||||
10
go.mod
10
go.mod
@@ -7,15 +7,15 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.2.2
|
||||
github.com/fluxcd/helm-controller/api v0.6.1
|
||||
github.com/fluxcd/image-automation-controller/api v0.4.0
|
||||
github.com/fluxcd/image-reflector-controller/api v0.4.1
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.2
|
||||
github.com/fluxcd/image-reflector-controller/api v0.5.0
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.4
|
||||
github.com/fluxcd/notification-controller/api v0.7.1
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0
|
||||
github.com/fluxcd/pkg/git v0.2.3
|
||||
github.com/fluxcd/pkg/git v0.3.0
|
||||
github.com/fluxcd/pkg/runtime v0.8.0
|
||||
github.com/fluxcd/pkg/ssh v0.0.5
|
||||
github.com/fluxcd/pkg/untar v0.0.5
|
||||
github.com/fluxcd/source-controller/api v0.7.1
|
||||
github.com/fluxcd/source-controller/api v0.7.4
|
||||
github.com/google/go-containerregistry v0.2.0
|
||||
github.com/manifoldco/promptui v0.7.0
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
@@ -24,7 +24,9 @@ require (
|
||||
k8s.io/api v0.20.2
|
||||
k8s.io/apiextensions-apiserver v0.20.2
|
||||
k8s.io/apimachinery v0.20.2
|
||||
k8s.io/cli-runtime v0.20.2 // indirect
|
||||
k8s.io/client-go v0.20.2
|
||||
sigs.k8s.io/cli-utils v0.20.2
|
||||
sigs.k8s.io/controller-runtime v0.8.0
|
||||
sigs.k8s.io/kustomize/api v0.7.0
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
|
||||
107
go.sum
107
go.sum
@@ -70,6 +70,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
|
||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@@ -124,6 +125,7 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
@@ -134,9 +136,11 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@@ -158,6 +162,7 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
@@ -190,23 +195,25 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fluxcd/helm-controller/api v0.6.1 h1:vraSNIXdSiqrjpKs53hnr2NMpL0YKGQcEpuILUZ3SlE=
|
||||
github.com/fluxcd/helm-controller/api v0.6.1/go.mod h1:vd4Nt6ZZlDkXwJLkmHRgvNc1bvBPMEIZ0o1qFyEWglo=
|
||||
github.com/fluxcd/image-automation-controller/api v0.4.0 h1:WMPVYfPQTLMvoINdoBDp5u26PJLO1EUZLyeQ95yHKgA=
|
||||
github.com/fluxcd/image-automation-controller/api v0.4.0/go.mod h1:lHGxbFJNIwgK32YWx9uNf4WR/Z92Hdrl8cn6TzixfUI=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.4.1 h1:D1gJL6m7NYE8833eBoLT0qAJZ5Q2Yic3UtAEI10fiWg=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.4.1/go.mod h1:MS3mGjZLnzZsfSqVLGbp0WNJr/k8XRFpw4G6ApLFTbc=
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.2 h1:+Qv63+nQPcDLfUJfVj7DjkZZjNMflSOOTBvAhULvGm8=
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.2/go.mod h1:GMdry0llCMT50hDcQ70ujmtd3vOXUWCJMTggPpGNM+I=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.5.0 h1:xzE+Vi5NevR2TkD9OrEYmjBLTYxeQ28VY5mo0x1Q93Q=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.5.0/go.mod h1:MS3mGjZLnzZsfSqVLGbp0WNJr/k8XRFpw4G6ApLFTbc=
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.4 h1:SbcwYh0041yVmODnHtUFNpqtD8HYPoDm1AhL40WkgB8=
|
||||
github.com/fluxcd/kustomize-controller/api v0.7.4/go.mod h1:GMdry0llCMT50hDcQ70ujmtd3vOXUWCJMTggPpGNM+I=
|
||||
github.com/fluxcd/notification-controller/api v0.7.1 h1:BDeJ172oJN0LKC6VJlu42NkeBCvTKn9cDPVaUo8M1Xs=
|
||||
github.com/fluxcd/notification-controller/api v0.7.1/go.mod h1:n1ow7Mxdcedrio5pf/HhBbaVp/4yGTFACPgfCtiyWoU=
|
||||
github.com/fluxcd/pkg/apis/meta v0.5.0 h1:FaU++mQY0g4sVVl+hG+vk0CXBLbb4EVfRuzs3IjLXvo=
|
||||
github.com/fluxcd/pkg/apis/meta v0.5.0/go.mod h1:aEUuZIawboAAFLlYz/juVJ7KNmlWbBtJFYkOWWmGUR4=
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0 h1:5e8gm4OLqjuKWdrOIY5DEEsjcwzyJFK8rCDesJ+V8IY=
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
||||
github.com/fluxcd/pkg/git v0.2.3 h1:EodoXWrOywqY2aZlgddwRTnnWZc9m1J1e5kuX2Lu5P4=
|
||||
github.com/fluxcd/pkg/git v0.2.3/go.mod h1:8v0QVumu1ugMG3nJL0KMYPZgmLjzesJHA2sOtXAHLPA=
|
||||
github.com/fluxcd/pkg/git v0.3.0 h1:nrKZWZ/ymDevud3Wf1LEieO/QcNPnqz1/MrkZBFcg9o=
|
||||
github.com/fluxcd/pkg/git v0.3.0/go.mod h1:ZwG0iLOqNSyNw6lsPIAO+v6+BqqCXyV+r1Oq6Lm+slg=
|
||||
github.com/fluxcd/pkg/runtime v0.6.2 h1:sWnSv6AhMY30fexRQ37lv2Q9Rvdu05zbiqMSldw+MjQ=
|
||||
github.com/fluxcd/pkg/runtime v0.6.2/go.mod h1:RuqYOYCvBJwo4rg83d28WOt2vfSaemuZCVpUagAjWQc=
|
||||
github.com/fluxcd/pkg/runtime v0.8.0 h1:cnSBZJLcXlKgjXpFFFExu+4ZncIxmPgNIx+ErLcCLnA=
|
||||
@@ -215,8 +222,8 @@ github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
||||
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
|
||||
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
|
||||
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
||||
github.com/fluxcd/source-controller/api v0.7.1 h1:GsiPhpApnt83H1TOA5aw/55N/oiMItaf+j9dVpvJedA=
|
||||
github.com/fluxcd/source-controller/api v0.7.1/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
|
||||
github.com/fluxcd/source-controller/api v0.7.4 h1:Hy29SUyanKNHbb4AQZo7PqzmTx4y8TfkeO0GqBcb5PE=
|
||||
github.com/fluxcd/source-controller/api v0.7.4/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
@@ -225,6 +232,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
@@ -253,6 +261,7 @@ github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.3.0 h1:q4c+kbcR0d5rSurhBR8dIgieOaYpXtsdTYfx22Cu6rs=
|
||||
github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-logr/zapr v0.2.0 h1:v6Ji8yBW77pva6NkJKQdHLAJKrIJKRHz0RXwPqCHSR4=
|
||||
github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
@@ -331,6 +340,7 @@ github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -343,6 +353,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.0.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.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -373,6 +384,9 @@ github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlS
|
||||
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
|
||||
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
|
||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -386,8 +400,8 @@ github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-containerregistry v0.2.0 h1:cWFYx+kOkKdyOET0pcp7GMCmxj7da40StvluSuSXWCg=
|
||||
github.com/google/go-containerregistry v0.2.0/go.mod h1:Ts3Wioz1r5ayWx8sS6vLcWltWcM1aqFjd/eVrkFhrWM=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM=
|
||||
github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
@@ -414,6 +428,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM=
|
||||
@@ -425,10 +440,13 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
@@ -473,6 +491,7 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10 h1:6q5mVkdH/vYmqngx7kZQTjJ5HRsx+ImorDIEQ+beJgc=
|
||||
@@ -519,6 +538,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
|
||||
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
@@ -558,6 +579,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
||||
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
@@ -589,6 +611,7 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -599,6 +622,7 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
|
||||
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
@@ -624,6 +648,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
@@ -634,11 +659,13 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
@@ -677,6 +704,7 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
@@ -732,11 +760,13 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV
|
||||
github.com/vdemeester/k8s-pkg-credentialprovider v1.18.1-0.20201019120933-f1d16962a4db/go.mod h1:grWy0bkr1XO6hqbaaCKaPXqkBVlMGHYG6PGykktwbJc=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/xanzy/go-gitlab v0.38.2 h1:FF4WgwFsLfOC4Wl67c9UDIC73C+UaYJ0pkZ2irbSu4M=
|
||||
github.com/xanzy/go-gitlab v0.38.2/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xanzy/go-gitlab v0.43.0 h1:rpOZQjxVJGW/ch+Jy4j7W4o7BB1mxkXJNVGuplZ7PUs=
|
||||
github.com/xanzy/go-gitlab v0.43.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
|
||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
|
||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
@@ -760,6 +790,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
@@ -767,13 +798,16 @@ go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
@@ -835,6 +869,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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=
|
||||
@@ -859,6 +894,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -893,6 +929,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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=
|
||||
@@ -947,6 +984,7 @@ golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
@@ -1026,6 +1064,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k=
|
||||
gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
@@ -1106,6 +1145,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -1118,6 +1158,7 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -1131,6 +1172,7 @@ gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -1140,7 +1182,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
|
||||
k8s.io/api v0.0.0-20191214185829-ca1d04f8b0d3/go.mod h1:itOjKREfmUTvcjantxOsyYU5mbFsU7qUnyUuRfF5+5M=
|
||||
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
|
||||
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
|
||||
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
|
||||
k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI=
|
||||
k8s.io/api v0.19.4 h1:I+1I4cgJYuCDgiLNjKx7SLmIbwgj9w7N7Zr5vSIdwpo=
|
||||
@@ -1148,11 +1193,17 @@ k8s.io/api v0.19.4/go.mod h1:SbtJ2aHCItirzdJ36YslycFNzWADYH3tgOhvBEFtZAk=
|
||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.2 h1:y/HR22XDZY3pniu9hIFDLpUCPq2w5eQ6aV/VFQ7uJMw=
|
||||
k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8=
|
||||
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=
|
||||
k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs=
|
||||
k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg=
|
||||
k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
|
||||
k8s.io/apiextensions-apiserver v0.20.2 h1:rfrMWQ87lhd8EzQWRnbQ4gXrniL/yTRBgYH1x1+BLlo=
|
||||
k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs=
|
||||
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4=
|
||||
k8s.io/apimachinery v0.0.0-20191214185652-442f8fb2f03a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
|
||||
k8s.io/apimachinery v0.0.0-20191216025728-0ee8b4573e3a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
|
||||
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
|
||||
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
|
||||
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
|
||||
k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
|
||||
k8s.io/apimachinery v0.19.4 h1:+ZoddM7nbzrDCp0T3SWnyxqf8cbWPT2fkZImoyvHUG0=
|
||||
@@ -1160,11 +1211,22 @@ k8s.io/apimachinery v0.19.4/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlm
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.2 h1:hFx6Sbt1oG0n6DZ+g4bFt5f6BoMkOjKWsQFu077M3Vg=
|
||||
k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
|
||||
k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
|
||||
k8s.io/apiserver v0.18.8/go.mod h1:12u5FuGql8Cc497ORNj79rhPdiXQC4bf53X/skR/1YM=
|
||||
k8s.io/apiserver v0.19.2/go.mod h1:FreAq0bJ2vtZFj9Ago/X0oNGC51GfubKK/ViOKfVAOA=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA=
|
||||
k8s.io/cli-runtime v0.0.0-20191214191754-e6dc6d5c8724/go.mod h1:wzlq80lvjgHW9if6MlE4OIGC86MDKsy5jtl9nxz/IYY=
|
||||
k8s.io/cli-runtime v0.17.2 h1:YH4txSplyGudvxjhAJeHEtXc7Tr/16clKGfN076ydGk=
|
||||
k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
|
||||
k8s.io/cli-runtime v0.20.2 h1:W0/FHdbApnl9oB7xdG643c/Zaf7TZT+43I+zKxwqvhU=
|
||||
k8s.io/cli-runtime v0.20.2/go.mod h1:FjH6uIZZZP3XmwrXWeeYCbgxcrD6YXxoAykBaWH0VdM=
|
||||
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
|
||||
k8s.io/client-go v0.0.0-20191214190045-a32a6f7a3052/go.mod h1:tAaoc/sYuIL0+njJefSAmE28CIcxyaFV4kbIujBlY2s=
|
||||
k8s.io/client-go v0.0.0-20191219150334-0b8da7416048/go.mod h1:ZEe8ZASDUAuqVGJ+UN0ka0PfaR+b6a6E1PGsSNZRui8=
|
||||
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
|
||||
k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
|
||||
k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
|
||||
k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA=
|
||||
k8s.io/client-go v0.19.4 h1:85D3mDNoLF+xqpyE9Dh/OtrJDyJrSRKkHmDXIbEzer8=
|
||||
@@ -1173,10 +1235,15 @@ k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.2 h1:uuf+iIAbfnCSw8IGAv/Rg0giM+2bOzHLOsbbrwrdhNQ=
|
||||
k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE=
|
||||
k8s.io/cloud-provider v0.18.8/go.mod h1:cn9AlzMPVIXA4HHLVbgGUigaQlZyHSZ7WAwDEFNrQSs=
|
||||
k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE=
|
||||
k8s.io/code-generator v0.0.0-20191214185510-0b9b3c99f9f2/go.mod h1:BjGKcoq1MRUmcssvHiSxodCco1T6nVIt4YeCT5CMSao=
|
||||
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
|
||||
k8s.io/code-generator v0.19.2/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
|
||||
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
|
||||
k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
|
||||
k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA=
|
||||
k8s.io/component-base v0.0.0-20191214190519-d868452632e2/go.mod h1:wupxkh1T/oUDqyTtcIjiEfpbmIHGm8By/vqpSKC6z8c=
|
||||
k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs=
|
||||
k8s.io/component-base v0.18.8/go.mod h1:00frPRDas29rx58pPCxNkhUfPbwajlyyvu8ruNgSErU=
|
||||
k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
@@ -1190,6 +1257,7 @@ k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
|
||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
@@ -1197,13 +1265,17 @@ k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ=
|
||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd/go.mod h1:9ehGcuUGjXVZh0qbYSB0vvofQw2JQe6c6cO0k4wu/Oo=
|
||||
k8s.io/legacy-cloud-providers v0.18.8/go.mod h1:tgp4xYf6lvjrWnjQwTOPvWQE9IVqSBGPF4on0IyICQE=
|
||||
k8s.io/metrics v0.0.0-20191214191643-6b1944c9f765/go.mod h1:5V7rewilItwK0cz4nomU0b3XCcees2Ka5EBYWS1HBeM=
|
||||
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg=
|
||||
@@ -1226,23 +1298,34 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/cli-utils v0.20.2 h1:jNMu4ExtvFXlmKqZMDJqySqK55vGtVRqoLht6eIMffw=
|
||||
sigs.k8s.io/cli-utils v0.20.2/go.mod h1:uT5cVxMrOoRplL8umtrJx5R51ZWsIKD7lQfPtot80uA=
|
||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||
sigs.k8s.io/controller-runtime v0.7.0 h1:bU20IBBEPccWz5+zXpLnpVsgBYxqclaHu1pVDl/gEt8=
|
||||
sigs.k8s.io/controller-runtime v0.7.0/go.mod h1:pJ3YBrJiAqMAZKi6UVGuE98ZrroV1p+pIhoHsMm9wdU=
|
||||
sigs.k8s.io/controller-runtime v0.8.0 h1:s0dYdo7lQgJiAf+alP82PRwbz+oAqL3oSyMQ18XRDOc=
|
||||
sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/kustomize/api v0.7.0 h1:djxH9k1izeU1BvdP1i23qqKwhmWu2BuKNEKr/Da7Dpw=
|
||||
sigs.k8s.io/kustomize/api v0.7.0/go.mod h1:3TxKEyaxwOIfHmRbQF14hDUSRmVQI0iSn8qDA5zaO/0=
|
||||
sigs.k8s.io/kustomize/kyaml v0.8.1/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
|
||||
sigs.k8s.io/kustomize/kyaml v0.10.3 h1:ARSJUMN/c3k31DYxRfZ+vp/UepUQjg9zCwny7Oj908I=
|
||||
sigs.k8s.io/kustomize/kyaml v0.10.3/go.mod h1:RA+iCHA2wPCOfv6uG6TfXXWhYsHpgErq/AljxWKuxtg=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
|
||||
|
||||
@@ -393,3 +393,24 @@ func ValidateComponents(components []string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(stefan): move this to fluxcd/pkg
|
||||
// taken from: https://github.com/fluxcd/helm-controller/blob/main/internal/util/util.go
|
||||
func MergeMaps(a, b map[string]interface{}) map[string]interface{} {
|
||||
out := make(map[string]interface{}, len(a))
|
||||
for k, v := range a {
|
||||
out[k] = v
|
||||
}
|
||||
for k, v := range b {
|
||||
if v, ok := v.(map[string]interface{}); ok {
|
||||
if bv, ok := out[k]; ok {
|
||||
if bv, ok := bv.(map[string]interface{}); ok {
|
||||
out[k] = MergeMaps(bv, v)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/image-reflector-controller/archive/v0.4.1.zip//image-reflector-controller-0.4.1/config/crd
|
||||
- https://github.com/fluxcd/image-reflector-controller/archive/v0.4.1.zip//image-reflector-controller-0.4.1/config/manager
|
||||
- https://github.com/fluxcd/image-reflector-controller/archive/v0.5.0.zip//image-reflector-controller-0.5.0/config/crd
|
||||
- https://github.com/fluxcd/image-reflector-controller/archive/v0.5.0.zip//image-reflector-controller-0.5.0/config/manager
|
||||
- account.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/kustomize-controller/archive/v0.7.2.zip//kustomize-controller-0.7.2/config/crd
|
||||
- https://github.com/fluxcd/kustomize-controller/archive/v0.7.2.zip//kustomize-controller-0.7.2/config/manager
|
||||
- https://github.com/fluxcd/kustomize-controller/archive/v0.7.4.zip//kustomize-controller-0.7.4/config/crd
|
||||
- https://github.com/fluxcd/kustomize-controller/archive/v0.7.4.zip//kustomize-controller-0.7.4/config/manager
|
||||
- account.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/source-controller/archive/v0.7.1.zip//source-controller-0.7.1/config/crd
|
||||
- https://github.com/fluxcd/source-controller/archive/v0.7.1.zip//source-controller-0.7.1/config/manager
|
||||
- https://github.com/fluxcd/source-controller/archive/v0.7.4.zip//source-controller-0.7.4/config/crd
|
||||
- https://github.com/fluxcd/source-controller/archive/v0.7.4.zip//source-controller-0.7.4/config/manager
|
||||
- account.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
|
||||
37
mkdocs.yml
37
mkdocs.yml
@@ -46,6 +46,9 @@ nav:
|
||||
- Introduction: index.md
|
||||
- Core Concepts: core-concepts/index.md
|
||||
- Get Started: get-started/index.md
|
||||
- Migration:
|
||||
- Migrate from Flux v1: guides/flux-v1-migration.md
|
||||
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
||||
- Guides:
|
||||
- Installation: guides/installation.md
|
||||
- Manage Helm Releases: guides/helmreleases.md
|
||||
@@ -55,9 +58,6 @@ nav:
|
||||
- Sealed Secrets: guides/sealed-secrets.md
|
||||
- Mozilla SOPS: guides/mozilla-sops.md
|
||||
- Automate image updates to Git: guides/image-update.md
|
||||
- Migration:
|
||||
- Migrate from Flux v1: guides/flux-v1-migration.md
|
||||
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
||||
- Toolkit Components:
|
||||
- Overview: components/index.md
|
||||
- Source Controller:
|
||||
@@ -104,10 +104,15 @@ nav:
|
||||
- Create alert provider: cmd/flux_create_alert-provider.md
|
||||
- Create alert: cmd/flux_create_alert.md
|
||||
- Create receiver: cmd/flux_create_receiver.md
|
||||
- Create image: cmd/flux_create_image.md
|
||||
- Create image policy: cmd/flux_create_image_policy.md
|
||||
- Create image repository: cmd/flux_create_image_repository.md
|
||||
- Create image update: cmd/flux_create_image_update.md
|
||||
- Create tenant: cmd/flux_create_tenant.md
|
||||
- Create secret: cmd/flux_create_secret.md
|
||||
- Create secret git: cmd/flux_create_secret_git.md
|
||||
- Create secret helm: cmd/flux_create_secret_helm.md
|
||||
- Create secret tls: cmd/flux_create_secret_tls.md
|
||||
- Delete: cmd/flux_delete.md
|
||||
- Delete kustomization: cmd/flux_delete_kustomization.md
|
||||
- Delete helmrelease: cmd/flux_delete_helmrelease.md
|
||||
@@ -115,6 +120,10 @@ nav:
|
||||
- Delete source git: cmd/flux_delete_source_git.md
|
||||
- Delete source helm: cmd/flux_delete_source_helm.md
|
||||
- Delete source bucket: cmd/flux_delete_source_bucket.md
|
||||
- Delete image: cmd/flux_delete_image.md
|
||||
- Delete image policy: cmd/flux_delete_image_policy.md
|
||||
- Delete image repository: cmd/flux_delete_image_repository.md
|
||||
- Delete image update: cmd/flux_delete_image_update.md
|
||||
- Export: cmd/flux_export.md
|
||||
- Export kustomization: cmd/flux_export_kustomization.md
|
||||
- Export helmrelease: cmd/flux_export_helmrelease.md
|
||||
@@ -125,6 +134,10 @@ nav:
|
||||
- Export alert provider: cmd/flux_export_alert-provider.md
|
||||
- Export alert: cmd/flux_export_alert.md
|
||||
- Export receiver: cmd/flux_export_receiver.md
|
||||
- Export image: cmd/flux_export_image.md
|
||||
- Export image policy: cmd/flux_export_image_policy.md
|
||||
- Export image repository: cmd/flux_export_image_repository.md
|
||||
- Export image update: cmd/flux_export_image_update.md
|
||||
- Get: cmd/flux_get.md
|
||||
- Get kustomizations: cmd/flux_get_kustomizations.md
|
||||
- Get helmreleases: cmd/flux_get_helmreleases.md
|
||||
@@ -134,8 +147,13 @@ nav:
|
||||
- Get sources chart: cmd/flux_get_sources_chart.md
|
||||
- Get sources bucket: cmd/flux_get_sources_bucket.md
|
||||
- Get alert provider: cmd/flux_get_alert-provider.md
|
||||
- Get alert: cmd/flux_get_alert.md
|
||||
- Get receiver: cmd/flux_get_receiver.md
|
||||
- Get alerts: cmd/flux_get_alerts.md
|
||||
- Get alert providers: cmd/flux_get_alert-providers.md
|
||||
- Get receivers: cmd/flux_get_receivers.md
|
||||
- Get images: cmd/flux_get_images.md
|
||||
- Get images policy: cmd/flux_get_images_policy.md
|
||||
- Get images repository: cmd/flux_get_images_repository.md
|
||||
- Get images update: cmd/flux_get_images_update.md
|
||||
- Install: cmd/flux_install.md
|
||||
- Resume: cmd/flux_resume.md
|
||||
- Resume kustomization: cmd/flux_resume_kustomization.md
|
||||
@@ -148,6 +166,9 @@ nav:
|
||||
- Resume alert provider: cmd/flux_resume_alert-provider.md
|
||||
- Resume alert: cmd/flux_resume_alert.md
|
||||
- Resume receiver: cmd/flux_resume_receiver.md
|
||||
- Resume image: cmd/flux_resume_image.md
|
||||
- Resume image repository: cmd/flux_resume_image_repository.md
|
||||
- Resume image update: cmd/flux_resume_image_update.md
|
||||
- Suspend: cmd/flux_suspend.md
|
||||
- Suspend kustomization: cmd/flux_suspend_kustomization.md
|
||||
- Suspend helmrelease: cmd/flux_suspend_helmrelease.md
|
||||
@@ -159,6 +180,9 @@ nav:
|
||||
- Suspend alert provider: cmd/flux_suspend_alert-provider.md
|
||||
- Suspend alert: cmd/flux_suspend_alert.md
|
||||
- Suspend receiver: cmd/flux_suspend_receiver.md
|
||||
- Suspend image: cmd/flux_suspend_image.md
|
||||
- Suspend image repository: cmd/flux_suspend_image_repository.md
|
||||
- Suspend image update: cmd/flux_suspend_image_update.md
|
||||
- Reconcile: cmd/flux_reconcile.md
|
||||
- Reconcile kustomization: cmd/flux_reconcile_kustomization.md
|
||||
- Reconcile helmrelease: cmd/flux_reconcile_helmrelease.md
|
||||
@@ -166,6 +190,9 @@ nav:
|
||||
- Reconcile source git: cmd/flux_reconcile_source_git.md
|
||||
- Reconcile source helm: cmd/flux_reconcile_source_helm.md
|
||||
- Reconcile source bucket: cmd/flux_reconcile_source_bucket.md
|
||||
- Reconcile image: cmd/flux_reconcile_image.md
|
||||
- Reconcile image repository: cmd/flux_reconcile_image_repository.md
|
||||
- Reconcile image update: cmd/flux_reconcile_image_update.md
|
||||
- Uninstall: cmd/flux_uninstall.md
|
||||
- Dev Guides:
|
||||
- Watching for source changes: dev-guides/source-watcher.md
|
||||
|
||||
Reference in New Issue
Block a user