Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crd: remove field transformation struct and its usages #46

Merged
merged 4 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions pkg/config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ func DefaultResource(name string, terraformSchema *schema.Resource, terraformReg
func MoveToStatus(sch *schema.Resource, fieldpaths ...string) {
for _, f := range fieldpaths {
s := GetSchema(sch, f)
if s == nil {
return
}
s.Optional = false
s.Computed = true

Expand All @@ -104,9 +107,10 @@ func MoveToStatus(sch *schema.Resource, fieldpaths ...string) {
// schemas.
func MarkAsRequired(sch *schema.Resource, fieldpaths ...string) {
for _, fieldpath := range fieldpaths {
s := GetSchema(sch, fieldpath)
s.Computed = false
s.Optional = false
if s := GetSchema(sch, fieldpath); s != nil {
s.Computed = false
s.Optional = false
}
}
}

Expand Down
42 changes: 42 additions & 0 deletions pkg/config/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ func TestMoveToStatus(t *testing.T) {
args
want
}{
"DoesNotExist": {
args: args{
fields: []string{"topD"},
sch: &schema.Resource{
Schema: map[string]*schema.Schema{
"topA": {Type: schema.TypeString},
"topB": {Type: schema.TypeInt},
"topC": {Type: schema.TypeString, Optional: true},
},
},
},
want: want{
sch: &schema.Resource{
Schema: map[string]*schema.Schema{
"topA": {Type: schema.TypeString},
"topB": {Type: schema.TypeInt},
"topC": {Type: schema.TypeString, Optional: true},
},
},
},
},
"TopLevelBasicFields": {
args: args{
fields: []string{"topA", "topB"},
Expand Down Expand Up @@ -263,6 +284,27 @@ func TestMarkAsRequired(t *testing.T) {
args
want
}{
"DoesNotExist": {
args: args{
fields: []string{"topD"},
sch: &schema.Resource{
Schema: map[string]*schema.Schema{
"topA": {Type: schema.TypeString},
"topB": {Type: schema.TypeInt, Computed: true},
"topC": {Type: schema.TypeString, Optional: true},
},
},
},
want: want{
sch: &schema.Resource{
Schema: map[string]*schema.Schema{
"topA": {Type: schema.TypeString},
"topB": {Type: schema.TypeInt, Computed: true},
"topC": {Type: schema.TypeString, Optional: true},
},
},
},
},
"TopLevelBasicFields": {
args: args{
fields: []string{"topB", "topC"},
Expand Down
83 changes: 44 additions & 39 deletions pkg/examples/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import (
"strings"

"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/pkg/errors"
"sigs.k8s.io/yaml"

"github.com/upbound/upjet/pkg/config"
"github.com/upbound/upjet/pkg/registry/reference"
"github.com/upbound/upjet/pkg/resource/json"
tjtypes "github.com/upbound/upjet/pkg/types"
"github.com/upbound/upjet/pkg/types/name"
)

var (
Expand Down Expand Up @@ -92,7 +94,7 @@ func (eg *Generator) StoreExamples() error { // nolint:gocyclo
if err := json.TFParser.Unmarshal([]byte(re.Dependencies[dn]), &exampleParams); err != nil {
return errors.Wrapf(err, "cannot unmarshal example manifest for resource: %s", dr.Config.Name)
}
pmd := paveCRManifest(exampleParams, dr.FieldTransformations, dr.Config,
pmd := paveCRManifest(exampleParams, dr.Config,
reference.NewRefPartsFromResourceName(dn).ExampleName, dr.Group, dr.Version)
if err := eg.writeManifest(&buff, pmd, context); err != nil {
return errors.Wrapf(err, "cannot store example manifest for %s dependency: %s", rn, dn)
Expand All @@ -107,8 +109,10 @@ func (eg *Generator) StoreExamples() error { // nolint:gocyclo
return nil
}

func paveCRManifest(exampleParams map[string]any, fieldTransformations map[string]tjtypes.Transformation, r *config.Resource, eName, group, version string) *reference.PavedWithManifest {
transformFields(r, exampleParams, r.ExternalName.OmittedFields, fieldTransformations, "")
func paveCRManifest(exampleParams map[string]any, r *config.Resource, eName, group, version string) *reference.PavedWithManifest {
delete(exampleParams, "depends_on")
delete(exampleParams, "lifecycle")
transformFields(r, exampleParams, r.ExternalName.OmittedFields, "")
example := map[string]any{
"apiVersion": fmt.Sprintf("%s/%s", group, version),
"kind": r.Kind,
Expand All @@ -122,12 +126,11 @@ func paveCRManifest(exampleParams map[string]any, fieldTransformations map[strin
},
}
return &reference.PavedWithManifest{
Paved: fieldpath.Pave(example),
ParamsPrefix: []string{"spec", "forProvider"},
FieldTransformations: fieldTransformations,
Config: r,
Group: group,
Version: version,
Paved: fieldpath.Pave(example),
ParamsPrefix: []string{"spec", "forProvider"},
Config: r,
Group: group,
Version: version,
}
}

Expand All @@ -148,7 +151,6 @@ func (eg *Generator) writeManifest(writer io.Writer, pm *reference.PavedWithMani
return errors.Wrapf(err, `cannot set "metadata.name" for resource %q:%s`, pm.Config.Name, pm.ExampleName)
}
u := pm.Paved.UnstructuredContent()
delete(u["spec"].(map[string]any)["forProvider"].(map[string]any), "depends_on")
buff, err := yaml.Marshal(u)
if err != nil {
return errors.Wrap(err, "cannot marshal example resource manifest")
Expand All @@ -161,12 +163,12 @@ func (eg *Generator) writeManifest(writer io.Writer, pm *reference.PavedWithMani
}

// Generate generates an example manifest for the specified Terraform resource.
func (eg *Generator) Generate(group, version string, r *config.Resource, fieldTransformations map[string]tjtypes.Transformation) error {
func (eg *Generator) Generate(group, version string, r *config.Resource) error {
rm := eg.configResources[r.Name].MetaResource
if rm == nil || len(rm.Examples) == 0 {
return nil
}
pm := paveCRManifest(rm.Examples[0].Paved.UnstructuredContent(), fieldTransformations, r, rm.Examples[0].Name, group, version)
pm := paveCRManifest(rm.Examples[0].Paved.UnstructuredContent(), r, rm.Examples[0].Name, group, version)
manifestDir := filepath.Join(eg.rootDir, "examples-generated", strings.ToLower(strings.Split(group, ".")[0]))
pm.ManifestPath = filepath.Join(manifestDir, fmt.Sprintf("%s.yaml", strings.ToLower(r.Kind)))
eg.resources[fmt.Sprintf("%s.%s", r.Name, reference.Wildcard)] = pm
Expand All @@ -188,7 +190,7 @@ func isStatus(r *config.Resource, attr string) bool {
return tjtypes.IsObservation(s)
}

func transformFields(r *config.Resource, params map[string]any, omittedFields []string, t map[string]tjtypes.Transformation, namePrefix string) { // nolint:gocyclo
func transformFields(r *config.Resource, params map[string]any, omittedFields []string, namePrefix string) { // nolint:gocyclo
for n := range params {
hName := getHierarchicalName(namePrefix, n)
if isStatus(r, hName) {
Expand All @@ -206,46 +208,49 @@ func transformFields(r *config.Resource, params map[string]any, omittedFields []
for n, v := range params {
switch pT := v.(type) {
case map[string]any:
transformFields(r, pT, omittedFields, t, getHierarchicalName(namePrefix, n))
transformFields(r, pT, omittedFields, getHierarchicalName(namePrefix, n))

case []any:
for _, e := range pT {
eM, ok := e.(map[string]any)
if !ok {
continue
}
transformFields(r, eM, omittedFields, t, getHierarchicalName(namePrefix, n))
transformFields(r, eM, omittedFields, getHierarchicalName(namePrefix, n))
}
}
}

for n, v := range params {
hName := getHierarchicalName(namePrefix, n)
for hn, transform := range t {
if hn != hName {
continue
}
delete(params, n)
switch {
case !transform.IsRef:
params[transform.TransformedName] = v
case transform.IsSensitive:
secretName, secretKey := getSecretRef(v)
params[transform.TransformedName] = getRefField(v,
map[string]any{
"name": secretName,
"namespace": defaultNamespace,
"key": secretKey,
})
fieldPath := getHierarchicalName(namePrefix, n)
sch := config.GetSchema(r.TerraformResource, fieldPath)
if sch == nil {
continue
}
// At this point, we confirmed that the field is part of the schema,
// so we'll need to perform at least name change on it.
delete(params, n)
fn := name.NewFromSnake(n)
switch {
case sch.Sensitive:
secretName, secretKey := getSecretRef(v)
params[fn.LowerCamelComputed+"SecretRef"] = getRefField(v, map[string]any{
"name": secretName,
"namespace": defaultNamespace,
"key": secretKey,
})
case r.References[fieldPath] != config.Reference{}:
switch v.(type) {
case []any:
l := sch.Type == schema.TypeList || sch.Type == schema.TypeSet
ref := name.ReferenceFieldName(fn, l, r.References[fieldPath].RefFieldName)
params[ref.LowerCamelComputed] = getNameRefField(v)
default:
switch v.(type) {
case []any:
params[transform.TransformedName] = getNameRefField(v)
default:
params[transform.SelectorName] = getSelectorField(v)
}
sel := name.SelectorFieldName(fn, r.References[fieldPath].SelectorFieldName)
params[sel.LowerCamelComputed] = getSelectorField(v)
}
break
default:
params[fn.LowerCamelComputed] = v
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pipeline/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func Run(pc *config.Provider, rootDir string) { // nolint:gocyclo
panic(errors.Wrapf(err, "cannot generate controller for resource %s", name))
}
controllerPkgList = append(controllerPkgList, ctrlPkgPath)
if err := exampleGen.Generate(group, version, resources[name], crdGen.Generated.FieldTransformations); err != nil {
if err := exampleGen.Generate(group, version, resources[name]); err != nil {
panic(errors.Wrapf(err, "cannot generate example manifest for resource %s", name))
}
count++
Expand Down
18 changes: 8 additions & 10 deletions pkg/registry/reference/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/upbound/upjet/pkg/config"
"github.com/upbound/upjet/pkg/registry"
"github.com/upbound/upjet/pkg/resource/json"
tjtypes "github.com/upbound/upjet/pkg/types"
)

const (
Expand Down Expand Up @@ -92,15 +91,14 @@ func NewRefPartsFromResourceName(rn string) Parts {

// PavedWithManifest represents an example manifest with a fieldpath.Paved
type PavedWithManifest struct {
Paved *fieldpath.Paved
ManifestPath string
ParamsPrefix []string
refsResolved bool
FieldTransformations map[string]tjtypes.Transformation
Config *config.Resource
Group string
Version string
ExampleName string
Paved *fieldpath.Paved
ManifestPath string
ParamsPrefix []string
refsResolved bool
Config *config.Resource
Group string
Version string
ExampleName string
}

// ResolutionContext represents a reference resolution context where
Expand Down
Loading