Skip to content

Commit

Permalink
fix loggin in tf.output
Browse files Browse the repository at this point in the history
Signed-off-by: Chanwit Kaewkasi <chanwit@gmail.com>
  • Loading branch information
chanwit committed Jun 6, 2023
1 parent fda60c8 commit 98a0688
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 114 deletions.
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 98a0688

Please sign in to comment.