Skip to content

Commit

Permalink
Merge pull request flux-iac#651 from weaveworks/fix-logging-outputs-b…
Browse files Browse the repository at this point in the history
…ump-v0.14.4

Fix logging outputs and bump v0.14.4
  • Loading branch information
Chanwit Kaewkasi authored Jun 6, 2023
2 parents fda60c8 + badc76b commit b203174
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 121 deletions.
4 changes: 2 additions & 2 deletions charts/tf-controller/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ apiVersion: v2
name: tf-controller
description: The Helm chart for Weave GitOps Terraform Controller
type: application
version: 0.11.3-lts
appVersion: "v0.14.3"
version: 0.11.4-lts
appVersion: "v0.14.4"
4 changes: 2 additions & 2 deletions charts/tf-controller/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Weave GitOps Terraform Controller

![Version: 0.11.3-lts](https://img.shields.io/badge/Version-0.11.3--lts-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.14.3](https://img.shields.io/badge/AppVersion-v0.14.3-informational?style=flat-square)
![Version: 0.11.4-lts](https://img.shields.io/badge/Version-0.11.4--lts-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.14.4](https://img.shields.io/badge/AppVersion-v0.14.4-informational?style=flat-square)

The Helm chart for Weave GitOps Terraform Controller

Expand Down Expand Up @@ -69,7 +69,7 @@ __Note__: If you need to use the `imagePullSecrets` it would be best to set `ser
| rbac.create | bool | `true` | If `true`, create and use RBAC resources |
| replicaCount | int | `1` | Number of TF-Controller pods to deploy |
| resources | object | `{"limits":{"cpu":"1000m","memory":"1Gi"},"requests":{"cpu":"200m","memory":"64Mi"}}` | Resource limits and requests |
| runner | object | `{"creationTimeout":"5m0s","grpc":{"maxMessageSize":4},"image":{"repository":"ghcr.io/weaveworks/tf-runner","tag":"v0.14.3"},"serviceAccount":{"allowedNamespaces":[],"annotations":{},"create":true,"name":""}}` | Runner-specific configurations |
| runner | object | `{"creationTimeout":"5m0s","grpc":{"maxMessageSize":4},"image":{"repository":"ghcr.io/weaveworks/tf-runner","tag":"v0.14.4"},"serviceAccount":{"allowedNamespaces":[],"annotations":{},"create":true,"name":""}}` | Runner-specific configurations |
| runner.creationTimeout | string | `"5m0s"` | Timeout for runner-creation (Controller) |
| runner.grpc.maxMessageSize | int | `4` | Maximum GRPC message size (Controller) |
| runner.image.repository | string | `"ghcr.io/weaveworks/tf-runner"` | Runner image repository |
Expand Down
4 changes: 2 additions & 2 deletions charts/tf-controller/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ image:
pullPolicy: IfNotPresent
# -- Overrides the image tag whose default is the chart appVersion.
# @default -- `.Chart.AppVersion`
tag: "v0.14.3"
tag: "v0.14.4"
# -- Controller image pull secret
imagePullSecrets: []
# -- Resource limits and requests
Expand Down Expand Up @@ -108,7 +108,7 @@ runner:
repository: ghcr.io/weaveworks/tf-runner
# -- Runner image tag
# @default -- `.Chart.AppVersion`
tag: "v0.14.3"
tag: "v0.14.4"
grpc:
# -- Maximum GRPC message size (Controller)
maxMessageSize: 4
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ generatorOptions:
images:
- name: weaveworks/tf-controller
newName: ghcr.io/weaveworks/tf-controller
newTag: v0.14.3
newTag: v0.14.4
114 changes: 0 additions & 114 deletions runner/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ import (
"io/ioutil"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"os"
"os/exec"
"path/filepath"
"reflect"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"strings"
Expand Down Expand Up @@ -588,118 +586,6 @@ func (r *TerraformRunnerServer) GetInventory(ctx context.Context, req *GetInvent
return &GetInventoryReply{Inventories: getInventoryFromTerraformModule(state.Values.RootModule)}, nil
}

func (r *TerraformRunnerServer) Output(ctx context.Context, req *OutputRequest) (*OutputReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("creating outputs")
if req.TfInstance != r.InstanceID {
err := fmt.Errorf("no TF instance found")
log.Error(err, "no terraform")
return nil, err
}

outputs, err := r.tf.Output(ctx)
if err != nil {
log.Error(err, "unable to get outputs")
return nil, err
}

outputReply := &OutputReply{Outputs: map[string]*OutputMeta{}}
for k, v := range outputs {
outputReply.Outputs[k] = &OutputMeta{
Sensitive: v.Sensitive,
Type: v.Type,
Value: v.Value,
}
}
return outputReply, nil
}

func (r *TerraformRunnerServer) WriteOutputs(ctx context.Context, req *WriteOutputsRequest) (*WriteOutputsReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("write outputs to secret")

objectKey := types.NamespacedName{Namespace: req.Namespace, Name: req.SecretName}
var outputSecret corev1.Secret

drift := true
create := true
if err := r.Client.Get(ctx, objectKey, &outputSecret); err == nil {
// if everything is there, we don't write anything
if reflect.DeepEqual(outputSecret.Data, req.Data) {
drift = false
} else {
// found, but need update
create = false
}
} else if apierrors.IsNotFound(err) == false {
log.Error(err, "unable to get output secret")
return nil, err
}

if drift {
if create {
vTrue := true
outputSecret = corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: req.SecretName,
Namespace: req.Namespace,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: infrav1.GroupVersion.Group + "/" + infrav1.GroupVersion.Version,
Kind: infrav1.TerraformKind,
Name: req.Name,
UID: types.UID(req.Uuid),
Controller: &vTrue,
},
},
},
Type: corev1.SecretTypeOpaque,
Data: req.Data,
}

err := r.Client.Create(ctx, &outputSecret)
if err != nil {
log.Error(err, "unable to create secret")
return nil, err
}
} else {
outputSecret.Data = req.Data
err := r.Client.Update(ctx, &outputSecret)
if err != nil {
log.Error(err, "unable to update secret")
return nil, err
}
}

return &WriteOutputsReply{Message: "ok", Changed: true}, nil
}

return &WriteOutputsReply{Message: "ok", Changed: false}, nil
}

func (r *TerraformRunnerServer) GetOutputs(ctx context.Context, req *GetOutputsRequest) (*GetOutputsReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("get outputs")
outputKey := types.NamespacedName{Namespace: req.Namespace, Name: req.SecretName}
outputSecret := corev1.Secret{}
err := r.Client.Get(ctx, outputKey, &outputSecret)
if err != nil {
err = fmt.Errorf("error getting terraform output for health checks: %s", err)
log.Error(err, "unable to check terraform health")
return nil, err
}

outputs := map[string]string{}
// parse map[string][]byte to map[string]string for go template parsing
if len(outputSecret.Data) > 0 {
for k, v := range outputSecret.Data {
outputs[k] = string(v)
}
}

return &GetOutputsReply{Outputs: outputs}, nil
}

func (r *TerraformRunnerServer) FinalizeSecrets(ctx context.Context, req *FinalizeSecretsRequest) (*FinalizeSecretsReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("finalize the output secrets")
Expand Down
140 changes: 140 additions & 0 deletions runner/server_outputs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package runner

import (
"context"
"fmt"
"io"
"reflect"

"github.com/hashicorp/terraform-exec/tfexec"
infrav1 "github.com/weaveworks/tf-controller/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
)

func (r *TerraformRunnerServer) tfOutput(ctx context.Context, opts ...tfexec.OutputOption) (map[string]tfexec.OutputMeta, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)

// This is the only place where we disable the logger
r.tf.SetStdout(io.Discard)
r.tf.SetStderr(io.Discard)

defer r.initLogger(log)

return r.tf.Output(ctx, opts...)
}

func (r *TerraformRunnerServer) Output(ctx context.Context, req *OutputRequest) (*OutputReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("creating outputs")
if req.TfInstance != r.InstanceID {
err := fmt.Errorf("no TF instance found")
log.Error(err, "no terraform")
return nil, err
}

outputs, err := r.tfOutput(ctx)
if err != nil {
log.Error(err, "unable to get outputs")
return nil, err
}

outputReply := &OutputReply{Outputs: map[string]*OutputMeta{}}
for k, v := range outputs {
outputReply.Outputs[k] = &OutputMeta{
Sensitive: v.Sensitive,
Type: v.Type,
Value: v.Value,
}
}
return outputReply, nil
}

func (r *TerraformRunnerServer) WriteOutputs(ctx context.Context, req *WriteOutputsRequest) (*WriteOutputsReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("write outputs to secret")

objectKey := types.NamespacedName{Namespace: req.Namespace, Name: req.SecretName}
var outputSecret corev1.Secret

drift := true
create := true
if err := r.Client.Get(ctx, objectKey, &outputSecret); err == nil {
// if everything is there, we don't write anything
if reflect.DeepEqual(outputSecret.Data, req.Data) {
drift = false
} else {
// found, but need update
create = false
}
} else if apierrors.IsNotFound(err) == false {
log.Error(err, "unable to get output secret")
return nil, err
}

if drift {
if create {
vTrue := true
outputSecret = corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: req.SecretName,
Namespace: req.Namespace,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: infrav1.GroupVersion.Group + "/" + infrav1.GroupVersion.Version,
Kind: infrav1.TerraformKind,
Name: req.Name,
UID: types.UID(req.Uuid),
Controller: &vTrue,
},
},
},
Type: corev1.SecretTypeOpaque,
Data: req.Data,
}

err := r.Client.Create(ctx, &outputSecret)
if err != nil {
log.Error(err, "unable to create secret")
return nil, err
}
} else {
outputSecret.Data = req.Data
err := r.Client.Update(ctx, &outputSecret)
if err != nil {
log.Error(err, "unable to update secret")
return nil, err
}
}

return &WriteOutputsReply{Message: "ok", Changed: true}, nil
}

return &WriteOutputsReply{Message: "ok", Changed: false}, nil
}

func (r *TerraformRunnerServer) GetOutputs(ctx context.Context, req *GetOutputsRequest) (*GetOutputsReply, error) {
log := ctrl.LoggerFrom(ctx, "instance-id", r.InstanceID).WithName(loggerName)
log.Info("get outputs")
outputKey := types.NamespacedName{Namespace: req.Namespace, Name: req.SecretName}
outputSecret := corev1.Secret{}
err := r.Client.Get(ctx, outputKey, &outputSecret)
if err != nil {
err = fmt.Errorf("error getting terraform output for health checks: %s", err)
log.Error(err, "unable to check terraform health")
return nil, err
}

outputs := map[string]string{}
// parse map[string][]byte to map[string]string for go template parsing
if len(outputSecret.Data) > 0 {
for k, v := range outputSecret.Data {
outputs[k] = string(v)
}
}

return &GetOutputsReply{Outputs: outputs}, nil
}

0 comments on commit b203174

Please sign in to comment.