Skip to content

Commit e833e5d

Browse files
committed
Adds CRD fields: property and required
1 parent 0be2e66 commit e833e5d

File tree

10 files changed

+196
-16
lines changed

10 files changed

+196
-16
lines changed

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM golang:1.19-alpine3.17 as build
2+
3+
RUN apk add make gcc musl-dev
4+
5+
WORKDIR /go/src/github.com/previousnext/terraform-provider-k8s
6+
COPY . /go/src/github.com/previousnext/terraform-provider-k8s
7+
8+
RUN go build -ldflags "-linkmode external -extldflags -static" -o terraform-provider-k8s
9+
10+
FROM hashicorp/terraform:0.14.8 as run
11+
12+
RUN apk add bash
13+
14+
RUN mkdir -p /root/.terraform.d/plugins
15+
16+
COPY --from=build /go/src/github.com/previousnext/terraform-provider-k8s/terraform-provider-k8s /root/.terraform.d/plugins/registry.terraform.io/previousnext/k8s/99.0.0/linux_amd64/terraform-provider-k8s_v99.0.0
17+
RUN chmod +x /root/.terraform.d/plugins/registry.terraform.io/*/*/*/linux_amd64/terraform-provider-*

internal/resources/apiextensions/v1beta1/crd/generate.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ package crd
22

33
import (
44
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5-
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
6-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7-
85
"github.com/previousnext/terraform-provider-k8s/internal/interfaceutils"
96
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/names"
7+
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/property"
8+
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/required"
9+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
)
1112

1213
// Generate the ServiceAccount.
1314
func Generate(d *schema.ResourceData) (apiextensionsv1.CustomResourceDefinition, error) {
1415
var (
15-
name = d.Get(FieldName).(string)
16-
rawLabels = d.Get(FieldLabels).(map[string]interface{})
17-
group = d.Get(FieldGroup).(string)
18-
version = d.Get(FieldVersion).(string)
19-
scope = d.Get(FieldScope).(string)
20-
rawNames = d.Get(FieldNames).([]interface{})
16+
name = d.Get(FieldName).(string)
17+
rawLabels = d.Get(FieldLabels).(map[string]interface{})
18+
group = d.Get(FieldGroup).(string)
19+
version = d.Get(FieldVersion).(string)
20+
scope = d.Get(FieldScope).(string)
21+
rawNames = d.Get(FieldNames).([]interface{})
22+
rawProperties = d.Get(FieldProperty).(*schema.Set).List()
23+
rawRequired = d.Get(FieldRequired).([]interface{})
2124
)
2225

2326
crd := apiextensionsv1.CustomResourceDefinition{
@@ -32,8 +35,13 @@ func Generate(d *schema.ResourceData) (apiextensionsv1.CustomResourceDefinition,
3235
Name: version,
3336
Served: true,
3437
Storage: true,
35-
// @todo, Determine better approach for schema.
36-
Schema: &apiextensionsv1.CustomResourceValidation{},
38+
Schema: &apiextensionsv1.CustomResourceValidation{
39+
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
40+
Properties: property.Expand(rawProperties),
41+
Required: required.Expand(rawRequired),
42+
Type: "object",
43+
},
44+
},
3745
Subresources: &apiextensionsv1.CustomResourceSubresources{
3846
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
3947
},
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package property
2+
3+
import (
4+
"k8s.io/utils/pointer"
5+
6+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
7+
)
8+
9+
// Expand will return a structured object.
10+
func Expand(in []interface{}) map[string]apiextensionsv1.JSONSchemaProps {
11+
if len(in) == 0 {
12+
return nil
13+
}
14+
15+
vars := make(map[string]apiextensionsv1.JSONSchemaProps, len(in))
16+
17+
for _, v := range in {
18+
value := v.(map[string]interface{})
19+
20+
prop := apiextensionsv1.JSONSchemaProps{}
21+
22+
if val, ok := value[FieldType]; ok && val != "" {
23+
prop.Type = val.(string)
24+
}
25+
26+
if val, ok := value[FieldPreserveUnknownFields]; ok && val == true {
27+
prop.XPreserveUnknownFields = pointer.Bool(true)
28+
}
29+
30+
if val, ok := value[FieldName]; ok && val != "" {
31+
vars[val.(string)] = prop
32+
}
33+
}
34+
35+
return vars
36+
}
37+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package property
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
)
6+
7+
const (
8+
// FieldName is a field identifier.
9+
FieldName = "name"
10+
// FieldType is a field identifier.
11+
FieldType = "type"
12+
// FieldPreserveUnknownFields is a field identifier.
13+
FieldPreserveUnknownFields = "preserve_unknown_fields"
14+
)
15+
16+
// Fields returns the fields for this package.
17+
func Fields() *schema.Schema {
18+
return &schema.Schema{
19+
Description: "Environment variables which can be set for a container",
20+
Type: schema.TypeSet,
21+
Optional: true,
22+
Elem: &schema.Resource{
23+
Schema: map[string]*schema.Schema{
24+
FieldName: {
25+
Type: schema.TypeString,
26+
Required: true,
27+
},
28+
FieldType: {
29+
Type: schema.TypeString,
30+
Required: true,
31+
},
32+
FieldPreserveUnknownFields: {
33+
Type: schema.TypeBool,
34+
Optional: true,
35+
},
36+
},
37+
},
38+
}
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package property
2+
3+
import (
4+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
5+
)
6+
7+
// Flatten structured object into unstructured.
8+
func Flatten(in map[string]apiextensionsv1.JSONSchemaProps) []interface{} {
9+
flattened := make([]interface{}, 0)
10+
11+
for name, value := range in {
12+
row := map[string]interface{}{}
13+
14+
row[FieldName] = name
15+
16+
if value.Type != "" {
17+
row[FieldType] = value.Type
18+
}
19+
20+
if value.XPreserveUnknownFields != nil {
21+
row[FieldPreserveUnknownFields] = *value.XPreserveUnknownFields
22+
}
23+
24+
flattened = append(flattened, row)
25+
}
26+
27+
return flattened
28+
}
29+

internal/resources/apiextensions/v1beta1/crd/read.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010

1111
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/names"
12+
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/property"
1213
"github.com/previousnext/terraform-provider-k8s/internal/terraform/config"
1314
"github.com/previousnext/terraform-provider-k8s/internal/terraform/id"
1415
)
@@ -47,5 +48,10 @@ func Read(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagn
4748
d.Set(FieldScope, crd.Spec.Scope)
4849
d.Set(FieldNames, names.Flatten(crd.Spec.Names))
4950

51+
if len(crd.Spec.Versions) > 0 {
52+
d.Set(FieldProperty, property.Flatten(crd.Spec.Versions[0].Schema.OpenAPIV3Schema.Properties))
53+
d.Set(FieldRequired, crd.Spec.Versions[0].Schema.OpenAPIV3Schema.Required)
54+
}
55+
5056
return diags
5157
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package required
2+
3+
// Expand will return a structured object.
4+
func Expand(s []interface{}) []string {
5+
result := make([]string, len(s))
6+
7+
for k, v := range s {
8+
result[k] = v.(string)
9+
}
10+
11+
return result
12+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package required
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
)
6+
7+
// Fields returns the fields for this package.
8+
func Fields() *schema.Schema {
9+
return &schema.Schema{
10+
Type: schema.TypeList,
11+
Optional: true,
12+
Elem: &schema.Schema{
13+
Type: schema.TypeString,
14+
},
15+
}
16+
}

internal/resources/apiextensions/v1beta1/crd/resource.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package crd
22

33
import (
44
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/property"
6+
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/required"
57

68
"github.com/previousnext/terraform-provider-k8s/internal/resources/apiextensions/v1beta1/crd/names"
79
)
@@ -21,6 +23,10 @@ const (
2123
FieldScope = "scope"
2224
// FieldNames is a field identifier.
2325
FieldNames = "names"
26+
// FieldProperty is a field identifier.
27+
FieldProperty = "property"
28+
// FieldRequired is a field identifier.
29+
FieldRequired = "required"
2430
)
2531

2632
// Resource returns this packages Resource and Fields.
@@ -32,11 +38,11 @@ func Resource() *schema.Resource {
3238
DeleteContext: Delete,
3339

3440
Schema: map[string]*schema.Schema{
35-
FieldName: &schema.Schema{
41+
FieldName: {
3642
Type: schema.TypeString,
3743
Required: true,
3844
},
39-
FieldLabels: &schema.Schema{
45+
FieldLabels: {
4046
Type: schema.TypeMap,
4147
Optional: true,
4248
},
@@ -52,7 +58,9 @@ func Resource() *schema.Resource {
5258
Type: schema.TypeString,
5359
Required: true,
5460
},
55-
FieldNames: names.Fields(),
61+
FieldNames: names.Fields(),
62+
FieldProperty: property.Fields(),
63+
FieldRequired: required.Fields(),
5664
},
5765
}
5866
}

internal/resources/apiextensions/v1beta1/crd/update.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,23 @@ func Update(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Dia
1717

1818
conn := m.(*config.Client)
1919

20-
crd, err := Generate(d)
20+
c, err := Generate(d)
2121
if err != nil {
2222
return diag.FromErr(err)
2323
}
2424

25-
_, err = conn.APIExtensions().ApiextensionsV1().CustomResourceDefinitions().Update(ctx, &crd, metav1.UpdateOptions{})
25+
crd, err := conn.APIExtensions().ApiextensionsV1().CustomResourceDefinitions().Get(ctx, c.ObjectMeta.Name, metav1.GetOptions{})
26+
if err != nil {
27+
return diag.FromErr(err)
28+
}
29+
30+
crd.Spec = c.Spec
31+
32+
_, err = conn.APIExtensions().ApiextensionsV1().CustomResourceDefinitions().Update(ctx, crd, metav1.UpdateOptions{})
2633
if err != nil {
2734
return diag.FromErr(err)
2835
}
2936

3037
return diags
3138
}
39+

0 commit comments

Comments
 (0)