Skip to content

Commit da1a0e4

Browse files
committed
add simple transformation functionality
1 parent 01e590b commit da1a0e4

File tree

6 files changed

+138
-34
lines changed

6 files changed

+138
-34
lines changed

cmd/plugin/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"fmt"
55
"os"
66

7-
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/cli/cluster"
7+
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/cli/clu2adv"
88
"github.com/spf13/cobra"
99
)
1010

@@ -16,7 +16,7 @@ func main() {
1616
}
1717

1818
terraformCmd.AddCommand(
19-
cluster.Builder(),
19+
clu2adv.Builder(),
2020
)
2121

2222
completionOption := &cobra.CompletionOptions{

go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ module github.com/mongodb-labs/atlas-cli-plugin-terraform
33
go 1.23.4
44

55
require (
6+
github.com/hashicorp/hcl/v2 v2.23.0
67
github.com/spf13/afero v1.12.0
78
github.com/spf13/cobra v1.8.1
89
)
910

1011
require (
12+
github.com/agext/levenshtein v1.2.1 // indirect
13+
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
14+
github.com/google/go-cmp v0.6.0 // indirect
1115
github.com/inconshreveable/mousetrap v1.1.0 // indirect
16+
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
17+
github.com/pmezard/go-difflib v1.0.0 // indirect
18+
github.com/sebdah/goldie/v2 v2.5.5 // indirect
19+
github.com/sergi/go-diff v1.3.1 // indirect
1220
github.com/spf13/pflag v1.0.5 // indirect
21+
github.com/zclconf/go-cty v1.16.2 // indirect
22+
golang.org/x/mod v0.22.0 // indirect
23+
golang.org/x/sync v0.10.0 // indirect
1324
golang.org/x/text v0.21.0 // indirect
25+
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
1426
)

go.sum

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,56 @@
1+
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
2+
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
3+
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
4+
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
15
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
6+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
10+
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
11+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
12+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
13+
github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos=
14+
github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
215
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
316
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
17+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
18+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
19+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
20+
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
21+
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
22+
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
23+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
24+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
425
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
26+
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
27+
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
28+
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
29+
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
30+
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
531
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
632
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
733
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
834
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
935
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
1036
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
37+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
38+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
39+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
40+
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
41+
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
42+
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
43+
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
44+
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
45+
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
46+
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
47+
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
1148
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
1249
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
50+
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
51+
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
1352
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
53+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
54+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
55+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
1456
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
package cluster
1+
package clu2adv
22

33
import (
4-
"fmt"
5-
6-
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/file"
74
"github.com/spf13/afero"
85
"github.com/spf13/cobra"
96
)
@@ -29,31 +26,3 @@ func Builder() *cobra.Command {
2926
cmd.Flags().BoolVarP(&o.overwriteOutput, "overwriteOutput", "w", false, "overwrite output file if exists")
3027
return cmd
3128
}
32-
33-
type opts struct {
34-
fs afero.Fs
35-
file string
36-
output string
37-
overwriteOutput bool
38-
}
39-
40-
func (o *opts) PreRun() error {
41-
if err := file.MustExist(o.fs, o.file); err != nil {
42-
return err
43-
}
44-
if !o.overwriteOutput {
45-
return file.MustNotExist(o.fs, o.output)
46-
}
47-
return nil
48-
}
49-
50-
func (o *opts) Run() error {
51-
content, err := afero.ReadFile(o.fs, o.file)
52-
if err != nil {
53-
return fmt.Errorf("failed to read file %s: %w", o.file, err)
54-
}
55-
if err := afero.WriteFile(o.fs, o.output, content, 0o600); err != nil {
56-
return fmt.Errorf("failed to write file %s: %w", o.output, err)
57-
}
58-
return nil
59-
}

internal/cli/clu2adv/opts.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package clu2adv
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/file"
7+
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/hcl"
8+
"github.com/spf13/afero"
9+
)
10+
11+
type opts struct {
12+
fs afero.Fs
13+
file string
14+
output string
15+
overwriteOutput bool
16+
}
17+
18+
func (o *opts) PreRun() error {
19+
if err := file.MustExist(o.fs, o.file); err != nil {
20+
return err
21+
}
22+
if !o.overwriteOutput {
23+
return file.MustNotExist(o.fs, o.output)
24+
}
25+
return nil
26+
}
27+
28+
func (o *opts) Run() error {
29+
inConfig, err := afero.ReadFile(o.fs, o.file)
30+
if err != nil {
31+
return fmt.Errorf("failed to read file %s: %w", o.file, err)
32+
}
33+
outConfig, err := hcl.ClusterToAdvancedCluster(inConfig)
34+
if err != nil {
35+
return err
36+
}
37+
if err := afero.WriteFile(o.fs, o.output, outConfig, 0o600); err != nil {
38+
return fmt.Errorf("failed to write file %s: %w", o.output, err)
39+
}
40+
return nil
41+
}

internal/hcl/hcl.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package hcl
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/hcl/v2"
7+
"github.com/hashicorp/hcl/v2/hclwrite"
8+
)
9+
10+
// ClusterToAdvancedCluster transforms all cluster definition in a
11+
// Terraform config file into an advanced_cluster definition.
12+
// All other resources and data sources are left untouched.
13+
// TODO: at the moment it just changes the resource type.
14+
func ClusterToAdvancedCluster(config []byte) ([]byte, error) {
15+
parser, err := getParser(config)
16+
if err != nil {
17+
return nil, err
18+
}
19+
body := parser.Body()
20+
for _, resource := range body.Blocks() {
21+
isResource := resource.Type() == "resource"
22+
labels := resource.Labels()
23+
resourceName := labels[0]
24+
if !isResource || resourceName != "mongodbatlas_cluster" {
25+
continue
26+
}
27+
// TODO: Do the full transformation
28+
labels[0] = "mongodbatlas_advanced_cluster"
29+
resource.SetLabels(labels)
30+
}
31+
return parser.Bytes(), nil
32+
}
33+
34+
func getParser(config []byte) (*hclwrite.File, error) {
35+
parser, diags := hclwrite.ParseConfig(config, "", hcl.Pos{Line: 1, Column: 1})
36+
if diags.HasErrors() {
37+
return nil, fmt.Errorf("failed to parse Terraform config file: %s", diags.Error())
38+
}
39+
return parser, nil
40+
}

0 commit comments

Comments
 (0)