Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29c46a9892 | ||
|
|
ef579fe596 | ||
|
|
5b268f62a3 | ||
|
|
1f1c8286a5 | ||
|
|
5401e1ace4 | ||
|
|
69294ef56d | ||
|
|
a685ed8029 | ||
|
|
68d0be3818 | ||
|
|
84e2cb4c1f | ||
|
|
263c664acd | ||
|
|
b12c4c22fb | ||
|
|
9f39fadb9e | ||
|
|
4c29a1ca27 | ||
|
|
f4db124d50 | ||
|
|
8f8c7cccc6 | ||
|
|
e2097c28bd | ||
|
|
871eb444fc |
@@ -39,6 +39,21 @@ func init() {
|
|||||||
createCmd.AddCommand(createSecretCmd)
|
createCmd.AddCommand(createSecretCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeSecret(name string) (corev1.Secret, error) {
|
||||||
|
secretLabels, err := parseLabels()
|
||||||
|
if err != nil {
|
||||||
|
return corev1.Secret{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: rootArgs.namespace,
|
||||||
|
Labels: secretLabels,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func upsertSecret(ctx context.Context, kubeClient client.Client, secret corev1.Secret) error {
|
func upsertSecret(ctx context.Context, kubeClient client.Client, secret corev1.Secret) error {
|
||||||
namespacedName := types.NamespacedName{
|
namespacedName := types.NamespacedName{
|
||||||
Namespace: secret.GetNamespace(),
|
Namespace: secret.GetNamespace(),
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/flags"
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
@@ -106,6 +104,10 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("secret name is required")
|
return fmt.Errorf("secret name is required")
|
||||||
}
|
}
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
secret, err := makeSecret(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if secretGitArgs.url == "" {
|
if secretGitArgs.url == "" {
|
||||||
return fmt.Errorf("url is required")
|
return fmt.Errorf("url is required")
|
||||||
@@ -116,22 +118,9 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("git URL parse failed: %w", err)
|
return fmt.Errorf("git URL parse failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secretLabels, err := parseLabels()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
secret := corev1.Secret{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: name,
|
|
||||||
Namespace: rootArgs.namespace,
|
|
||||||
Labels: secretLabels,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
pair, err := generateKeyPair(ctx, secretGitArgs.keyAlgorithm, secretGitArgs.rsaBits, secretGitArgs.ecdsaCurve)
|
pair, err := generateKeyPair(ctx, secretGitArgs.keyAlgorithm, secretGitArgs.rsaBits, secretGitArgs.ecdsaCurve)
|
||||||
|
|||||||
@@ -19,11 +19,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
)
|
)
|
||||||
@@ -58,9 +55,7 @@ The create secret helm command generates a Kubernetes secret with basic authenti
|
|||||||
type secretHelmFlags struct {
|
type secretHelmFlags struct {
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
certFile string
|
secretTLSFlags
|
||||||
keyFile string
|
|
||||||
caFile string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var secretHelmArgs secretHelmFlags
|
var secretHelmArgs secretHelmFlags
|
||||||
@@ -68,10 +63,7 @@ var secretHelmArgs secretHelmFlags
|
|||||||
func init() {
|
func init() {
|
||||||
createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.username, "username", "u", "", "basic authentication username")
|
createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.username, "username", "u", "", "basic authentication username")
|
||||||
createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.password, "password", "p", "", "basic authentication password")
|
createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.password, "password", "p", "", "basic authentication password")
|
||||||
createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.certFile, "cert-file", "", "TLS authentication cert file path")
|
initSecretTLSFlags(createSecretHelmCmd.Flags(), &secretHelmArgs.secretTLSFlags)
|
||||||
createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.keyFile, "key-file", "", "TLS authentication key file path")
|
|
||||||
createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.caFile, "ca-file", "", "TLS authentication CA file path")
|
|
||||||
|
|
||||||
createSecretCmd.AddCommand(createSecretHelmCmd)
|
createSecretCmd.AddCommand(createSecretHelmCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,46 +72,18 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("secret name is required")
|
return fmt.Errorf("secret name is required")
|
||||||
}
|
}
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
secret, err := makeSecret(name)
|
||||||
secretLabels, err := parseLabels()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
secret := corev1.Secret{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: name,
|
|
||||||
Namespace: rootArgs.namespace,
|
|
||||||
Labels: secretLabels,
|
|
||||||
},
|
|
||||||
StringData: map[string]string{},
|
|
||||||
}
|
|
||||||
|
|
||||||
if secretHelmArgs.username != "" && secretHelmArgs.password != "" {
|
if secretHelmArgs.username != "" && secretHelmArgs.password != "" {
|
||||||
secret.StringData["username"] = secretHelmArgs.username
|
secret.StringData["username"] = secretHelmArgs.username
|
||||||
secret.StringData["password"] = secretHelmArgs.password
|
secret.StringData["password"] = secretHelmArgs.password
|
||||||
}
|
}
|
||||||
|
|
||||||
if secretHelmArgs.certFile != "" && secretHelmArgs.keyFile != "" {
|
if err = populateSecretTLS(&secret, secretHelmArgs.secretTLSFlags); err != nil {
|
||||||
cert, err := ioutil.ReadFile(secretHelmArgs.certFile)
|
return err
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read repository cert file '%s': %w", secretHelmArgs.certFile, err)
|
|
||||||
}
|
|
||||||
secret.StringData["certFile"] = string(cert)
|
|
||||||
|
|
||||||
key, err := ioutil.ReadFile(secretHelmArgs.keyFile)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read repository key file '%s': %w", secretHelmArgs.keyFile, err)
|
|
||||||
}
|
|
||||||
secret.StringData["keyFile"] = string(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
if secretHelmArgs.caFile != "" {
|
|
||||||
ca, err := ioutil.ReadFile(secretHelmArgs.caFile)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read repository CA file '%s': %w", secretHelmArgs.caFile, err)
|
|
||||||
}
|
|
||||||
secret.StringData["caFile"] = string(ca)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if createArgs.export {
|
if createArgs.export {
|
||||||
|
|||||||
128
cmd/flux/create_secret_tls.go
Normal file
128
cmd/flux/create_secret_tls.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020, 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var createSecretTLSCmd = &cobra.Command{
|
||||||
|
Use: "tls [name]",
|
||||||
|
Short: "Create or update a Kubernetes secret with TLS certificates",
|
||||||
|
Long: `
|
||||||
|
The create secret tls command generates a Kubernetes secret with certificates for use with TLS.`,
|
||||||
|
Example: `
|
||||||
|
# Create a TLS secret on disk and encrypt it with Mozilla SOPS.
|
||||||
|
# Files are expected to be PEM-encoded.
|
||||||
|
flux create secret tls certs \
|
||||||
|
--namespace=my-namespace \
|
||||||
|
--cert-file=./client.crt \
|
||||||
|
--key-file=./client.key \
|
||||||
|
--export > certs.yaml
|
||||||
|
|
||||||
|
sops --encrypt --encrypted-regex '^(data|stringData)$' \
|
||||||
|
--in-place certs.yaml
|
||||||
|
`,
|
||||||
|
RunE: createSecretTLSCmdRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
type secretTLSFlags struct {
|
||||||
|
certFile string
|
||||||
|
keyFile string
|
||||||
|
caFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
var secretTLSArgs secretTLSFlags
|
||||||
|
|
||||||
|
func initSecretTLSFlags(flags *pflag.FlagSet, args *secretTLSFlags) {
|
||||||
|
flags.StringVar(&args.certFile, "cert-file", "", "TLS authentication cert file path")
|
||||||
|
flags.StringVar(&args.keyFile, "key-file", "", "TLS authentication key file path")
|
||||||
|
flags.StringVar(&args.caFile, "ca-file", "", "TLS authentication CA file path")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flags := createSecretTLSCmd.Flags()
|
||||||
|
initSecretTLSFlags(flags, &secretTLSArgs)
|
||||||
|
createSecretCmd.AddCommand(createSecretTLSCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func populateSecretTLS(secret *corev1.Secret, args secretTLSFlags) error {
|
||||||
|
if args.certFile != "" && args.keyFile != "" {
|
||||||
|
cert, err := ioutil.ReadFile(args.certFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read repository cert file '%s': %w", args.certFile, err)
|
||||||
|
}
|
||||||
|
secret.StringData["certFile"] = string(cert)
|
||||||
|
|
||||||
|
key, err := ioutil.ReadFile(args.keyFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read repository key file '%s': %w", args.keyFile, err)
|
||||||
|
}
|
||||||
|
secret.StringData["keyFile"] = string(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.caFile != "" {
|
||||||
|
ca, err := ioutil.ReadFile(args.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read repository CA file '%s': %w", args.caFile, err)
|
||||||
|
}
|
||||||
|
secret.StringData["caFile"] = string(ca)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return fmt.Errorf("secret name is required")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
secret, err := makeSecret(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = populateSecretTLS(&secret, secretTLSArgs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if createArgs.export {
|
||||||
|
return exportSecret(secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.Actionf("secret '%s' created in '%s' namespace", name, rootArgs.namespace)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -17,15 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteHelmReleaseCmd = &cobra.Command{
|
var deleteHelmReleaseCmd = &cobra.Command{
|
||||||
@@ -36,57 +29,12 @@ var deleteHelmReleaseCmd = &cobra.Command{
|
|||||||
Example: ` # Delete a Helm release and the Kubernetes resources created by it
|
Example: ` # Delete a Helm release and the Kubernetes resources created by it
|
||||||
flux delete hr podinfo
|
flux delete hr podinfo
|
||||||
`,
|
`,
|
||||||
RunE: deleteHelmReleaseCmdRun,
|
RunE: deleteCommand{
|
||||||
|
apiType: helmReleaseType,
|
||||||
|
object: universalAdapter{&helmv2.HelmRelease{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
deleteCmd.AddCommand(deleteHelmReleaseCmd)
|
deleteCmd.AddCommand(deleteHelmReleaseCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return fmt.Errorf("release 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
|
|
||||||
}
|
|
||||||
|
|
||||||
if !deleteArgs.silent {
|
|
||||||
if !helmRelease.Spec.Suspend {
|
|
||||||
logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s Helm release!", name)
|
|
||||||
}
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: "Are you sure you want to delete this Helm release",
|
|
||||||
IsConfirm: true,
|
|
||||||
}
|
|
||||||
if _, err := prompt.Run(); err != nil {
|
|
||||||
return fmt.Errorf("aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Actionf("deleting release %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
err = kubeClient.Delete(ctx, &helmRelease)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("release deleted")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,14 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteKsCmd = &cobra.Command{
|
var deleteKsCmd = &cobra.Command{
|
||||||
@@ -35,57 +29,12 @@ var deleteKsCmd = &cobra.Command{
|
|||||||
Example: ` # Delete a kustomization and the Kubernetes resources created by it
|
Example: ` # Delete a kustomization and the Kubernetes resources created by it
|
||||||
flux delete kustomization podinfo
|
flux delete kustomization podinfo
|
||||||
`,
|
`,
|
||||||
RunE: deleteKsCmdRun,
|
RunE: deleteCommand{
|
||||||
|
apiType: kustomizationType,
|
||||||
|
object: universalAdapter{&kustomizev1.Kustomization{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
deleteCmd.AddCommand(deleteKsCmd)
|
deleteCmd.AddCommand(deleteKsCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteKsCmdRun(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
|
|
||||||
}
|
|
||||||
|
|
||||||
if !deleteArgs.silent {
|
|
||||||
if !kustomization.Spec.Suspend {
|
|
||||||
logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name)
|
|
||||||
}
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: "Are you sure you want to delete this kustomization",
|
|
||||||
IsConfirm: true,
|
|
||||||
}
|
|
||||||
if _, err := prompt.Run(); err != nil {
|
|
||||||
return fmt.Errorf("aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Actionf("deleting kustomization %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
err = kubeClient.Delete(ctx, &kustomization)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("kustomization deleted")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,14 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteSourceBucketCmd = &cobra.Command{
|
var deleteSourceBucketCmd = &cobra.Command{
|
||||||
@@ -34,54 +28,12 @@ var deleteSourceBucketCmd = &cobra.Command{
|
|||||||
Example: ` # Delete a Bucket source
|
Example: ` # Delete a Bucket source
|
||||||
flux delete source bucket podinfo
|
flux delete source bucket podinfo
|
||||||
`,
|
`,
|
||||||
RunE: deleteSourceBucketCmdRun,
|
RunE: deleteCommand{
|
||||||
|
apiType: bucketType,
|
||||||
|
object: universalAdapter{&sourcev1.Bucket{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
deleteSourceCmd.AddCommand(deleteSourceBucketCmd)
|
deleteSourceCmd.AddCommand(deleteSourceBucketCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return fmt.Errorf("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 !deleteArgs.silent {
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: "Are you sure you want to delete this source",
|
|
||||||
IsConfirm: true,
|
|
||||||
}
|
|
||||||
if _, err := prompt.Run(); err != nil {
|
|
||||||
return fmt.Errorf("aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
err = kubeClient.Delete(ctx, &bucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source deleted")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,14 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
"github.com/manifoldco/promptui"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var deleteSourceGitCmd = &cobra.Command{
|
var deleteSourceGitCmd = &cobra.Command{
|
||||||
@@ -34,54 +28,12 @@ var deleteSourceGitCmd = &cobra.Command{
|
|||||||
Example: ` # Delete a Git repository
|
Example: ` # Delete a Git repository
|
||||||
flux delete source git podinfo
|
flux delete source git podinfo
|
||||||
`,
|
`,
|
||||||
RunE: deleteSourceGitCmdRun,
|
RunE: deleteCommand{
|
||||||
|
apiType: gitRepositoryType,
|
||||||
|
object: universalAdapter{&sourcev1.GitRepository{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
deleteSourceCmd.AddCommand(deleteSourceGitCmd)
|
deleteSourceCmd.AddCommand(deleteSourceGitCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return fmt.Errorf("git 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 git sourcev1.GitRepository
|
|
||||||
err = kubeClient.Get(ctx, namespacedName, &git)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !deleteArgs.silent {
|
|
||||||
prompt := promptui.Prompt{
|
|
||||||
Label: "Are you sure you want to delete this source",
|
|
||||||
IsConfirm: true,
|
|
||||||
}
|
|
||||||
if _, err := prompt.Run(); err != nil {
|
|
||||||
return fmt.Errorf("aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
err = kubeClient.Delete(ctx, &git)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source deleted")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,7 +34,10 @@ var deleteSourceHelmCmd = &cobra.Command{
|
|||||||
Example: ` # Delete a Helm repository
|
Example: ` # Delete a Helm repository
|
||||||
flux delete source helm podinfo
|
flux delete source helm podinfo
|
||||||
`,
|
`,
|
||||||
RunE: deleteSourceHelmCmdRun,
|
RunE: deleteCommand{
|
||||||
|
apiType: helmRepositoryType,
|
||||||
|
object: universalAdapter{&sourcev1.HelmRepository{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var getSourceHelmChartCmd = &cobra.Command{
|
|||||||
flux get sources chart --all-namespaces
|
flux get sources chart --all-namespaces
|
||||||
`,
|
`,
|
||||||
RunE: getCommand{
|
RunE: getCommand{
|
||||||
apiType: bucketType,
|
apiType: helmChartType,
|
||||||
list: &helmChartListAdapter{&sourcev1.HelmChartList{}},
|
list: &helmChartListAdapter{&sourcev1.HelmChartList{}},
|
||||||
}.run,
|
}.run,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var getSourceGitCmd = &cobra.Command{
|
|||||||
flux get sources git --all-namespaces
|
flux get sources git --all-namespaces
|
||||||
`,
|
`,
|
||||||
RunE: getCommand{
|
RunE: getCommand{
|
||||||
apiType: bucketType,
|
apiType: gitRepositoryType,
|
||||||
list: &gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
|
list: &gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
|
||||||
}.run,
|
}.run,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var getSourceHelmCmd = &cobra.Command{
|
|||||||
flux get sources helm --all-namespaces
|
flux get sources helm --all-namespaces
|
||||||
`,
|
`,
|
||||||
RunE: getCommand{
|
RunE: getCommand{
|
||||||
apiType: bucketType,
|
apiType: helmRepositoryType,
|
||||||
list: &helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
|
list: &helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
|
||||||
}.run,
|
}.run,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rhrArgs.syncHrWithSource {
|
if rhrArgs.syncHrWithSource {
|
||||||
|
nsCopy := rootArgs.namespace
|
||||||
|
if helmRelease.Spec.Chart.Spec.SourceRef.Namespace != "" {
|
||||||
|
rootArgs.namespace = helmRelease.Spec.Chart.Spec.SourceRef.Namespace
|
||||||
|
}
|
||||||
switch helmRelease.Spec.Chart.Spec.SourceRef.Kind {
|
switch helmRelease.Spec.Chart.Spec.SourceRef.Kind {
|
||||||
case sourcev1.HelmRepositoryKind:
|
case sourcev1.HelmRepositoryKind:
|
||||||
err = reconcileSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
err = reconcileSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
|
||||||
@@ -104,6 +108,7 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
rootArgs.namespace = nsCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
lastHandledReconcileAt := helmRelease.Status.LastHandledReconcileAt
|
lastHandledReconcileAt := helmRelease.Status.LastHandledReconcileAt
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rksArgs.syncKsWithSource {
|
if rksArgs.syncKsWithSource {
|
||||||
|
nsCopy := rootArgs.namespace
|
||||||
|
if kustomization.Spec.SourceRef.Namespace != "" {
|
||||||
|
rootArgs.namespace = kustomization.Spec.SourceRef.Namespace
|
||||||
|
}
|
||||||
switch kustomization.Spec.SourceRef.Kind {
|
switch kustomization.Spec.SourceRef.Kind {
|
||||||
case sourcev1.GitRepositoryKind:
|
case sourcev1.GitRepositoryKind:
|
||||||
err = reconcileSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
|
err = reconcileSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
|
||||||
@@ -100,6 +104,7 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
rootArgs.namespace = nsCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
lastHandledReconcileAt := kustomization.Status.LastHandledReconcileAt
|
lastHandledReconcileAt := kustomization.Status.LastHandledReconcileAt
|
||||||
|
|||||||
@@ -17,14 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendHrCmd = &cobra.Command{
|
var suspendHrCmd = &cobra.Command{
|
||||||
@@ -35,43 +29,20 @@ var suspendHrCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing Helm release
|
Example: ` # Suspend reconciliation for an existing Helm release
|
||||||
flux suspend hr podinfo
|
flux suspend hr podinfo
|
||||||
`,
|
`,
|
||||||
RunE: suspendHrCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: helmReleaseType,
|
||||||
|
object: &helmReleaseAdapter{&helmv2.HelmRelease{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendCmd.AddCommand(suspendHrCmd)
|
suspendCmd.AddCommand(suspendHrCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendHrCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj helmReleaseAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.HelmRelease.Spec.Suspend
|
||||||
return fmt.Errorf("HelmRelease name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj helmReleaseAdapter) setSuspended() {
|
||||||
|
obj.HelmRelease.Spec.Suspend = true
|
||||||
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("suspending HelmRelease %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
helmRelease.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("HelmRelease suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendKsCmd = &cobra.Command{
|
var suspendKsCmd = &cobra.Command{
|
||||||
@@ -34,43 +29,20 @@ var suspendKsCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing Kustomization
|
Example: ` # Suspend reconciliation for an existing Kustomization
|
||||||
flux suspend ks podinfo
|
flux suspend ks podinfo
|
||||||
`,
|
`,
|
||||||
RunE: suspendKsCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: kustomizationType,
|
||||||
|
object: kustomizationAdapter{&kustomizev1.Kustomization{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendCmd.AddCommand(suspendKsCmd)
|
suspendCmd.AddCommand(suspendKsCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendKsCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj kustomizationAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.Kustomization.Spec.Suspend
|
||||||
return fmt.Errorf("kustomization name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj kustomizationAdapter) setSuspended() {
|
||||||
|
obj.Kustomization.Spec.Suspend = true
|
||||||
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("suspending kustomization %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
kustomization.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &kustomization); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("kustomization suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,8 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendSourceBucketCmd = &cobra.Command{
|
var suspendSourceBucketCmd = &cobra.Command{
|
||||||
@@ -33,43 +28,20 @@ var suspendSourceBucketCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing Bucket
|
Example: ` # Suspend reconciliation for an existing Bucket
|
||||||
flux suspend source bucket podinfo
|
flux suspend source bucket podinfo
|
||||||
`,
|
`,
|
||||||
RunE: suspendSourceBucketCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: bucketType,
|
||||||
|
object: bucketAdapter{&sourcev1.Bucket{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendSourceCmd.AddCommand(suspendSourceBucketCmd)
|
suspendSourceCmd.AddCommand(suspendSourceBucketCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj bucketAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.Bucket.Spec.Suspend
|
||||||
return fmt.Errorf("source name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj bucketAdapter) setSuspended() {
|
||||||
|
obj.Bucket.Spec.Suspend = true
|
||||||
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("suspending source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
bucket.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &bucket); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,9 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendSourceHelmChartCmd = &cobra.Command{
|
var suspendSourceHelmChartCmd = &cobra.Command{
|
||||||
@@ -33,43 +29,20 @@ var suspendSourceHelmChartCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing HelmChart
|
Example: ` # Suspend reconciliation for an existing HelmChart
|
||||||
flux suspend source chart podinfo
|
flux suspend source chart podinfo
|
||||||
`,
|
`,
|
||||||
RunE: suspendSourceHelmChartCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: helmChartType,
|
||||||
|
object: helmChartAdapter{&sourcev1.HelmChart{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendSourceCmd.AddCommand(suspendSourceHelmChartCmd)
|
suspendSourceCmd.AddCommand(suspendSourceHelmChartCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj helmChartAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.HelmChart.Spec.Suspend
|
||||||
return fmt.Errorf("source name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj helmChartAdapter) setSuspended() {
|
||||||
|
obj.HelmChart.Spec.Suspend = true
|
||||||
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 chart sourcev1.HelmChart
|
|
||||||
err = kubeClient.Get(ctx, namespacedName, &chart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Actionf("suspending source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
chart.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &chart); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,9 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendSourceGitCmd = &cobra.Command{
|
var suspendSourceGitCmd = &cobra.Command{
|
||||||
@@ -33,43 +29,20 @@ var suspendSourceGitCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing GitRepository
|
Example: ` # Suspend reconciliation for an existing GitRepository
|
||||||
flux suspend source git podinfo
|
flux suspend source git podinfo
|
||||||
`,
|
`,
|
||||||
RunE: suspendSourceGitCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: gitRepositoryType,
|
||||||
|
object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendSourceCmd.AddCommand(suspendSourceGitCmd)
|
suspendSourceCmd.AddCommand(suspendSourceGitCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj gitRepositoryAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.GitRepository.Spec.Suspend
|
||||||
return fmt.Errorf("source name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj gitRepositoryAdapter) setSuspended() {
|
||||||
|
obj.GitRepository.Spec.Suspend = true
|
||||||
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("suspending source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
repository.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &repository); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,9 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var suspendSourceHelmCmd = &cobra.Command{
|
var suspendSourceHelmCmd = &cobra.Command{
|
||||||
@@ -33,43 +29,20 @@ var suspendSourceHelmCmd = &cobra.Command{
|
|||||||
Example: ` # Suspend reconciliation for an existing HelmRepository
|
Example: ` # Suspend reconciliation for an existing HelmRepository
|
||||||
flux suspend source helm bitnami
|
flux suspend source helm bitnami
|
||||||
`,
|
`,
|
||||||
RunE: suspendSourceHelmCmdRun,
|
RunE: suspendCommand{
|
||||||
|
apiType: helmRepositoryType,
|
||||||
|
object: helmRepositoryAdapter{&sourcev1.HelmRepository{}},
|
||||||
|
}.run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
suspendSourceCmd.AddCommand(suspendSourceHelmCmd)
|
suspendSourceCmd.AddCommand(suspendSourceHelmCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func suspendSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
func (obj helmRepositoryAdapter) isSuspended() bool {
|
||||||
if len(args) < 1 {
|
return obj.HelmRepository.Spec.Suspend
|
||||||
return fmt.Errorf("source name is required")
|
}
|
||||||
}
|
|
||||||
name := args[0]
|
func (obj helmRepositoryAdapter) setSuspended() {
|
||||||
|
obj.HelmRepository.Spec.Suspend = true
|
||||||
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("suspending source %s in %s namespace", name, rootArgs.namespace)
|
|
||||||
repository.Spec.Suspend = true
|
|
||||||
if err := kubeClient.Update(ctx, &repository); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("source suspended")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,4 +30,5 @@ The create source sub-commands generate Kubernetes secrets specific to Flux.
|
|||||||
* [flux create](flux_create.md) - Create or update sources and resources
|
* [flux create](flux_create.md) - Create or update sources and resources
|
||||||
* [flux create secret git](flux_create_secret_git.md) - Create or update a Kubernetes secret for Git authentication
|
* [flux create secret git](flux_create_secret_git.md) - Create or update a Kubernetes secret for Git authentication
|
||||||
* [flux create secret helm](flux_create_secret_helm.md) - Create or update a Kubernetes secret for Helm repository authentication
|
* [flux create secret helm](flux_create_secret_helm.md) - Create or update a Kubernetes secret for Helm repository authentication
|
||||||
|
* [flux create secret tls](flux_create_secret_tls.md) - Create or update a Kubernetes secret with TLS certificates
|
||||||
|
|
||||||
|
|||||||
56
docs/cmd/flux_create_secret_tls.md
Normal file
56
docs/cmd/flux_create_secret_tls.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
## flux create secret tls
|
||||||
|
|
||||||
|
Create or update a Kubernetes secret with TLS certificates
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
|
||||||
|
The create secret tls command generates a Kubernetes secret with certificates for use with TLS.
|
||||||
|
|
||||||
|
```
|
||||||
|
flux create secret tls [name] [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Create a TLS secret on disk and encrypt it with Mozilla SOPS.
|
||||||
|
# Files are expected to be PEM-encoded.
|
||||||
|
flux create secret tls certs \
|
||||||
|
--namespace=my-namespace \
|
||||||
|
--cert-file=./client.crt \
|
||||||
|
--key-file=./client.key \
|
||||||
|
--export > certs.yaml
|
||||||
|
|
||||||
|
sops --encrypt --encrypted-regex '^(data|stringData)$' \
|
||||||
|
--in-place certs.yaml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
--ca-file string TLS authentication CA file path
|
||||||
|
--cert-file string TLS authentication cert file path
|
||||||
|
-h, --help help for tls
|
||||||
|
--key-file string TLS authentication key file path
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
--context string kubernetes context to use
|
||||||
|
--export export in YAML format to stdout
|
||||||
|
--interval duration source sync interval (default 1m0s)
|
||||||
|
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||||
|
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
|
||||||
|
-n, --namespace string the namespace scope for this operation (default "flux-system")
|
||||||
|
--timeout duration timeout for this operation (default 5m0s)
|
||||||
|
--verbose print generated objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [flux create secret](flux_create_secret.md) - Create or update Kubernetes secrets
|
||||||
|
|
||||||
1
go.mod
1
go.mod
@@ -20,6 +20,7 @@ require (
|
|||||||
github.com/manifoldco/promptui v0.7.0
|
github.com/manifoldco/promptui v0.7.0
|
||||||
github.com/olekukonko/tablewriter v0.0.4
|
github.com/olekukonko/tablewriter v0.0.4
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/cobra v1.1.1
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
k8s.io/api v0.20.2
|
k8s.io/api v0.20.2
|
||||||
k8s.io/apiextensions-apiserver v0.20.2
|
k8s.io/apiextensions-apiserver v0.20.2
|
||||||
k8s.io/apimachinery v0.20.2
|
k8s.io/apimachinery v0.20.2
|
||||||
|
|||||||
@@ -70,13 +70,19 @@ roleRef:
|
|||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: kustomize-controller
|
name: kustomize-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: helm-controller
|
name: helm-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: source-controller
|
name: source-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: notification-controller
|
name: notification-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: image-reflector-controller
|
name: image-reflector-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: image-automation-controller
|
name: image-automation-controller
|
||||||
|
namespace: flux-system
|
||||||
|
|||||||
@@ -9,5 +9,7 @@ roleRef:
|
|||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: kustomize-controller
|
name: kustomize-controller
|
||||||
|
namespace: flux-system
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: helm-controller
|
name: helm-controller
|
||||||
|
namespace: flux-system
|
||||||
|
|||||||
10
mkdocs.yml
10
mkdocs.yml
@@ -83,11 +83,11 @@ nav:
|
|||||||
- Receiver CRD: components/notification/receiver.md
|
- Receiver CRD: components/notification/receiver.md
|
||||||
- Notification API Reference: components/notification/api.md
|
- Notification API Reference: components/notification/api.md
|
||||||
- Image Automation Controllers:
|
- Image Automation Controllers:
|
||||||
- Overview: components/images/controller.md
|
- Overview: components/image/controller.md
|
||||||
- ImageRepository CRD: components/images/imagerepositories.md
|
- ImageRepository CRD: components/image/imagerepositories.md
|
||||||
- ImagePolicy CRD: docs/components/image/imagepolicies.md
|
- ImagePolicy CRD: components/image/imagepolicies.md
|
||||||
- ImageUpdateAutomation CRD: docs/components/image/imageupdateautomations.md
|
- ImageUpdateAutomation CRD: components/image/imageupdateautomations.md
|
||||||
- Automation API Reference: docs/components/image/automation-api.md
|
- Automation API Reference: components/image/automation-api.md
|
||||||
- Flux CLI:
|
- Flux CLI:
|
||||||
- Overview: cmd/flux.md
|
- Overview: cmd/flux.md
|
||||||
- Bootstrap: cmd/flux_bootstrap.md
|
- Bootstrap: cmd/flux_bootstrap.md
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ limitations under the License.
|
|||||||
package install
|
package install
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -91,9 +93,23 @@ func generate(base string, options Options) error {
|
|||||||
return fmt.Errorf("generate roles kustomization failed: %w", err)
|
return fmt.Errorf("generate roles kustomization failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := copyFile(filepath.Join(base, "rbac.yaml"), filepath.Join(base, "roles/rbac.yaml")); err != nil {
|
rbacFile := filepath.Join(base, "roles/rbac.yaml")
|
||||||
|
if err := copyFile(filepath.Join(base, "rbac.yaml"), rbacFile); err != nil {
|
||||||
return fmt.Errorf("generate rbac failed: %w", err)
|
return fmt.Errorf("generate rbac failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for kustomize not being able to patch the SA in ClusterRoleBindings
|
||||||
|
defaultNS := MakeDefaultOptions().Namespace
|
||||||
|
if defaultNS != options.Namespace {
|
||||||
|
rbac, err := ioutil.ReadFile(rbacFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading rbac file failed: %w", err)
|
||||||
|
}
|
||||||
|
rbac = bytes.ReplaceAll(rbac, []byte(defaultNS), []byte(options.Namespace))
|
||||||
|
if err := ioutil.WriteFile(rbacFile, rbac, os.ModePerm); err != nil {
|
||||||
|
return fmt.Errorf("replacing service account namespace in rbac failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ images:
|
|||||||
var kustomizationRolesTmpl = `---
|
var kustomizationRolesTmpl = `---
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
|
namespace: {{.Namespace}}
|
||||||
resources:
|
resources:
|
||||||
- rbac.yaml
|
- rbac.yaml
|
||||||
nameSuffix: -{{.Namespace}}
|
nameSuffix: -{{.Namespace}}
|
||||||
|
|||||||
Reference in New Issue
Block a user