Skip to content

Commit

Permalink
feat: introduce json format for inline module (#165)
Browse files Browse the repository at this point in the history
Signed-off-by: Dennis Kniep <kniepdennis@gmail.com>
  • Loading branch information
denniskniep committed Jul 31, 2024
1 parent b294b63 commit 588d051
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
16 changes: 15 additions & 1 deletion apis/v1beta1/workspace_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,29 @@ const (
ModuleSourceInline ModuleSource = "Inline"
)

// A InlineFormat specifies the format of the inline Terraform content.
// +kubebuilder:validation:Enum=HCL;JSON
type InlineFormat string

// Vars file formats.
var (
InlineFormatHCL InlineFormat = "HCL"
InlineFormatJSON InlineFormat = "JSON"
)

// WorkspaceParameters are the configurable fields of a Workspace.
type WorkspaceParameters struct {
// The root module of this workspace; i.e. the module containing its main.tf
// file. When the workspace's source is 'Remote' (the default) this can be
// any address supported by terraform init -from-module, for example a git
// repository or an S3 bucket. When the workspace's source is 'Inline' the
// content of a simple main.tf file may be written inline.
// content of a simple main.tf or main.tf.json file may be written inline.
Module string `json:"module"`

// Specifies the format of the inline Terraform content
// if Source is 'Inline'
InlineFormat InlineFormat `json:"inlineFormat,omitempty"`

// Source of the root module of this workspace.
Source ModuleSource `json:"source"`

Expand Down
11 changes: 8 additions & 3 deletions internal/controller/workspace/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const (
errWriteCreds = "cannot write Terraform credentials"
errWriteGitCreds = "cannot write .git-credentials to /tmp dir"
errWriteConfig = "cannot write Terraform configuration " + tfConfig
errWriteMain = "cannot write Terraform configuration " + tfMain
errWriteMain = "cannot write Terraform configuration "
errWriteBackend = "cannot write Terraform configuration " + tfBackendFile
errInit = "cannot initialize Terraform configuration"
errWorkspace = "cannot select Terraform workspace"
Expand All @@ -87,6 +87,7 @@ const (
// TODO(negz): Make the Terraform binary path and work dir configurable.
tfPath = "terraform"
tfMain = "main.tf"
tfMainJSON = "main.tf.json"
tfConfig = "crossplane-provider-config.tf"
tfBackendFile = "crossplane.remote.tfbackend"
)
Expand Down Expand Up @@ -249,8 +250,12 @@ func (c *connector) Connect(ctx context.Context, mg resource.Managed) (managed.E
}

case v1beta1.ModuleSourceInline:
if err := c.fs.WriteFile(filepath.Join(dir, tfMain), []byte(cr.Spec.ForProvider.Module), 0600); err != nil {
return nil, errors.Wrap(err, errWriteMain)
filename := tfMain
if cr.Spec.ForProvider.InlineFormat == v1beta1.InlineFormatJSON {
filename = tfMainJSON
}
if err := c.fs.WriteFile(filepath.Join(dir, filename), []byte(cr.Spec.ForProvider.Module), 0600); err != nil {
return nil, errors.Wrap(err, errWriteMain+filename)
}
}

Expand Down
38 changes: 37 additions & 1 deletion internal/controller/workspace/workspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,43 @@ func TestConnect(t *testing.T) {
},
},
},
want: errors.Wrap(errBoom, errWriteMain),
want: errors.Wrap(errBoom, errWriteMain+tfMain),
},
"WriteMainJsonError": {
reason: "We should return any error encountered while writing our main.tf file",
fields: fields{
kube: &test.MockClient{
MockGet: test.NewMockGetFn(nil),
},
usage: resource.TrackerFn(func(_ context.Context, _ resource.Managed) error { return nil }),
fs: afero.Afero{
Fs: &ErrFs{
Fs: afero.NewMemMapFs(),
errs: map[string]error{filepath.Join(tfDir, string(uid), tfMainJSON): errBoom},
},
},
terraform: func(_ string, _ bool, _ ...string) tfclient {
return &MockTf{
MockInit: func(ctx context.Context, o ...terraform.InitOption) error { return nil },
}
},
},
args: args{
mg: &v1beta1.Workspace{
ObjectMeta: metav1.ObjectMeta{UID: uid},
Spec: v1beta1.WorkspaceSpec{
ResourceSpec: xpv1.ResourceSpec{
ProviderConfigReference: &xpv1.Reference{},
},
ForProvider: v1beta1.WorkspaceParameters{
Module: "I'm JSON!",
Source: v1beta1.ModuleSourceInline,
InlineFormat: v1beta1.InlineFormatJSON,
},
},
},
},
want: errors.Wrap(errBoom, errWriteMain+tfMainJSON),
},
"TerraformInitError": {
reason: "We should return any error encountered while initializing Terraform",
Expand Down
10 changes: 9 additions & 1 deletion package/crds/tf.upbound.io_workspaces.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,21 @@ spec:
items:
type: string
type: array
inlineFormat:
description: |-
Specifies the format of the inline Terraform content
if Source is 'Inline'
enum:
- HCL
- JSON
type: string
module:
description: |-
The root module of this workspace; i.e. the module containing its main.tf
file. When the workspace's source is 'Remote' (the default) this can be
any address supported by terraform init -from-module, for example a git
repository or an S3 bucket. When the workspace's source is 'Inline' the
content of a simple main.tf file may be written inline.
content of a simple main.tf or main.tf.json file may be written inline.
type: string
planArgs:
description: Arguments to be included in the terraform plan CLI
Expand Down

0 comments on commit 588d051

Please sign in to comment.