Skip to content

Commit

Permalink
Add an example manifest converter for conversion of singleton lists t…
Browse files Browse the repository at this point in the history
…o embedded object

Signed-off-by: Sergen Yalçın <[email protected]>
  • Loading branch information
sergenyalcin committed May 6, 2024
1 parent 9a463d5 commit 9bfe975
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 20 deletions.
133 changes: 133 additions & 0 deletions pkg/config/example_conversions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package config

import (
"bytes"
"fmt"
"github.com/crossplane/upjet/pkg/config/conversion"

Check failure on line 6 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
"github.com/pkg/errors"
"io"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

Check failure on line 9 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
k8sschema "k8s.io/apimachinery/pkg/runtime/schema"
kyaml "k8s.io/apimachinery/pkg/util/yaml"
"log"
"os"
"path/filepath"
"sigs.k8s.io/yaml"

Check failure on line 15 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
"strings"

Check failure on line 16 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
)

func ConvertSingletonListToEmbeddedObject(pc *Provider, startPath string) error {

Check failure on line 19 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

cyclomatic complexity 21 of func `ConvertSingletonListToEmbeddedObject` is high (> 10) (gocyclo)
resourceRegistry := prepareResourceRegistry(pc)
err := filepath.Walk(startPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

var convertedFileContent string
if !info.IsDir() && strings.HasSuffix(info.Name(), ".yaml") {
log.Printf("Converting: %s\n", path)
content, err := os.ReadFile(path)
if err != nil {
return err
}

examples, err := decodeExamples(string(content))
if err != nil {
return err
}

rootResource := resourceRegistry[fmt.Sprintf("%s/%s", examples[0].GroupVersionKind().Kind, examples[0].GroupVersionKind().Group)]
if rootResource == nil {
return nil
}

newPath := strings.Replace(path, examples[0].GroupVersionKind().Version, rootResource.Version, -1)

Check failure on line 44 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

wrapperFunc: use strings.ReplaceAll method in `strings.Replace(path, examples[0].GroupVersionKind().Version, rootResource.Version, -1)` (gocritic)
if path == newPath {
return nil
}
annotationValue := strings.ToLower(fmt.Sprintf("%s/%s/%s", rootResource.ShortGroup, rootResource.Version, rootResource.Kind))
for _, e := range examples {
if resource, ok := resourceRegistry[fmt.Sprintf("%s/%s", e.GroupVersionKind().Kind, e.GroupVersionKind().Group)]; ok {
conversionPaths := resource.CRDListConversionPaths()
if conversionPaths != nil && e.GroupVersionKind().Version != resource.Version {
for i, cp := range conversionPaths {
conversionPaths[i] = "spec.forProvider." + cp
}
converted, err := conversion.Convert(e.Object, conversionPaths, conversion.ToEmbeddedObject)
if err != nil {
return err
}
e.Object = converted
e.SetGroupVersionKind(k8sschema.GroupVersionKind{
Group: e.GroupVersionKind().Group,
Version: resource.Version,
Kind: e.GetKind(),
})
}
annotations := e.GetAnnotations()
annotations["meta.upbound.io/example-id"] = annotationValue
e.SetAnnotations(annotations)
}
}
convertedFileContent = "# SPDX-FileCopyrightText: 2024 The Crossplane Authors <https://crossplane.io>\n#\n# SPDX-License-Identifier: CC0-1.0\n\n"
for i, e := range examples {
var convertedData []byte
convertedData, err := yaml.Marshal(&e)
if err != nil {
return err
}
if i == len(examples)-1 {
convertedFileContent += string(convertedData)
} else {
convertedFileContent += string(convertedData) + "\n---\n\n"
}
}
dir := filepath.Dir(newPath)

// Create all necessary directories if they do not exist
err = os.MkdirAll(dir, os.ModePerm)
if err != nil {
return err
}
f, err := os.Create(newPath)
if err != nil {
return err
}
if _, err := f.Write([]byte(convertedFileContent)); err != nil {

Check failure on line 96 in pkg/config/example_conversions.go

View workflow job for this annotation

GitHub Actions / lint

preferStringWriter: f.WriteString(convertedFileContent) should be preferred to the f.Write([]byte(convertedFileContent)) (gocritic)
return err
}
log.Printf("Converted: %s\n", path)
}
return nil
})
if err != nil {
log.Printf("Error walking the path %q: %v\n", startPath, err)
}
return nil
}

func prepareResourceRegistry(pc *Provider) map[string]*Resource {
reg := map[string]*Resource{}
for _, r := range pc.Resources {
reg[fmt.Sprintf("%s/%s.%s", r.Kind, r.ShortGroup, pc.RootGroup)] = r
}
return reg
}

func decodeExamples(content string) ([]*unstructured.Unstructured, error) {
var manifests []*unstructured.Unstructured
decoder := kyaml.NewYAMLOrJSONDecoder(bytes.NewBufferString(content), 1024)
for {
u := &unstructured.Unstructured{}
if err := decoder.Decode(&u); err != nil {
if errors.Is(err, io.EOF) {
break
}
return nil, errors.Wrap(err, "cannot decode manifest")
}
if u != nil {
manifests = append(manifests, u)
}
}
return manifests, nil
}
40 changes: 20 additions & 20 deletions pkg/config/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
package config

import (
"context"
"fmt"
"strings"
"time"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
xpresource "github.com/crossplane/crossplane-runtime/pkg/resource"
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/crossplane/upjet/pkg/config/conversion"
"github.com/crossplane/upjet/pkg/registry"
"context"

Check failure on line 8 in pkg/config/resource.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
"fmt"
"strings"
"time"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"

Check failure on line 13 in pkg/config/resource.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
xpresource "github.com/crossplane/crossplane-runtime/pkg/resource"
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/crossplane/upjet/pkg/config/conversion"

Check failure on line 26 in pkg/config/resource.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/crossplane/upjet) -s blank -s dot --custom-order (gci)
"github.com/crossplane/upjet/pkg/registry"
)

// A ListType is a type of list.
Expand Down

0 comments on commit 9bfe975

Please sign in to comment.