Skip to content

Commit

Permalink
Only apply CRD API conversions for converting between singleton list …
Browse files Browse the repository at this point in the history
…and embedded objects APIs

Signed-off-by: Fatih Türken <[email protected]>
  • Loading branch information
turkenf committed Jul 23, 2024
1 parent a505c3e commit af52e9d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 9 deletions.
6 changes: 6 additions & 0 deletions config/old-singleton-list-apis.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
azuread_application
azuread_conditional_access_policy
azuread_group
azuread_invitation
azuread_named_location
azuread_service_principal
62 changes: 53 additions & 9 deletions config/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ package config

import (
"context"
"strings"

// Note(turkenh): we are importing this to embed provider schema document
_ "embed"

"github.com/crossplane/upjet/pkg/config"
ujconfig "github.com/crossplane/upjet/pkg/config"
"github.com/crossplane/upjet/pkg/config/conversion"
"github.com/crossplane/upjet/pkg/registry/reference"
Expand Down Expand Up @@ -44,6 +47,28 @@ var providerSchema string
//go:embed provider-metadata.yaml
var providerMetadata string

// oldSingletonListAPIs is a newline-delimited list of Terraform resource
// names with converted singleton list APIs with at least CRD API version
// containing the old singleton list API. This is to prevent the API
// conversion for the newly added resources whose CRD APIs will already
// use embedded objects instead of the singleton lists and thus, will
// not possess a CRD API version with the singleton list. Thus, for
// the newly added resources (resources added after the singleton lists
// have been converted), we do not need the CRD API conversion
// functions that convert between singleton lists and embedded objects,
// but we need only the Terraform conversion functions.
// This list is immutable and represents the set of resources with the
// already generated CRD API versions with now converted singleton lists.
// Because new resources should never have singleton lists in their
// generated APIs, there should be no need to add them to this list.
// However, bugs might result in exceptions in the future.
// Please see:
// https://github.com/crossplane-contrib/provider-upjet-azuread/pull/123
// for more context on singleton list to embedded object conversions.
//
//go:embed old-singleton-list-apis.txt
var oldSingletonListAPIs string

// workaround for the TF Google v2.41.0-based no-fork release: We would like to
// keep the types in the generated CRDs intact
// (prevent number->int type replacements).
Expand Down Expand Up @@ -136,22 +161,41 @@ func resourceList(t map[string]ujconfig.ExternalName) []string {
}

func bumpVersionsWithEmbeddedLists(pc *ujconfig.Provider) {
l := strings.Split(strings.TrimSpace(oldSingletonListAPIs), "\n")
oldSLAPIs := make(map[string]struct{}, len(l))
for _, n := range l {
oldSLAPIs[n] = struct{}{}
}

for name, r := range pc.Resources {
r := r
// nothing to do if no singleton list has been converted to
// an embedded object
if len(r.CRDListConversionPaths()) == 0 {
continue
}
r.Version = "v1beta2"
// we would like to set the storage version to v1beta1 to facilitate
// downgrades.
r.SetCRDStorageVersion("v1beta1")
r.ControllerReconcileVersion = "v1beta1"
r.Conversions = []conversion.Conversion{
conversion.NewIdentityConversionExpandPaths(conversion.AllVersions, conversion.AllVersions, []string{"spec.forProvider", "spec.initProvider", "status.atProvider"}, r.CRDListConversionPaths()...),
conversion.NewSingletonListConversion("v1beta1", "v1beta2", conversion.DefaultPathPrefixes(), r.CRDListConversionPaths(), conversion.ToEmbeddedObject),
conversion.NewSingletonListConversion("v1beta2", "v1beta1", conversion.DefaultPathPrefixes(), r.CRDListConversionPaths(), conversion.ToSingletonList)}
if _, ok := oldSLAPIs[name]; ok {
r.Version = "v1beta2"
r.PreviousVersions = []string{"v1beta1"}
// we would like to set the storage version to v1beta1 to facilitate
// downgrades.
r.SetCRDStorageVersion("v1beta1")
// because the controller reconciles on the API version with the singleton list API,
// no need for a Terraform conversion.
r.ControllerReconcileVersion = "v1beta1"
r.Conversions = []conversion.Conversion{
conversion.NewIdentityConversionExpandPaths(conversion.AllVersions, conversion.AllVersions, conversion.DefaultPathPrefixes(), r.CRDListConversionPaths()...),
conversion.NewSingletonListConversion("v1beta1", "v1beta2", conversion.DefaultPathPrefixes(), r.CRDListConversionPaths(), conversion.ToEmbeddedObject),
conversion.NewSingletonListConversion("v1beta2", "v1beta1", conversion.DefaultPathPrefixes(), r.CRDListConversionPaths(), conversion.ToSingletonList)}
} else {
// the controller will be reconciling on the CRD API version
// with the converted API (with embedded objects in place of
// singleton lists), so we need the appropriate Terraform
// converter in this case.
r.TerraformConversions = []config.TerraformConversion{
config.NewTFSingletonConversion(),
}
}
pc.Resources[name] = r
}
}

0 comments on commit af52e9d

Please sign in to comment.