Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions cmd/tfctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ var (
BuildVersion string
)

var defaultNamespace = "flux-system"
var kubeconfigArgs = genericclioptions.NewConfigFlags(false)
var (
defaultNamespace = "flux-system"
kubeconfigArgs = genericclioptions.NewConfigFlags(false)
)

func main() {
cmd := newRootCommand()
Expand Down Expand Up @@ -127,20 +129,47 @@ func buildUninstallCmd(app *tfctl.CLI) *cobra.Command {
}

var reconcileExamples = `
# Reconcile a Terraform resource
# Reconcile a specific Terraform resource
tfctl reconcile --namespace=default my-resource

# Reconcile all Terraform resources in the namespace
tfctl reconcile --all
`

func buildReconcileCmd(app *tfctl.CLI) *cobra.Command {
return &cobra.Command{
reconcile := &cobra.Command{
Use: "reconcile NAME",
Short: "Trigger a reconcile of the provided resource",
Short: "Trigger a reconcile of the provided resource or all resources",
Example: strings.Trim(reconcileExamples, "\n"),
Args: cobra.ExactArgs(1),
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return app.Reconcile(os.Stdout, args[0])
all, err := cmd.Flags().GetBool("all")
if err != nil {
return err
}

resource := ""

if all {
if len(args) > 0 {
return errors.New("cannot use --all and provide resource name at the same time")
}
} else {
if len(args) == 0 {
return errors.New("resource name required unless --all is specified")
}
resource = args[0]
if len(args) > 1 {
return errors.New("only one resource name accepted")
Comment thread
cschindlbeck marked this conversation as resolved.
}
}
return app.Reconcile(os.Stdout, resource)
},
}

reconcile.Flags().Bool("all", false, "Trigger reconcile for all Terraform resources in the namespace")

return reconcile
}

var suspendExamples = `
Expand Down
33 changes: 28 additions & 5 deletions tfctl/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tfctl

import (
"context"
"errors"
"fmt"
"io"
"time"
Expand All @@ -13,25 +14,47 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

// Reconcile annotates the given object
// Reconcile triggers a reconciliation of Terraform resources.
// If resource == "", it reconciles all resources in the namespace.
func (c *CLI) Reconcile(out io.Writer, resource string) error {
if resource == "" {
return reconcileAllResources(context.TODO(), out, c.client, c.namespace)
}
key := types.NamespacedName{
Name: resource,
Namespace: c.namespace,
}

err := requestReconciliation(context.TODO(), c.client, key)
if err != nil {
return err
}

fmt.Fprintf(out, " Reconcile requested for %s/%s\n", c.namespace, resource)

return nil
}

func reconcileAllResources(ctx context.Context, out io.Writer, kubeClient client.Client, namespace string) error {
terraformList := &infrav1.TerraformList{}
if err := kubeClient.List(ctx, terraformList, client.InNamespace(namespace)); err != nil {
return err
}

var errs []error
for _, terraform := range terraformList.Items {
key := types.NamespacedName{
Name: terraform.Name,
Namespace: terraform.Namespace,
}
if err := requestReconciliation(ctx, kubeClient, key); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile %s/%s: %w", terraform.Namespace, terraform.Name, err))
} else {
fmt.Fprintf(out, " Reconcile requested for %s/%s\n", terraform.Namespace, terraform.Name)
}
}
return errors.Join(errs...)
}

func requestReconciliation(ctx context.Context, kubeClient client.Client, namespacedName types.NamespacedName) error {
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
terraform := &infrav1.Terraform{}
if err := kubeClient.Get(ctx, namespacedName, terraform); err != nil {
return err
Expand Down
Loading