Skip to content

Commit 7b5a641

Browse files
committed
chore: support environment resource
1 parent d00f6b4 commit 7b5a641

File tree

5 files changed

+212
-7
lines changed

5 files changed

+212
-7
lines changed

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
TEST?=$$(go list ./... | grep -v 'vendor')
2+
HOSTNAME=registry.terraform.io
3+
NAMESPACE=bytebase
4+
NAME=bytebase
5+
BINARY=terraform-provider-${NAMESPACE}
6+
VERSION=0.0.1
7+
OS_ARCH=darwin_amd64
8+
9+
default: install
10+
11+
build:
12+
go build -o ${BINARY}
13+
14+
release:
15+
goreleaser release --rm-dist --snapshot --skip-publish --skip-sign
16+
17+
install: build
18+
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
19+
mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
20+
21+
test:
22+
go test -i $(TEST) || exit 1
23+
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
24+
25+
testacc:
26+
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m

api/environment.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ type Environment struct {
1313
type EnvironmentCreate struct {
1414
// Domain specific fields
1515
Name string `json:"name"`
16-
Order *int `json:"order"`
16+
Order *int `json:"order,omitempty"`
1717
}
1818

1919
// EnvironmentPatch is the API message for patching an environment.
2020
type EnvironmentPatch struct {
2121
// Domain specific fields
22-
Name string `json:"name,omitempty"`
23-
Order int `json:"order"`
22+
Name *string `json:"name,omitempty"`
23+
Order *int `json:"order,omitempty"`
2424
}

examples/main.tf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
terraform {
2+
required_providers {
3+
bytebase = {
4+
version = "0.0.1"
5+
source = "registry.terraform.io/bytebase/bytebase"
6+
}
7+
}
8+
}
9+
10+
provider "bytebase" {
11+
12+
password = "ed"
13+
bytebase_url = "http://localhost:8080/v1"
14+
}
15+
16+
# Create a new environment named "dev"
17+
resource "bytebase_environment" "dev" {
18+
name = "dev"
19+
}
20+
21+
# Print the new environment
22+
output "staging_environment" {
23+
value = bytebase_environment.dev
24+
}

provider/provider.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ func NewProvider() *schema.Provider {
3232
},
3333
},
3434
ConfigureContextFunc: providerConfigure,
35-
// TODO: implement the data source.
36-
DataSourcesMap: map[string]*schema.Resource{},
37-
// TODO: implement the resource.
38-
ResourcesMap: map[string]*schema.Resource{},
35+
DataSourcesMap: map[string]*schema.Resource{},
36+
ResourcesMap: map[string]*schema.Resource{
37+
"bytebase_environment": resourceEnvironment(),
38+
},
3939
}
4040
}
4141

provider/resource_environment.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
"github.com/bytebase/terraform-provider-bytebase/api"
8+
"github.com/bytebase/terraform-provider-bytebase/client"
9+
10+
"github.com/hashicorp/terraform-plugin-log/tflog"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
13+
)
14+
15+
func resourceEnvironment() *schema.Resource {
16+
return &schema.Resource{
17+
CreateContext: resourceEnvironmentCreate,
18+
ReadContext: resourceEnvironmentRead,
19+
UpdateContext: resourceEnvironmentUpdate,
20+
DeleteContext: resourceEnvironmentDelete,
21+
Importer: &schema.ResourceImporter{
22+
StateContext: schema.ImportStatePassthroughContext,
23+
},
24+
Schema: map[string]*schema.Schema{
25+
"name": {
26+
Type: schema.TypeString,
27+
Required: true,
28+
},
29+
"order": {
30+
Type: schema.TypeInt,
31+
Optional: true,
32+
Computed: true,
33+
Default: nil,
34+
},
35+
},
36+
}
37+
}
38+
39+
func resourceEnvironmentCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
40+
c := m.(*client.Client)
41+
42+
// Warning or errors can be collected in a slice type
43+
var diags diag.Diagnostics
44+
45+
name, ok := d.Get("name").(string)
46+
if !ok {
47+
diags = append(diags, diag.Diagnostic{
48+
Severity: diag.Error,
49+
Summary: "Unable to get the environment name",
50+
Detail: "The environment name is required for creation",
51+
})
52+
return diags
53+
}
54+
55+
create := &api.EnvironmentCreate{
56+
Name: name,
57+
}
58+
59+
tflog.Info(ctx, "order", map[string]interface{}{"order": d.Get("order")})
60+
61+
order, ok := d.GetOk("order")
62+
if ok {
63+
val := order.(int)
64+
create.Order = &val
65+
}
66+
67+
tflog.Debug(ctx, "try to create environment with name", map[string]interface{}{"name": name})
68+
69+
env, err := c.CreateEnvironment(create)
70+
if err != nil {
71+
return diag.FromErr(err)
72+
}
73+
74+
d.SetId(strconv.Itoa(env.ID))
75+
76+
return resourceEnvironmentRead(ctx, d, m)
77+
}
78+
79+
func resourceEnvironmentRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
80+
c := m.(*client.Client)
81+
82+
envID, err := strconv.Atoi(d.Id())
83+
if err != nil {
84+
return diag.FromErr(err)
85+
}
86+
87+
env, err := c.GetEnvironment(envID)
88+
if err != nil {
89+
return diag.FromErr(err)
90+
}
91+
92+
return setEnvironment(d, env)
93+
}
94+
95+
func resourceEnvironmentUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
96+
c := m.(*client.Client)
97+
98+
envID, err := strconv.Atoi(d.Id())
99+
if err != nil {
100+
return diag.FromErr(err)
101+
}
102+
103+
if d.HasChange("name") || d.HasChange("order") {
104+
patch := &api.EnvironmentPatch{}
105+
106+
name, ok := d.GetOk("name")
107+
if ok {
108+
val := name.(string)
109+
patch.Name = &val
110+
}
111+
112+
order, ok := d.GetOk("order")
113+
if ok {
114+
val := order.(int)
115+
patch.Order = &val
116+
}
117+
118+
if _, err := c.UpdateEnvironment(envID, patch); err != nil {
119+
return diag.FromErr(err)
120+
}
121+
}
122+
123+
return resourceEnvironmentRead(ctx, d, m)
124+
}
125+
126+
func resourceEnvironmentDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
127+
c := m.(*client.Client)
128+
129+
// Warning or errors can be collected in a slice type
130+
var diags diag.Diagnostics
131+
132+
envID, err := strconv.Atoi(d.Id())
133+
if err != nil {
134+
return diag.FromErr(err)
135+
}
136+
137+
if err := c.DeleteEnvironment(envID); err != nil {
138+
return diag.FromErr(err)
139+
}
140+
141+
d.SetId("")
142+
143+
return diags
144+
}
145+
146+
func setEnvironment(d *schema.ResourceData, env *api.Environment) diag.Diagnostics {
147+
if err := d.Set("name", env.Name); err != nil {
148+
return diag.Errorf("cannot set name for environment: %s", err.Error())
149+
}
150+
if err := d.Set("order", env.Order); err != nil {
151+
return diag.Errorf("cannot set order for environment: %s", err.Error())
152+
}
153+
154+
return nil
155+
}

0 commit comments

Comments
 (0)