Skip to content

Commit

Permalink
Merge pull request #163 from lsviben/mpm
Browse files Browse the repository at this point in the history
Migrate to XP ManagementPolicies
  • Loading branch information
turkenh committed Jan 11, 2024
2 parents c8a78af + e3215fe commit cc10a8c
Show file tree
Hide file tree
Showing 34 changed files with 2,126 additions and 270 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
/bin
/vendor
/.vendor-new
.vscode
.vscode
/.idea

22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,25 @@ manifests:
@$(INFO) Deprecated. Run make generate instead.

.PHONY: cobertura submodules fallthrough test-integration run manifests

generate.run: go.generate kustomize.gen

generate.done: kustomize.clean

# This hack is needed because we want to inject the conversion webhook
# configuration into the Object CRD. This is not possible with the CRD
# generation through controller-gen, and actually kubebuilder does
# something similar, so we are following suit. Can be removed once we
# drop support for v1alpha1.
kustomize.gen: $(KUBECTL)
@$(INFO) Generating CRDs with kustomize
@$(KUBECTL) kustomize cluster/kustomize/ > cluster/kustomize/kubernetes.crossplane.io_objects.yaml
@mv cluster/kustomize/kubernetes.crossplane.io_objects.yaml cluster/kustomize/crds/kubernetes.crossplane.io_objects.yaml
@mv cluster/kustomize/crds package/crds
@$(OK) Generated CRDs with kustomize

kustomize.clean:
@$(INFO) Cleaning up kustomize generated CRDs
@rm -rf cluster/kustomize/crds
@rm -f cluster/kustomize/kubernetes.crossplane.io_objects.yaml
@$(OK) Cleaned up kustomize generated CRDs
2 changes: 1 addition & 1 deletion apis/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ limitations under the License.
//go:generate rm -rf ../package/crds

// Generate deepcopy methodsets and CRD manifests
//go:generate go run -tags generate sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile=../hack/boilerplate.go.txt paths=./... crd:crdVersions=v1 output:artifacts:config=../package/crds
//go:generate go run -tags generate sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile=../hack/boilerplate.go.txt paths=./... crd:crdVersions=v1 output:artifacts:config=../cluster/kustomize/crds

// Generate crossplane-runtime methodsets (resource.Claim, etc)
//go:generate go run -tags generate github.com/crossplane/crossplane-tools/cmd/angryjet generate-methodsets --header-file=../hack/boilerplate.go.txt ./...
Expand Down
2 changes: 2 additions & 0 deletions apis/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"

objectv1alpha1 "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1"
objectv1alhpa2 "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha2"
templatev1alpha1 "github.com/crossplane-contrib/provider-kubernetes/apis/v1alpha1"
)

Expand All @@ -29,6 +30,7 @@ func init() {
AddToSchemes = append(AddToSchemes,
templatev1alpha1.SchemeBuilder.AddToScheme,
objectv1alpha1.SchemeBuilder.AddToScheme,
objectv1alhpa2.SchemeBuilder.AddToScheme,
)
}

Expand Down
195 changes: 195 additions & 0 deletions apis/object/v1alpha1/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
Copyright 2023 The Crossplane Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"errors"

"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/conversion"

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

"github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha2"
)

// ConvertTo converts this Object to the Hub version (v1alpha2).
func (src *Object) ConvertTo(dstRaw conversion.Hub) error { // nolint:golint // We want to use different names for receiver parameter to be more clear.
dst := dstRaw.(*v1alpha2.Object)

// copy identical fields
dst.ObjectMeta = src.ObjectMeta

dst.Status = v1alpha2.ObjectStatus{
ResourceStatus: src.Status.ResourceStatus,
AtProvider: v1alpha2.ObjectObservation{
Manifest: src.Status.AtProvider.Manifest,
},
}

connectionDetails := []v1alpha2.ConnectionDetail{}
for _, cd := range src.Spec.ConnectionDetails {
connectionDetails = append(connectionDetails, v1alpha2.ConnectionDetail{
ObjectReference: cd.ObjectReference,
})
}

references := []v1alpha2.Reference{}
for _, r := range src.Spec.References {
ref := v1alpha2.Reference{}
if r.DependsOn != nil {
ref.DependsOn = &v1alpha2.DependsOn{
APIVersion: r.DependsOn.APIVersion,
Kind: r.DependsOn.Kind,
Name: r.DependsOn.Name,
Namespace: r.DependsOn.Namespace,
}
}
if r.PatchesFrom != nil {
ref.PatchesFrom = &v1alpha2.PatchesFrom{
DependsOn: v1alpha2.DependsOn{
APIVersion: r.PatchesFrom.APIVersion,
Kind: r.PatchesFrom.Kind,
Name: r.PatchesFrom.Name,
Namespace: r.PatchesFrom.Namespace,
},
FieldPath: r.PatchesFrom.FieldPath,
}
}
references = append(references, ref)
}

dst.Spec = v1alpha2.ObjectSpec{
ResourceSpec: xpv1.ResourceSpec{
WriteConnectionSecretToReference: src.GetWriteConnectionSecretToReference(),
PublishConnectionDetailsTo: src.GetPublishConnectionDetailsTo(),
ProviderConfigReference: src.GetProviderConfigReference(),
DeletionPolicy: src.GetDeletionPolicy(),
},
ConnectionDetails: connectionDetails,
ForProvider: v1alpha2.ObjectParameters{
Manifest: src.Spec.ForProvider.Manifest,
},
References: references,
Readiness: v1alpha2.Readiness{
Policy: v1alpha2.ReadinessPolicy(src.Spec.Readiness.Policy),
},
}

// handle management policies migration
switch src.Spec.ManagementPolicy {
case Default, "":
dst.Spec.ManagementPolicies = xpv1.ManagementPolicies{xpv1.ManagementActionAll}
case ObserveCreateUpdate:
dst.Spec.ManagementPolicies = xpv1.ManagementPolicies{xpv1.ManagementActionObserve, xpv1.ManagementActionCreate, xpv1.ManagementActionUpdate}
case ObserveDelete:
dst.Spec.ManagementPolicies = xpv1.ManagementPolicies{xpv1.ManagementActionObserve, xpv1.ManagementActionDelete}
case Observe:
dst.Spec.ManagementPolicies = xpv1.ManagementPolicies{xpv1.ManagementActionObserve}
default:
return errors.New("unknown management policy")
}

return nil
}

// ConvertFrom converts from the Hub version (v1alpha2) to this version.
func (dst *Object) ConvertFrom(srcRaw conversion.Hub) error { // nolint:golint, gocyclo // We want to use different names for receiver parameter to be more clear.
src := srcRaw.(*v1alpha2.Object)

// copy identical fields
dst.ObjectMeta = src.ObjectMeta
dst.Status = ObjectStatus{
ResourceStatus: src.Status.ResourceStatus,
AtProvider: ObjectObservation{
Manifest: src.Status.AtProvider.Manifest,
},
}

connectionDetails := []ConnectionDetail{}
for _, cd := range src.Spec.ConnectionDetails {
connectionDetails = append(connectionDetails, ConnectionDetail{
ObjectReference: cd.ObjectReference,
})
}

references := []Reference{}
for _, r := range src.Spec.References {
ref := Reference{}
if r.DependsOn != nil {
ref.DependsOn = &DependsOn{
APIVersion: r.DependsOn.APIVersion,
Kind: r.DependsOn.Kind,
Name: r.DependsOn.Name,
Namespace: r.DependsOn.Namespace,
}
}
if r.PatchesFrom != nil {
ref.PatchesFrom = &PatchesFrom{
DependsOn: DependsOn{
APIVersion: r.PatchesFrom.APIVersion,
Kind: r.PatchesFrom.Kind,
Name: r.PatchesFrom.Name,
Namespace: r.PatchesFrom.Namespace,
},
FieldPath: r.PatchesFrom.FieldPath,
}
}
references = append(references, ref)
}

dst.Spec = ObjectSpec{
ResourceSpec: ResourceSpec{
WriteConnectionSecretToReference: src.GetWriteConnectionSecretToReference(),
PublishConnectionDetailsTo: src.GetPublishConnectionDetailsTo(),
ProviderConfigReference: src.GetProviderConfigReference(),
DeletionPolicy: src.GetDeletionPolicy(),
},
ConnectionDetails: connectionDetails,
ForProvider: ObjectParameters{
Manifest: src.Spec.ForProvider.Manifest,
},
References: references,
Readiness: Readiness{
Policy: ReadinessPolicy(src.Spec.Readiness.Policy),
},
}

// handle management policies migration
policySet := sets.New[xpv1.ManagementAction](src.GetManagementPolicies()...)

switch {
case policySet.Has(xpv1.ManagementActionAll):
dst.Spec.ManagementPolicy = Default
case policySet.HasAll(xpv1.ManagementActionObserve, xpv1.ManagementActionCreate, xpv1.ManagementActionUpdate, xpv1.ManagementActionDelete):
dst.Spec.ManagementPolicy = Default
case policySet.HasAll(xpv1.ManagementActionObserve, xpv1.ManagementActionCreate, xpv1.ManagementActionUpdate) &&
!policySet.Has(xpv1.ManagementActionDelete):
dst.Spec.ManagementPolicy = ObserveCreateUpdate
case policySet.HasAll(xpv1.ManagementActionObserve, xpv1.ManagementActionDelete) &&
!policySet.HasAny(xpv1.ManagementActionCreate, xpv1.ManagementActionUpdate):
dst.Spec.ManagementPolicy = ObserveDelete
case policySet.Has(xpv1.ManagementActionObserve) &&
!policySet.HasAny(xpv1.ManagementActionCreate, xpv1.ManagementActionUpdate, xpv1.ManagementActionDelete):
dst.Spec.ManagementPolicy = Observe
default:
// TODO(turkenh): Should we default to something here instead of erroring out?
return errors.New("unsupported management policy")
}

return nil
}
Loading

0 comments on commit cc10a8c

Please sign in to comment.