From a02452ccb9723a78079c4081126cab9164053c73 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 23 Sep 2020 12:04:28 +0300 Subject: [PATCH] Implement bucket CRUD commands --- cmd/gotk/create_source_bucket.go | 229 +++++++++++++++++++++++ cmd/gotk/delete_source_bucket.go | 86 +++++++++ cmd/gotk/export_source_bucket.go | 166 ++++++++++++++++ cmd/gotk/get_source_bucket.go | 80 ++++++++ cmd/gotk/reconcile_source_bucket.go | 131 +++++++++++++ docs/cmd/gotk_create_source.md | 1 + docs/cmd/gotk_create_source_bucket.md | 65 +++++++ docs/cmd/gotk_delete_source.md | 1 + docs/cmd/gotk_delete_source_bucket.md | 40 ++++ docs/cmd/gotk_export_source.md | 1 + docs/cmd/gotk_export_source_bucket.md | 44 +++++ docs/cmd/gotk_get_sources.md | 1 + docs/cmd/gotk_get_sources_bucket.md | 39 ++++ docs/cmd/gotk_reconcile_source.md | 1 + docs/cmd/gotk_reconcile_source_bucket.md | 39 ++++ mkdocs.yml | 5 + 16 files changed, 929 insertions(+) create mode 100644 cmd/gotk/create_source_bucket.go create mode 100644 cmd/gotk/delete_source_bucket.go create mode 100644 cmd/gotk/export_source_bucket.go create mode 100644 cmd/gotk/get_source_bucket.go create mode 100644 cmd/gotk/reconcile_source_bucket.go create mode 100644 docs/cmd/gotk_create_source_bucket.md create mode 100644 docs/cmd/gotk_delete_source_bucket.md create mode 100644 docs/cmd/gotk_export_source_bucket.md create mode 100644 docs/cmd/gotk_get_sources_bucket.md create mode 100644 docs/cmd/gotk_reconcile_source_bucket.md diff --git a/cmd/gotk/create_source_bucket.go b/cmd/gotk/create_source_bucket.go new file mode 100644 index 00000000..65dcb824 --- /dev/null +++ b/cmd/gotk/create_source_bucket.go @@ -0,0 +1,229 @@ +/* +Copyright 2020 The Flux CD contributors. + +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" + "os" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + 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/v1alpha1" +) + +var createSourceBucketCmd = &cobra.Command{ + Use: "bucket [name]", + Short: "Create or update a Bucket source", + Long: ` +The create source bucket command generates a Bucket resource and waits for it to be downloaded. +For Buckets with static authentication, the credentials are stored in a Kubernetes secret.`, + Example: ` # Create a source from a Buckets using static authentication + gotk create source bucket podinfo \ + --bucket-name=podinfo \ + --endpoint=minio.minio.svc.cluster.local:9000 \ + --insecure=true \ + --access-key=myaccesskey \ + --secret-key=mysecretkey \ + --interval=10m + + # Create a source from an Amazon S3 Bucket using IAM authentication + gotk create source bucket podinfo \ + --bucket-name=podinfo \ + --provider=aws \ + --endpoint=s3.amazonaws.com \ + --region=us-east-1 \ + --interval=10m +`, + RunE: createSourceBucketCmdRun, +} + +var ( + sourceBucketName string + sourceBucketProvider string + sourceBucketEndpoint string + sourceBucketAccessKey string + sourceBucketSecretKey string + sourceBucketRegion string + sourceBucketInsecure bool +) + +func init() { + createSourceBucketCmd.Flags().StringVar(&sourceBucketProvider, "provider", "generic", "the S3 compatible storage provider name, can be 'generic' or 'aws'") + createSourceBucketCmd.Flags().StringVar(&sourceBucketName, "bucket-name", "", "the bucket name") + createSourceBucketCmd.Flags().StringVar(&sourceBucketEndpoint, "endpoint", "", "the bucket endpoint address") + createSourceBucketCmd.Flags().StringVar(&sourceBucketAccessKey, "access-key", "", "the bucket access key") + createSourceBucketCmd.Flags().StringVar(&sourceBucketSecretKey, "secret-key", "", "the bucket secret key") + createSourceBucketCmd.Flags().StringVar(&sourceBucketRegion, "region", "", "the bucket region") + createSourceBucketCmd.Flags().BoolVar(&sourceBucketInsecure, "insecure", false, "for when connecting to a non-TLS S3 HTTP endpoint") + + createSourceCmd.AddCommand(createSourceBucketCmd) +} + +func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("source name is required") + } + name := args[0] + secretName := fmt.Sprintf("bucket-%s", name) + + if sourceBucketProvider == "" { + return fmt.Errorf("provider is required") + } + + if sourceBucketName == "" { + return fmt.Errorf("bucket-name is required") + } + + if sourceBucketEndpoint == "" { + return fmt.Errorf("endpoint is required") + } + + sourceLabels, err := parseLabels() + if err != nil { + return err + } + + tmpDir, err := ioutil.TempDir("", name) + if err != nil { + return err + } + defer os.RemoveAll(tmpDir) + + bucket := sourcev1.Bucket{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: sourceLabels, + }, + Spec: sourcev1.BucketSpec{ + BucketName: sourceBucketName, + Provider: sourceBucketProvider, + Insecure: sourceBucketInsecure, + Endpoint: sourceBucketEndpoint, + Region: sourceBucketRegion, + Interval: metav1.Duration{ + Duration: interval, + }, + }, + } + + if export { + return exportBucket(bucket) + } + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + kubeClient, err := utils.kubeClient(kubeconfig) + if err != nil { + return err + } + + logger.Generatef("generating source") + + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: namespace, + }, + StringData: map[string]string{}, + } + + if sourceBucketAccessKey != "" && sourceBucketSecretKey != "" { + secret.StringData["accesskey"] = sourceBucketAccessKey + secret.StringData["secretkey"] = sourceBucketSecretKey + } + + if len(secret.StringData) > 0 { + logger.Actionf("applying secret with the bucket credentials") + if err := upsertSecret(ctx, kubeClient, secret); err != nil { + return err + } + bucket.Spec.SecretRef = &corev1.LocalObjectReference{ + Name: secretName, + } + logger.Successf("authentication configured") + } + + logger.Actionf("applying source") + if err := upsertBucket(ctx, kubeClient, bucket); err != nil { + return err + } + + logger.Waitingf("waiting for download") + if err := wait.PollImmediate(pollInterval, timeout, + isBucketReady(ctx, kubeClient, name, namespace)); err != nil { + return err + } + + logger.Successf("download completed") + + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + err = kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return fmt.Errorf("helm index failed: %w", err) + } + + if bucket.Status.Artifact != nil { + logger.Successf("fetched revision: %s", bucket.Status.Artifact.Revision) + } else { + return fmt.Errorf("index download failed, artifact not found") + } + + return nil +} + +func upsertBucket(ctx context.Context, kubeClient client.Client, bucket sourcev1.Bucket) error { + namespacedName := types.NamespacedName{ + Namespace: bucket.GetNamespace(), + Name: bucket.GetName(), + } + + var existing sourcev1.Bucket + err := kubeClient.Get(ctx, namespacedName, &existing) + if err != nil { + if errors.IsNotFound(err) { + if err := kubeClient.Create(ctx, &bucket); err != nil { + return err + } else { + logger.Successf("source created") + return nil + } + } + return err + } + + existing.Labels = bucket.Labels + existing.Spec = bucket.Spec + if err := kubeClient.Update(ctx, &existing); err != nil { + return err + } + + logger.Successf("source updated") + return nil +} diff --git a/cmd/gotk/delete_source_bucket.go b/cmd/gotk/delete_source_bucket.go new file mode 100644 index 00000000..c1d8c94c --- /dev/null +++ b/cmd/gotk/delete_source_bucket.go @@ -0,0 +1,86 @@ +/* +Copyright 2020 The Flux CD contributors. + +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" + + sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1" + "github.com/manifoldco/promptui" + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/types" +) + +var deleteSourceBucketCmd = &cobra.Command{ + Use: "bucket [name]", + Short: "Delete a Bucket source", + Long: "The delete source bucket command deletes the given Bucket from the cluster.", + Example: ` # Delete a Bucket source + gotk delete source bucket podinfo +`, + RunE: deleteSourceBucketCmdRun, +} + +func init() { + 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(), timeout) + defer cancel() + + kubeClient, err := utils.kubeClient(kubeconfig) + if err != nil { + return err + } + + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + + var bucket sourcev1.Bucket + err = kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return err + } + + if !deleteSilent { + 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, namespace) + err = kubeClient.Delete(ctx, &bucket) + if err != nil { + return err + } + logger.Successf("source deleted") + + return nil +} diff --git a/cmd/gotk/export_source_bucket.go b/cmd/gotk/export_source_bucket.go new file mode 100644 index 00000000..904ddc55 --- /dev/null +++ b/cmd/gotk/export_source_bucket.go @@ -0,0 +1,166 @@ +/* +Copyright 2020 The Flux CD contributors. + +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" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/yaml" + + sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1" +) + +var exportSourceBucketCmd = &cobra.Command{ + Use: "bucket [name]", + Short: "Export Bucket sources in YAML format", + Long: "The export source git command exports on or all Bucket sources in YAML format.", + Example: ` # Export all Bucket sources + gotk export source bucket --all > sources.yaml + + # Export a Bucket source including the static credentials + gotk export source bucket my-bucket --with-credentials > source.yaml +`, + RunE: exportSourceBucketCmdRun, +} + +func init() { + exportSourceCmd.AddCommand(exportSourceBucketCmd) +} + +func exportSourceBucketCmdRun(cmd *cobra.Command, args []string) error { + if !exportAll && len(args) < 1 { + return fmt.Errorf("name is required") + } + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + kubeClient, err := utils.kubeClient(kubeconfig) + if err != nil { + return err + } + + if exportAll { + var list sourcev1.BucketList + err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + if err != nil { + return err + } + + if len(list.Items) == 0 { + logger.Failuref("no source found in %s namespace", namespace) + return nil + } + + for _, bucket := range list.Items { + if err := exportBucket(bucket); err != nil { + return err + } + if exportSourceWithCred { + if err := exportBucketCredentials(ctx, kubeClient, bucket); err != nil { + return err + } + } + } + } else { + name := args[0] + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + var bucket sourcev1.Bucket + err = kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return err + } + if err := exportBucket(bucket); err != nil { + return err + } + if exportSourceWithCred { + return exportBucketCredentials(ctx, kubeClient, bucket) + } + } + return nil +} + +func exportBucket(source sourcev1.Bucket) error { + gvk := sourcev1.GroupVersion.WithKind(sourcev1.BucketKind) + export := sourcev1.Bucket{ + TypeMeta: metav1.TypeMeta{ + Kind: gvk.Kind, + APIVersion: gvk.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: source.Name, + Namespace: source.Namespace, + Labels: source.Labels, + Annotations: source.Annotations, + }, + Spec: source.Spec, + } + + data, err := yaml.Marshal(export) + if err != nil { + return err + } + + fmt.Println("---") + fmt.Println(resourceToString(data)) + return nil +} + +func exportBucketCredentials(ctx context.Context, kubeClient client.Client, source sourcev1.Bucket) error { + if source.Spec.SecretRef != nil { + namespacedName := types.NamespacedName{ + Namespace: source.Namespace, + Name: source.Spec.SecretRef.Name, + } + var cred corev1.Secret + err := kubeClient.Get(ctx, namespacedName, &cred) + if err != nil { + return fmt.Errorf("failed to retrieve secret %s, error: %w", namespacedName.Name, err) + } + + exported := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + }, + Data: cred.Data, + Type: cred.Type, + } + + data, err := yaml.Marshal(exported) + if err != nil { + return err + } + + fmt.Println("---") + fmt.Println(resourceToString(data)) + } + return nil +} diff --git a/cmd/gotk/get_source_bucket.go b/cmd/gotk/get_source_bucket.go new file mode 100644 index 00000000..6174de49 --- /dev/null +++ b/cmd/gotk/get_source_bucket.go @@ -0,0 +1,80 @@ +/* +Copyright 2020 The Flux CD contributors. + +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" + + sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1" + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var getSourceBucketCmd = &cobra.Command{ + Use: "bucket", + Short: "Get Bucket source statuses", + Long: "The get sources bucket command prints the status of the Bucket sources.", + Example: ` # List all Buckets and their status + gotk get sources bucket +`, + RunE: getSourceBucketCmdRun, +} + +func init() { + getSourceCmd.AddCommand(getSourceBucketCmd) +} + +func getSourceBucketCmdRun(cmd *cobra.Command, args []string) error { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + kubeClient, err := utils.kubeClient(kubeconfig) + if err != nil { + return err + } + + var list sourcev1.BucketList + err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + if err != nil { + return err + } + + if len(list.Items) == 0 { + logger.Failuref("no sources found in %s namespace", namespace) + return nil + } + + for _, source := range list.Items { + isInitialized := false + for _, condition := range source.Status.Conditions { + if condition.Type == sourcev1.ReadyCondition { + if condition.Status != corev1.ConditionFalse { + logger.Successf("%s last fetched revision: %s", source.GetName(), source.Status.Artifact.Revision) + } else { + logger.Failuref("%s %s", source.GetName(), condition.Message) + } + isInitialized = true + break + } + } + if !isInitialized { + logger.Failuref("%s is not ready", source.GetName()) + } + } + return nil +} diff --git a/cmd/gotk/reconcile_source_bucket.go b/cmd/gotk/reconcile_source_bucket.go new file mode 100644 index 00000000..fb4fbbbf --- /dev/null +++ b/cmd/gotk/reconcile_source_bucket.go @@ -0,0 +1,131 @@ +/* +Copyright 2020 The Flux CD contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + "time" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/client" + + consts "github.com/fluxcd/pkg/runtime" + sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1" +) + +var reconcileSourceBucketCmd = &cobra.Command{ + Use: "bucket [name]", + Short: "Reconcile a Bucket source", + Long: `The reconcile source command triggers a reconciliation of a Bucket resource and waits for it to finish.`, + Example: ` # Trigger a reconciliation for an existing source + gotk reconcile source bucket podinfo +`, + RunE: syncSourceBucketCmdRun, +} + +func init() { + reconcileSourceCmd.AddCommand(reconcileSourceBucketCmd) +} + +func syncSourceBucketCmdRun(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(), timeout) + defer cancel() + + kubeClient, err := utils.kubeClient(kubeconfig) + if err != nil { + return err + } + + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + + logger.Actionf("annotating source %s in %s namespace", name, namespace) + var bucket sourcev1.Bucket + err = kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return err + } + + if bucket.Annotations == nil { + bucket.Annotations = map[string]string{ + consts.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano), + } + } else { + bucket.Annotations[consts.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano) + } + if err := kubeClient.Update(ctx, &bucket); err != nil { + return err + } + logger.Successf("source annotated") + + logger.Waitingf("waiting for reconciliation") + if err := wait.PollImmediate(pollInterval, timeout, + isBucketReady(ctx, kubeClient, name, namespace)); err != nil { + return err + } + + logger.Successf("bucket reconciliation completed") + + err = kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return err + } + + if bucket.Status.Artifact != nil { + logger.Successf("fetched revision %s", bucket.Status.Artifact.Revision) + } else { + return fmt.Errorf("bucket reconciliation failed, artifact not found") + } + return nil +} + +func isBucketReady(ctx context.Context, kubeClient client.Client, name, namespace string) wait.ConditionFunc { + return func() (bool, error) { + var bucket sourcev1.Bucket + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + + err := kubeClient.Get(ctx, namespacedName, &bucket) + if err != nil { + return false, err + } + + for _, condition := range bucket.Status.Conditions { + if condition.Type == sourcev1.ReadyCondition { + if condition.Status == corev1.ConditionTrue { + return true, nil + } else if condition.Status == corev1.ConditionFalse { + return false, fmt.Errorf(condition.Message) + } + } + } + return false, nil + } +} diff --git a/docs/cmd/gotk_create_source.md b/docs/cmd/gotk_create_source.md index a75c25a2..642977a8 100644 --- a/docs/cmd/gotk_create_source.md +++ b/docs/cmd/gotk_create_source.md @@ -27,6 +27,7 @@ The create source sub-commands generate sources. ### SEE ALSO * [gotk create](gotk_create.md) - Create or update sources and resources +* [gotk create source bucket](gotk_create_source_bucket.md) - Create or update a Bucket source * [gotk create source git](gotk_create_source_git.md) - Create or update a GitRepository source * [gotk create source helm](gotk_create_source_helm.md) - Create or update a HelmRepository source diff --git a/docs/cmd/gotk_create_source_bucket.md b/docs/cmd/gotk_create_source_bucket.md new file mode 100644 index 00000000..76c3a543 --- /dev/null +++ b/docs/cmd/gotk_create_source_bucket.md @@ -0,0 +1,65 @@ +## gotk create source bucket + +Create or update a Bucket source + +### Synopsis + + +The create source bucket command generates a Bucket resource and waits for it to be downloaded. +For Buckets with static authentication, the credentials are stored in a Kubernetes secret. + +``` +gotk create source bucket [name] [flags] +``` + +### Examples + +``` + # Create a source from a Buckets using static authentication + gotk create source bucket podinfo \ + --bucket-name=podinfo \ + --endpoint=minio.minio.svc.cluster.local:9000 \ + --insecure=true \ + --access-key=myaccesskey \ + --secret-key=mysecretkey \ + --interval=10m + + # Create a source from an Amazon S3 Bucket using IAM authentication + gotk create source bucket podinfo \ + --bucket-name=podinfo \ + --provider=aws \ + --endpoint=s3.amazonaws.com \ + --region=us-east-1 \ + --interval=10m + +``` + +### Options + +``` + --access-key string the bucket access key + --bucket-name string the bucket name + --endpoint string the bucket endpoint address + -h, --help help for bucket + --insecure for when connecting to a non-TLS S3 HTTP endpoint + --provider string the S3 compatible storage provider name, can be 'generic' or 'aws' (default "generic") + --region string the bucket region + --secret-key string the bucket secret key +``` + +### Options inherited from parent commands + +``` + --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 "gitops-system") + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects +``` + +### SEE ALSO + +* [gotk create source](gotk_create_source.md) - Create or update sources + diff --git a/docs/cmd/gotk_delete_source.md b/docs/cmd/gotk_delete_source.md index 180ba57e..9626c113 100644 --- a/docs/cmd/gotk_delete_source.md +++ b/docs/cmd/gotk_delete_source.md @@ -25,6 +25,7 @@ The delete source sub-commands delete sources. ### SEE ALSO * [gotk delete](gotk_delete.md) - Delete sources and resources +* [gotk delete source bucket](gotk_delete_source_bucket.md) - Delete a Bucket source * [gotk delete source git](gotk_delete_source_git.md) - Delete a GitRepository source * [gotk delete source helm](gotk_delete_source_helm.md) - Delete a HelmRepository source diff --git a/docs/cmd/gotk_delete_source_bucket.md b/docs/cmd/gotk_delete_source_bucket.md new file mode 100644 index 00000000..8241acb9 --- /dev/null +++ b/docs/cmd/gotk_delete_source_bucket.md @@ -0,0 +1,40 @@ +## gotk delete source bucket + +Delete a Bucket source + +### Synopsis + +The delete source bucket command deletes the given Bucket from the cluster. + +``` +gotk delete source bucket [name] [flags] +``` + +### Examples + +``` + # Delete a Bucket source + gotk delete source bucket podinfo + +``` + +### Options + +``` + -h, --help help for bucket +``` + +### Options inherited from parent commands + +``` + --kubeconfig string path to the kubeconfig file (default "~/.kube/config") + -n, --namespace string the namespace scope for this operation (default "gitops-system") + -s, --silent delete resource without asking for confirmation + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects +``` + +### SEE ALSO + +* [gotk delete source](gotk_delete_source.md) - Delete sources + diff --git a/docs/cmd/gotk_export_source.md b/docs/cmd/gotk_export_source.md index 5cbf32fd..d80fc828 100644 --- a/docs/cmd/gotk_export_source.md +++ b/docs/cmd/gotk_export_source.md @@ -26,6 +26,7 @@ The export source sub-commands export sources in YAML format. ### SEE ALSO * [gotk export](gotk_export.md) - Export resources in YAML format +* [gotk export source bucket](gotk_export_source_bucket.md) - Export Bucket sources in YAML format * [gotk export source git](gotk_export_source_git.md) - Export GitRepository sources in YAML format * [gotk export source helm](gotk_export_source_helm.md) - Export HelmRepository sources in YAML format diff --git a/docs/cmd/gotk_export_source_bucket.md b/docs/cmd/gotk_export_source_bucket.md new file mode 100644 index 00000000..2d0edc78 --- /dev/null +++ b/docs/cmd/gotk_export_source_bucket.md @@ -0,0 +1,44 @@ +## gotk export source bucket + +Export Bucket sources in YAML format + +### Synopsis + +The export source git command exports on or all Bucket sources in YAML format. + +``` +gotk export source bucket [name] [flags] +``` + +### Examples + +``` + # Export all Bucket sources + gotk export source bucket --all > sources.yaml + + # Export a Bucket source including the static credentials + gotk export source bucket my-bucket --with-credentials > source.yaml + +``` + +### Options + +``` + -h, --help help for bucket +``` + +### Options inherited from parent commands + +``` + --all select all resources + --kubeconfig string path to the kubeconfig file (default "~/.kube/config") + -n, --namespace string the namespace scope for this operation (default "gitops-system") + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects + --with-credentials include credential secrets +``` + +### SEE ALSO + +* [gotk export source](gotk_export_source.md) - Export sources + diff --git a/docs/cmd/gotk_get_sources.md b/docs/cmd/gotk_get_sources.md index efcfdb7c..5cae4a07 100644 --- a/docs/cmd/gotk_get_sources.md +++ b/docs/cmd/gotk_get_sources.md @@ -24,6 +24,7 @@ The get source sub-commands print the statuses of the sources. ### SEE ALSO * [gotk get](gotk_get.md) - Get sources and resources +* [gotk get sources bucket](gotk_get_sources_bucket.md) - Get Bucket source statuses * [gotk get sources git](gotk_get_sources_git.md) - Get GitRepository source statuses * [gotk get sources helm](gotk_get_sources_helm.md) - Get HelmRepository source statuses diff --git a/docs/cmd/gotk_get_sources_bucket.md b/docs/cmd/gotk_get_sources_bucket.md new file mode 100644 index 00000000..bf748ed6 --- /dev/null +++ b/docs/cmd/gotk_get_sources_bucket.md @@ -0,0 +1,39 @@ +## gotk get sources bucket + +Get Bucket source statuses + +### Synopsis + +The get sources bucket command prints the status of the Bucket sources. + +``` +gotk get sources bucket [flags] +``` + +### Examples + +``` + # List all Buckets and their status + gotk get sources bucket + +``` + +### Options + +``` + -h, --help help for bucket +``` + +### Options inherited from parent commands + +``` + --kubeconfig string path to the kubeconfig file (default "~/.kube/config") + -n, --namespace string the namespace scope for this operation (default "gitops-system") + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects +``` + +### SEE ALSO + +* [gotk get sources](gotk_get_sources.md) - Get source statuses + diff --git a/docs/cmd/gotk_reconcile_source.md b/docs/cmd/gotk_reconcile_source.md index 439da16a..56310014 100644 --- a/docs/cmd/gotk_reconcile_source.md +++ b/docs/cmd/gotk_reconcile_source.md @@ -24,6 +24,7 @@ The reconcile source sub-commands trigger a reconciliation of sources. ### SEE ALSO * [gotk reconcile](gotk_reconcile.md) - Reconcile sources and resources +* [gotk reconcile source bucket](gotk_reconcile_source_bucket.md) - Reconcile a Bucket source * [gotk reconcile source git](gotk_reconcile_source_git.md) - Reconcile a GitRepository source * [gotk reconcile source helm](gotk_reconcile_source_helm.md) - Reconcile a HelmRepository source diff --git a/docs/cmd/gotk_reconcile_source_bucket.md b/docs/cmd/gotk_reconcile_source_bucket.md new file mode 100644 index 00000000..ed801c63 --- /dev/null +++ b/docs/cmd/gotk_reconcile_source_bucket.md @@ -0,0 +1,39 @@ +## gotk reconcile source bucket + +Reconcile a Bucket source + +### Synopsis + +The reconcile source command triggers a reconciliation of a Bucket resource and waits for it to finish. + +``` +gotk reconcile source bucket [name] [flags] +``` + +### Examples + +``` + # Trigger a reconciliation for an existing source + gotk reconcile source bucket podinfo + +``` + +### Options + +``` + -h, --help help for bucket +``` + +### Options inherited from parent commands + +``` + --kubeconfig string path to the kubeconfig file (default "~/.kube/config") + -n, --namespace string the namespace scope for this operation (default "gitops-system") + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects +``` + +### SEE ALSO + +* [gotk reconcile source](gotk_reconcile_source.md) - Reconcile sources + diff --git a/mkdocs.yml b/mkdocs.yml index 6053cdc9..560fa32b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -85,6 +85,7 @@ nav: - Create source: cmd/gotk_create_source.md - Create source git: cmd/gotk_create_source_git.md - Create source helm: cmd/gotk_create_source_helm.md + - Create source bucket: cmd/gotk_create_source_bucket.md - Create tenant: cmd/gotk_create_tenant.md - Delete: cmd/gotk_delete.md - Delete kustomization: cmd/gotk_delete_kustomization.md @@ -92,18 +93,21 @@ nav: - Delete source: cmd/gotk_delete_source.md - Delete source git: cmd/gotk_delete_source_git.md - Delete source helm: cmd/gotk_delete_source_helm.md + - Delete source bucket: cmd/gotk_delete_source_bucket.md - Export: cmd/gotk_export.md - Export kustomization: cmd/gotk_export_kustomization.md - Export helmrelease: cmd/gotk_export_helmrelease.md - Export source: cmd/gotk_export_source.md - Export source git: cmd/gotk_export_source_git.md - Export source helm: cmd/gotk_export_source_helm.md + - Export source bucket: cmd/gotk_export_source_bucket.md - Get: cmd/gotk_get.md - Get kustomizations: cmd/gotk_get_kustomizations.md - Get helmreleases: cmd/gotk_get_helmreleases.md - Get sources: cmd/gotk_get_sources.md - Get sources git: cmd/gotk_get_sources_git.md - Get sources helm: cmd/gotk_get_sources_helm.md + - Get sources bucket: cmd/gotk_get_sources_bucket.md - Install: cmd/gotk_install.md - Resume: cmd/gotk_resume.md - Resume kustomization: cmd/gotk_resume_kustomization.md @@ -117,6 +121,7 @@ nav: - Reconcile source: cmd/gotk_reconcile_source.md - Reconcile source git: cmd/gotk_reconcile_source_git.md - Reconcile source helm: cmd/gotk_reconcile_source_helm.md + - Reconcile source bucket: cmd/gotk_reconcile_source_bucket.md - Uninstall: cmd/gotk_uninstall.md - Roadmap: roadmap/index.md - Contributing: contributing/index.md