refactor shared api types to common package
Signed-off-by: Erhan Cagirici <erhan@upbound.io>
This commit is contained in:
parent
54f050c217
commit
c056ae9de1
|
@ -219,6 +219,13 @@ linters:
|
||||||
- staticcheck
|
- staticcheck
|
||||||
text: 'SA1019: .+ is deprecated: Use Composition Functions instead.'
|
text: 'SA1019: .+ is deprecated: Use Composition Functions instead.'
|
||||||
|
|
||||||
|
# Some shared structs in apis/common/v1 are moved to
|
||||||
|
# apis/common. To preserve a backward-compatible directory structure
|
||||||
|
# package had to be named common, which we suppress.
|
||||||
|
- linters:
|
||||||
|
- revive
|
||||||
|
text: "var-naming: avoid meaningless package names"
|
||||||
|
path: apis/common
|
||||||
paths:
|
paths:
|
||||||
- zz_generated\..+\.go$
|
- zz_generated\..+\.go$
|
||||||
- .+\.pb.go$
|
- .+\.pb.go$
|
||||||
|
|
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ConditionType represents a condition a resource could be in.
|
||||||
|
type ConditionType string
|
||||||
|
|
||||||
|
// Condition types.
|
||||||
|
const (
|
||||||
|
// TypeReady resources are believed to be ready to handle work.
|
||||||
|
TypeReady ConditionType = "Ready"
|
||||||
|
|
||||||
|
// TypeSynced resources are believed to be in sync with the
|
||||||
|
// Kubernetes resources that manage their lifecycle.
|
||||||
|
TypeSynced ConditionType = "Synced"
|
||||||
|
|
||||||
|
// TypeHealthy resources are believed to be in a healthy state and to have all
|
||||||
|
// of their child resources in a healthy state. For example, a claim is
|
||||||
|
// healthy when the claim is synced and the underlying composite resource is
|
||||||
|
// both synced and healthy. A composite resource is healthy when the composite
|
||||||
|
// resource is synced and all composed resources are synced and, if
|
||||||
|
// applicable, healthy (e.g., the composed resource is a composite resource).
|
||||||
|
// TODO: This condition is not yet implemented. It is currently just reserved
|
||||||
|
// as a system condition. See the tracking issue for more details
|
||||||
|
// https://github.com/crossplane/crossplane/issues/5643.
|
||||||
|
TypeHealthy ConditionType = "Healthy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ConditionReason represents the reason a resource is in a condition.
|
||||||
|
type ConditionReason string
|
||||||
|
|
||||||
|
// Reasons a resource is or is not ready.
|
||||||
|
const (
|
||||||
|
ReasonAvailable ConditionReason = "Available"
|
||||||
|
ReasonUnavailable ConditionReason = "Unavailable"
|
||||||
|
ReasonCreating ConditionReason = "Creating"
|
||||||
|
ReasonDeleting ConditionReason = "Deleting"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reasons a resource is or is not synced.
|
||||||
|
const (
|
||||||
|
ReasonReconcileSuccess ConditionReason = "ReconcileSuccess"
|
||||||
|
ReasonReconcileError ConditionReason = "ReconcileError"
|
||||||
|
ReasonReconcilePaused ConditionReason = "ReconcilePaused"
|
||||||
|
)
|
||||||
|
|
||||||
|
// See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
|
||||||
|
|
||||||
|
// A Condition that may apply to a resource.
|
||||||
|
type Condition struct { //nolint:recvcheck // False positive - only has non-pointer methods AFAICT.
|
||||||
|
// Type of this condition. At most one of each condition type may apply to
|
||||||
|
// a resource at any point in time.
|
||||||
|
Type ConditionType `json:"type"`
|
||||||
|
|
||||||
|
// Status of this condition; is it currently True, False, or Unknown?
|
||||||
|
Status corev1.ConditionStatus `json:"status"`
|
||||||
|
|
||||||
|
// LastTransitionTime is the last time this condition transitioned from one
|
||||||
|
// status to another.
|
||||||
|
LastTransitionTime metav1.Time `json:"lastTransitionTime"`
|
||||||
|
|
||||||
|
// A Reason for this condition's last transition from one status to another.
|
||||||
|
Reason ConditionReason `json:"reason"`
|
||||||
|
|
||||||
|
// A Message containing details about this condition's last transition from
|
||||||
|
// one status to another, if any.
|
||||||
|
// +optional
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
|
||||||
|
// ObservedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||||
|
// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||||
|
// with respect to the current state of the instance.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the condition is identical to the supplied condition,
|
||||||
|
// ignoring the LastTransitionTime.
|
||||||
|
func (c Condition) Equal(other Condition) bool {
|
||||||
|
return c.Type == other.Type &&
|
||||||
|
c.Status == other.Status &&
|
||||||
|
c.Reason == other.Reason &&
|
||||||
|
c.Message == other.Message &&
|
||||||
|
c.ObservedGeneration == other.ObservedGeneration
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMessage returns a condition by adding the provided message to existing
|
||||||
|
// condition.
|
||||||
|
func (c Condition) WithMessage(msg string) Condition {
|
||||||
|
c.Message = msg
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithObservedGeneration returns a condition by adding the provided observed generation
|
||||||
|
// to existing condition.
|
||||||
|
func (c Condition) WithObservedGeneration(gen int64) Condition {
|
||||||
|
c.ObservedGeneration = gen
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSystemConditionType returns true if the condition is owned by the
|
||||||
|
// Crossplane system (e.g, Ready, Synced, Healthy).
|
||||||
|
func IsSystemConditionType(t ConditionType) bool {
|
||||||
|
switch t {
|
||||||
|
case TypeReady, TypeSynced, TypeHealthy:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(negz): Conditions are implemented as a slice rather than a map to comply
|
||||||
|
// with Kubernetes API conventions. Ideally we'd comply by using a map that
|
||||||
|
// marshalled to a JSON array, but doing so confuses the CRD schema generator.
|
||||||
|
// https://github.com/kubernetes/community/blob/9bf8cd/contributors/devel/sig-architecture/api-conventions.md#lists-of-named-subobjects-preferred-over-maps
|
||||||
|
|
||||||
|
// NOTE(negz): Do not manipulate Conditions directly. Use the Set method.
|
||||||
|
|
||||||
|
// A ConditionedStatus reflects the observed status of a resource. Only
|
||||||
|
// one condition of each type may exist.
|
||||||
|
type ConditionedStatus struct {
|
||||||
|
// Conditions of the resource.
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
|
// +optional
|
||||||
|
Conditions []Condition `json:"conditions,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConditionedStatus returns a stat with the supplied conditions set.
|
||||||
|
func NewConditionedStatus(c ...Condition) *ConditionedStatus {
|
||||||
|
s := &ConditionedStatus{}
|
||||||
|
s.SetConditions(c...)
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCondition returns the condition for the given ConditionType if exists,
|
||||||
|
// otherwise returns nil.
|
||||||
|
func (s *ConditionedStatus) GetCondition(ct ConditionType) Condition {
|
||||||
|
for _, c := range s.Conditions {
|
||||||
|
if c.Type == ct {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Condition{Type: ct, Status: corev1.ConditionUnknown}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConditions sets the supplied conditions, replacing any existing conditions
|
||||||
|
// of the same type. This is a no-op if all supplied conditions are identical,
|
||||||
|
// ignoring the last transition time, to those already set.
|
||||||
|
func (s *ConditionedStatus) SetConditions(c ...Condition) {
|
||||||
|
for _, cond := range c {
|
||||||
|
exists := false
|
||||||
|
|
||||||
|
for i, existing := range s.Conditions {
|
||||||
|
if existing.Type != cond.Type {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if existing.Equal(cond) {
|
||||||
|
exists = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Conditions[i] = cond
|
||||||
|
exists = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
s.Conditions = append(s.Conditions, cond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the status is identical to the supplied status,
|
||||||
|
// ignoring the LastTransitionTimes and order of statuses.
|
||||||
|
func (s *ConditionedStatus) Equal(other *ConditionedStatus) bool {
|
||||||
|
if s == nil || other == nil {
|
||||||
|
return s == nil && other == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(other.Conditions) != len(s.Conditions) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
sc := make([]Condition, len(s.Conditions))
|
||||||
|
copy(sc, s.Conditions)
|
||||||
|
|
||||||
|
oc := make([]Condition, len(other.Conditions))
|
||||||
|
copy(oc, other.Conditions)
|
||||||
|
|
||||||
|
// We should not have more than one condition of each type.
|
||||||
|
sort.Slice(sc, func(i, j int) bool { return sc[i].Type < sc[j].Type })
|
||||||
|
sort.Slice(oc, func(i, j int) bool { return oc[i].Type < oc[j].Type })
|
||||||
|
|
||||||
|
for i := range sc {
|
||||||
|
if !sc[i].Equal(oc[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating returns a condition that indicates the resource is currently
|
||||||
|
// being created.
|
||||||
|
func Creating() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeReady,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonCreating,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting returns a condition that indicates the resource is currently
|
||||||
|
// being deleted.
|
||||||
|
func Deleting() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeReady,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonDeleting,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Available returns a condition that indicates the resource is
|
||||||
|
// currently observed to be available for use.
|
||||||
|
func Available() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeReady,
|
||||||
|
Status: corev1.ConditionTrue,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonAvailable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unavailable returns a condition that indicates the resource is not
|
||||||
|
// currently available for use. Unavailable should be set only when Crossplane
|
||||||
|
// expects the resource to be available but knows it is not, for example
|
||||||
|
// because its API reports it is unhealthy.
|
||||||
|
func Unavailable() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeReady,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonUnavailable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReconcileSuccess returns a condition indicating that Crossplane successfully
|
||||||
|
// completed the most recent reconciliation of the resource.
|
||||||
|
func ReconcileSuccess() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeSynced,
|
||||||
|
Status: corev1.ConditionTrue,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonReconcileSuccess,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReconcileError returns a condition indicating that Crossplane encountered an
|
||||||
|
// error while reconciling the resource. This could mean Crossplane was
|
||||||
|
// unable to update the resource to reflect its desired state, or that
|
||||||
|
// Crossplane was unable to determine the current actual state of the resource.
|
||||||
|
func ReconcileError(err error) Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeSynced,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonReconcileError,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReconcilePaused returns a condition that indicates reconciliation on
|
||||||
|
// the managed resource is paused via the pause annotation.
|
||||||
|
func ReconcilePaused() Condition {
|
||||||
|
return Condition{
|
||||||
|
Type: TypeSynced,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: ReasonReconcilePaused,
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Package common contains core API types used by most Crossplane resources.
|
||||||
|
// +kubebuilder:object:generate=true
|
||||||
|
package common
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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 common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dario.cat/mergo"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MergeOptions Specifies merge options on a field path.
|
||||||
|
type MergeOptions struct { // TODO(aru): add more options that control merging behavior
|
||||||
|
// Specifies that already existing values in a merged map should be preserved
|
||||||
|
// +optional
|
||||||
|
KeepMapValues *bool `json:"keepMapValues,omitempty"`
|
||||||
|
// Specifies that already existing elements in a merged slice should be preserved
|
||||||
|
// +optional
|
||||||
|
AppendSlice *bool `json:"appendSlice,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergoConfiguration the default behavior is to replace maps and slices.
|
||||||
|
func (mo *MergeOptions) MergoConfiguration() []func(*mergo.Config) {
|
||||||
|
config := []func(*mergo.Config){mergo.WithOverride}
|
||||||
|
if mo == nil {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
if mo.KeepMapValues != nil && *mo.KeepMapValues {
|
||||||
|
config = config[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if mo.AppendSlice != nil && *mo.AppendSlice {
|
||||||
|
config = append(config, mergo.WithAppendSlice)
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAppendSlice returns true if mo.AppendSlice is set to true.
|
||||||
|
func (mo *MergeOptions) IsAppendSlice() bool {
|
||||||
|
return mo != nil && mo.AppendSlice != nil && *mo.AppendSlice
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright 2024 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 common
|
||||||
|
|
||||||
|
// ObservedStatus contains the recent reconciliation stats.
|
||||||
|
type ObservedStatus struct {
|
||||||
|
// ObservedGeneration is the latest metadata.generation
|
||||||
|
// which resulted in either a ready state, or stalled due to error
|
||||||
|
// it can not recover from without human intervention.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetObservedGeneration sets the generation of the main resource
|
||||||
|
// during the last reconciliation.
|
||||||
|
func (s *ObservedStatus) SetObservedGeneration(generation int64) {
|
||||||
|
s.ObservedGeneration = generation
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObservedGeneration returns the last observed generation of the main resource.
|
||||||
|
func (s *ObservedStatus) GetObservedGeneration() int64 {
|
||||||
|
return s.ObservedGeneration
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 common
|
||||||
|
|
||||||
|
// ManagementPolicies determine how should Crossplane controllers manage an
|
||||||
|
// external resource through an array of ManagementActions.
|
||||||
|
type ManagementPolicies []ManagementAction
|
||||||
|
|
||||||
|
// A ManagementAction represents an action that the Crossplane controllers
|
||||||
|
// can take on an external resource.
|
||||||
|
// +kubebuilder:validation:Enum=Observe;Create;Update;Delete;LateInitialize;*
|
||||||
|
type ManagementAction string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ManagementActionObserve means that the managed resource status.atProvider
|
||||||
|
// will be updated with the external resource state.
|
||||||
|
ManagementActionObserve ManagementAction = "Observe"
|
||||||
|
|
||||||
|
// ManagementActionCreate means that the external resource will be created
|
||||||
|
// using the managed resource spec.initProvider and spec.forProvider.
|
||||||
|
ManagementActionCreate ManagementAction = "Create"
|
||||||
|
|
||||||
|
// ManagementActionUpdate means that the external resource will be updated
|
||||||
|
// using the managed resource spec.forProvider.
|
||||||
|
ManagementActionUpdate ManagementAction = "Update"
|
||||||
|
|
||||||
|
// ManagementActionDelete means that the external resource will be deleted
|
||||||
|
// when the managed resource is deleted.
|
||||||
|
ManagementActionDelete ManagementAction = "Delete"
|
||||||
|
|
||||||
|
// ManagementActionLateInitialize means that unspecified fields of the managed
|
||||||
|
// resource spec.forProvider will be updated with the external resource state.
|
||||||
|
ManagementActionLateInitialize ManagementAction = "LateInitialize"
|
||||||
|
|
||||||
|
// ManagementActionAll means that all of the above actions will be taken
|
||||||
|
// by the Crossplane controllers.
|
||||||
|
ManagementActionAll ManagementAction = "*"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A DeletionPolicy determines what should happen to the underlying external
|
||||||
|
// resource when a managed resource is deleted.
|
||||||
|
// +kubebuilder:validation:Enum=Orphan;Delete
|
||||||
|
type DeletionPolicy string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DeletionOrphan means the external resource will be orphaned when its
|
||||||
|
// managed resource is deleted.
|
||||||
|
DeletionOrphan DeletionPolicy = "Orphan"
|
||||||
|
|
||||||
|
// DeletionDelete means both the external resource will be deleted when its
|
||||||
|
// managed resource is deleted.
|
||||||
|
DeletionDelete DeletionPolicy = "Delete"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A CompositeDeletePolicy determines how the composite resource should be deleted
|
||||||
|
// when the corresponding claim is deleted.
|
||||||
|
// +kubebuilder:validation:Enum=Background;Foreground
|
||||||
|
type CompositeDeletePolicy string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CompositeDeleteBackground means the composite resource will be deleted using
|
||||||
|
// the Background Propagation Policy when the claim is deleted.
|
||||||
|
CompositeDeleteBackground CompositeDeletePolicy = "Background"
|
||||||
|
|
||||||
|
// CompositeDeleteForeground means the composite resource will be deleted using
|
||||||
|
// the Foreground Propagation Policy when the claim is deleted.
|
||||||
|
CompositeDeleteForeground CompositeDeletePolicy = "Foreground"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An UpdatePolicy determines how something should be updated - either
|
||||||
|
// automatically (without human intervention) or manually.
|
||||||
|
// +kubebuilder:validation:Enum=Automatic;Manual
|
||||||
|
type UpdatePolicy string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UpdateAutomatic means the resource should be updated automatically,
|
||||||
|
// without any human intervention.
|
||||||
|
UpdateAutomatic UpdatePolicy = "Automatic"
|
||||||
|
|
||||||
|
// UpdateManual means the resource requires human intervention to
|
||||||
|
// update.
|
||||||
|
UpdateManual UpdatePolicy = "Manual"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResolvePolicy is a type for resolve policy.
|
||||||
|
type ResolvePolicy string
|
||||||
|
|
||||||
|
// ResolutionPolicy is a type for resolution policy.
|
||||||
|
type ResolutionPolicy string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ResolvePolicyAlways is a resolve option.
|
||||||
|
// When the ResolvePolicy is set to ResolvePolicyAlways the reference will
|
||||||
|
// be tried to resolve for every reconcile loop.
|
||||||
|
ResolvePolicyAlways ResolvePolicy = "Always"
|
||||||
|
|
||||||
|
// ResolutionPolicyRequired is a resolution option.
|
||||||
|
// When the ResolutionPolicy is set to ResolutionPolicyRequired the execution
|
||||||
|
// could not continue even if the reference cannot be resolved.
|
||||||
|
ResolutionPolicyRequired ResolutionPolicy = "Required"
|
||||||
|
|
||||||
|
// ResolutionPolicyOptional is a resolution option.
|
||||||
|
// When the ReferenceResolutionPolicy is set to ReferencePolicyOptional the
|
||||||
|
// execution could continue even if the reference cannot be resolved.
|
||||||
|
ResolutionPolicyOptional ResolutionPolicy = "Optional"
|
||||||
|
)
|
|
@ -0,0 +1,328 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ResourceCredentialsSecretEndpointKey is the key inside a connection secret for the connection endpoint.
|
||||||
|
ResourceCredentialsSecretEndpointKey = "endpoint"
|
||||||
|
// ResourceCredentialsSecretPortKey is the key inside a connection secret for the connection port.
|
||||||
|
ResourceCredentialsSecretPortKey = "port"
|
||||||
|
// ResourceCredentialsSecretUserKey is the key inside a connection secret for the connection user.
|
||||||
|
ResourceCredentialsSecretUserKey = "username"
|
||||||
|
// ResourceCredentialsSecretPasswordKey is the key inside a connection secret for the connection password.
|
||||||
|
ResourceCredentialsSecretPasswordKey = "password"
|
||||||
|
// ResourceCredentialsSecretCAKey is the key inside a connection secret for the server CA certificate.
|
||||||
|
ResourceCredentialsSecretCAKey = "clusterCA"
|
||||||
|
// ResourceCredentialsSecretClientCertKey is the key inside a connection secret for the client certificate.
|
||||||
|
ResourceCredentialsSecretClientCertKey = "clientCert"
|
||||||
|
// ResourceCredentialsSecretClientKeyKey is the key inside a connection secret for the client key.
|
||||||
|
ResourceCredentialsSecretClientKeyKey = "clientKey"
|
||||||
|
// ResourceCredentialsSecretTokenKey is the key inside a connection secret for the bearer token value.
|
||||||
|
ResourceCredentialsSecretTokenKey = "token"
|
||||||
|
// ResourceCredentialsSecretKubeconfigKey is the key inside a connection secret for the raw kubeconfig yaml.
|
||||||
|
ResourceCredentialsSecretKubeconfigKey = "kubeconfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LabelKeyProviderKind is added to ProviderConfigUsages to relate them to their
|
||||||
|
// ProviderConfig.
|
||||||
|
const LabelKeyProviderKind = "crossplane.io/provider-config-kind"
|
||||||
|
|
||||||
|
// LabelKeyProviderName is added to ProviderConfigUsages to relate them to their
|
||||||
|
// ProviderConfig.
|
||||||
|
const LabelKeyProviderName = "crossplane.io/provider-config"
|
||||||
|
|
||||||
|
// NOTE(negz): The below secret references differ from ObjectReference and
|
||||||
|
// LocalObjectReference in that they include only the fields Crossplane needs to
|
||||||
|
// reference a secret, and make those fields required. This reduces ambiguity in
|
||||||
|
// the API for resource authors.
|
||||||
|
|
||||||
|
// A LocalSecretReference is a reference to a secret in the same namespace as
|
||||||
|
// the referencer.
|
||||||
|
type LocalSecretReference struct {
|
||||||
|
// Name of the secret.
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A SecretReference is a reference to a secret in an arbitrary namespace.
|
||||||
|
type SecretReference struct {
|
||||||
|
// Name of the secret.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Namespace of the secret.
|
||||||
|
Namespace string `json:"namespace"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A SecretKeySelector is a reference to a secret key in an arbitrary namespace.
|
||||||
|
type SecretKeySelector struct {
|
||||||
|
SecretReference `json:",inline"`
|
||||||
|
|
||||||
|
// The key to select.
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A LocalSecretKeySelector is a reference to a secret key
|
||||||
|
// in the same namespace with the referencing object.
|
||||||
|
type LocalSecretKeySelector struct {
|
||||||
|
LocalSecretReference `json:",inline"`
|
||||||
|
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSecretKeySelector is a convenience method for converting the
|
||||||
|
// LocalSecretKeySelector to a SecretKeySelector with the given namespace.
|
||||||
|
func (ls *LocalSecretKeySelector) ToSecretKeySelector(namespace string) *SecretKeySelector {
|
||||||
|
return &SecretKeySelector{
|
||||||
|
SecretReference: SecretReference{
|
||||||
|
Name: ls.Name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Key: ls.Key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Policy represents the Resolve and Resolution policies of Reference instance.
|
||||||
|
type Policy struct {
|
||||||
|
// Resolve specifies when this reference should be resolved. The default
|
||||||
|
// is 'IfNotPresent', which will attempt to resolve the reference only when
|
||||||
|
// the corresponding field is not present. Use 'Always' to resolve the
|
||||||
|
// reference on every reconcile.
|
||||||
|
// +optional
|
||||||
|
// +kubebuilder:validation:Enum=Always;IfNotPresent
|
||||||
|
Resolve *ResolvePolicy `json:"resolve,omitempty"`
|
||||||
|
|
||||||
|
// Resolution specifies whether resolution of this reference is required.
|
||||||
|
// The default is 'Required', which means the reconcile will fail if the
|
||||||
|
// reference cannot be resolved. 'Optional' means this reference will be
|
||||||
|
// a no-op if it cannot be resolved.
|
||||||
|
// +optional
|
||||||
|
// +kubebuilder:default=Required
|
||||||
|
// +kubebuilder:validation:Enum=Required;Optional
|
||||||
|
Resolution *ResolutionPolicy `json:"resolution,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsResolutionPolicyOptional checks whether the resolution policy of relevant reference is Optional.
|
||||||
|
func (p *Policy) IsResolutionPolicyOptional() bool {
|
||||||
|
if p == nil || p.Resolution == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return *p.Resolution == ResolutionPolicyOptional
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsResolvePolicyAlways checks whether the resolution policy of relevant reference is Always.
|
||||||
|
func (p *Policy) IsResolvePolicyAlways() bool {
|
||||||
|
if p == nil || p.Resolve == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return *p.Resolve == ResolvePolicyAlways
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Reference to a named object.
|
||||||
|
type Reference struct {
|
||||||
|
// Name of the referenced object.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Policies for referencing.
|
||||||
|
// +optional
|
||||||
|
Policy *Policy `json:"policy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A NamespacedReference to a named object.
|
||||||
|
type NamespacedReference struct {
|
||||||
|
// Name of the referenced object.
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Namespace of the referenced object
|
||||||
|
// +optional
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
// Policies for referencing.
|
||||||
|
// +optional
|
||||||
|
Policy *Policy `json:"policy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A TypedReference refers to an object by Name, Kind, and APIVersion. It is
|
||||||
|
// commonly used to reference cluster-scoped objects or objects where the
|
||||||
|
// namespace is already known.
|
||||||
|
type TypedReference struct {
|
||||||
|
// APIVersion of the referenced object.
|
||||||
|
APIVersion string `json:"apiVersion"`
|
||||||
|
|
||||||
|
// Kind of the referenced object.
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
|
||||||
|
// Name of the referenced object.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// UID of the referenced object.
|
||||||
|
// +optional
|
||||||
|
UID types.UID `json:"uid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Selector selects an object.
|
||||||
|
type Selector struct {
|
||||||
|
// MatchLabels ensures an object with matching labels is selected.
|
||||||
|
MatchLabels map[string]string `json:"matchLabels,omitempty"`
|
||||||
|
|
||||||
|
// MatchControllerRef ensures an object with the same controller reference
|
||||||
|
// as the selecting object is selected.
|
||||||
|
MatchControllerRef *bool `json:"matchControllerRef,omitempty"`
|
||||||
|
|
||||||
|
// Policies for selection.
|
||||||
|
// +optional
|
||||||
|
Policy *Policy `json:"policy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NamespacedSelector selects a namespaced object.
|
||||||
|
type NamespacedSelector struct {
|
||||||
|
// MatchLabels ensures an object with matching labels is selected.
|
||||||
|
MatchLabels map[string]string `json:"matchLabels,omitempty"`
|
||||||
|
|
||||||
|
// MatchControllerRef ensures an object with the same controller reference
|
||||||
|
// as the selecting object is selected.
|
||||||
|
MatchControllerRef *bool `json:"matchControllerRef,omitempty"`
|
||||||
|
|
||||||
|
// Policies for selection.
|
||||||
|
// +optional
|
||||||
|
Policy *Policy `json:"policy,omitempty"`
|
||||||
|
|
||||||
|
// Namespace for the selector
|
||||||
|
// +optional
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderConfigReference is a typed reference to a ProviderConfig
|
||||||
|
// object, with a known api group.
|
||||||
|
type ProviderConfigReference struct {
|
||||||
|
// Kind of the referenced object.
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
|
||||||
|
// Name of the referenced object.
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGroupVersionKind sets the Kind and APIVersion of a TypedReference.
|
||||||
|
func (obj *TypedReference) SetGroupVersionKind(gvk schema.GroupVersionKind) {
|
||||||
|
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupVersionKind gets the GroupVersionKind of a TypedReference.
|
||||||
|
func (obj *TypedReference) GroupVersionKind() schema.GroupVersionKind {
|
||||||
|
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectKind get the ObjectKind of a TypedReference.
|
||||||
|
func (obj *TypedReference) GetObjectKind() schema.ObjectKind { return obj }
|
||||||
|
|
||||||
|
// ResourceStatus represents the observed state of a managed resource.
|
||||||
|
type ResourceStatus struct {
|
||||||
|
ConditionedStatus `json:",inline"`
|
||||||
|
ObservedStatus `json:",inline"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A CredentialsSource is a source from which provider credentials may be
|
||||||
|
// acquired.
|
||||||
|
type CredentialsSource string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CredentialsSourceNone indicates that a provider does not require
|
||||||
|
// credentials.
|
||||||
|
CredentialsSourceNone CredentialsSource = "None"
|
||||||
|
|
||||||
|
// CredentialsSourceSecret indicates that a provider should acquire
|
||||||
|
// credentials from a secret.
|
||||||
|
CredentialsSourceSecret CredentialsSource = "Secret"
|
||||||
|
|
||||||
|
// CredentialsSourceInjectedIdentity indicates that a provider should use
|
||||||
|
// credentials via its (pod's) identity; i.e. via IRSA for AWS,
|
||||||
|
// Workload Identity for GCP, Pod Identity for Azure, or in-cluster
|
||||||
|
// authentication for the Kubernetes API.
|
||||||
|
CredentialsSourceInjectedIdentity CredentialsSource = "InjectedIdentity"
|
||||||
|
|
||||||
|
// CredentialsSourceEnvironment indicates that a provider should acquire
|
||||||
|
// credentials from an environment variable.
|
||||||
|
CredentialsSourceEnvironment CredentialsSource = "Environment"
|
||||||
|
|
||||||
|
// CredentialsSourceFilesystem indicates that a provider should acquire
|
||||||
|
// credentials from the filesystem.
|
||||||
|
CredentialsSourceFilesystem CredentialsSource = "Filesystem"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CommonCredentialSelectors provides common selectors for extracting
|
||||||
|
// credentials.
|
||||||
|
//
|
||||||
|
//nolint:revive // preserve backward-compatibility
|
||||||
|
type CommonCredentialSelectors struct {
|
||||||
|
// Fs is a reference to a filesystem location that contains credentials that
|
||||||
|
// must be used to connect to the provider.
|
||||||
|
// +optional
|
||||||
|
Fs *FsSelector `json:"fs,omitempty"`
|
||||||
|
|
||||||
|
// Env is a reference to an environment variable that contains credentials
|
||||||
|
// that must be used to connect to the provider.
|
||||||
|
// +optional
|
||||||
|
Env *EnvSelector `json:"env,omitempty"`
|
||||||
|
|
||||||
|
// A SecretRef is a reference to a secret key that contains the credentials
|
||||||
|
// that must be used to connect to the provider.
|
||||||
|
// +optional
|
||||||
|
SecretRef *SecretKeySelector `json:"secretRef,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvSelector selects an environment variable.
|
||||||
|
type EnvSelector struct {
|
||||||
|
// Name is the name of an environment variable.
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsSelector selects a filesystem location.
|
||||||
|
type FsSelector struct {
|
||||||
|
// Path is a filesystem path.
|
||||||
|
Path string `json:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ProviderConfigStatus defines the observed status of a ProviderConfig.
|
||||||
|
type ProviderConfigStatus struct {
|
||||||
|
ConditionedStatus `json:",inline"`
|
||||||
|
|
||||||
|
// Users of this provider configuration.
|
||||||
|
Users int64 `json:"users,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ProviderConfigUsage is a record that a particular managed resource is using
|
||||||
|
// a particular provider configuration.
|
||||||
|
type ProviderConfigUsage struct {
|
||||||
|
// ProviderConfigReference to the provider config being used.
|
||||||
|
ProviderConfigReference Reference `json:"providerConfigRef"`
|
||||||
|
|
||||||
|
// ResourceReference to the managed resource using the provider config.
|
||||||
|
ResourceReference TypedReference `json:"resourceRef"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A TypedProviderConfigUsage is a record that a particular managed resource is using
|
||||||
|
// a particular provider configuration.
|
||||||
|
type TypedProviderConfigUsage struct {
|
||||||
|
// ProviderConfigReference to the provider config being used.
|
||||||
|
ProviderConfigReference ProviderConfigReference `json:"providerConfigRef"`
|
||||||
|
|
||||||
|
// ResourceReference to the managed resource using the provider config.
|
||||||
|
ResourceReference TypedReference `json:"resourceRef"`
|
||||||
|
}
|
|
@ -17,23 +17,20 @@ limitations under the License.
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ConditionType represents a condition a resource could be in.
|
// A ConditionType represents a condition a resource could be in.
|
||||||
type ConditionType string
|
type ConditionType = common.ConditionType
|
||||||
|
|
||||||
// Condition types.
|
// Condition types.
|
||||||
const (
|
const (
|
||||||
// TypeReady resources are believed to be ready to handle work.
|
// TypeReady resources are believed to be ready to handle work.
|
||||||
TypeReady ConditionType = "Ready"
|
TypeReady ConditionType = common.TypeReady
|
||||||
|
|
||||||
// TypeSynced resources are believed to be in sync with the
|
// TypeSynced resources are believed to be in sync with the
|
||||||
// Kubernetes resources that manage their lifecycle.
|
// Kubernetes resources that manage their lifecycle.
|
||||||
TypeSynced ConditionType = "Synced"
|
TypeSynced ConditionType = common.TypeSynced
|
||||||
|
|
||||||
// TypeHealthy resources are believed to be in a healthy state and to have all
|
// TypeHealthy resources are believed to be in a healthy state and to have all
|
||||||
// of their child resources in a healthy state. For example, a claim is
|
// of their child resources in a healthy state. For example, a claim is
|
||||||
|
@ -44,90 +41,36 @@ const (
|
||||||
// TODO: This condition is not yet implemented. It is currently just reserved
|
// TODO: This condition is not yet implemented. It is currently just reserved
|
||||||
// as a system condition. See the tracking issue for more details
|
// as a system condition. See the tracking issue for more details
|
||||||
// https://github.com/crossplane/crossplane/issues/5643.
|
// https://github.com/crossplane/crossplane/issues/5643.
|
||||||
TypeHealthy ConditionType = "Healthy"
|
TypeHealthy ConditionType = common.TypeHealthy
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ConditionReason represents the reason a resource is in a condition.
|
// A ConditionReason represents the reason a resource is in a condition.
|
||||||
type ConditionReason string
|
type ConditionReason = common.ConditionReason
|
||||||
|
|
||||||
// Reasons a resource is or is not ready.
|
// Reasons a resource is or is not ready.
|
||||||
const (
|
const (
|
||||||
ReasonAvailable ConditionReason = "Available"
|
ReasonAvailable = common.ReasonAvailable
|
||||||
ReasonUnavailable ConditionReason = "Unavailable"
|
ReasonUnavailable = common.ReasonUnavailable
|
||||||
ReasonCreating ConditionReason = "Creating"
|
ReasonCreating = common.ReasonCreating
|
||||||
ReasonDeleting ConditionReason = "Deleting"
|
ReasonDeleting = common.ReasonDeleting
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reasons a resource is or is not synced.
|
// Reasons a resource is or is not synced.
|
||||||
const (
|
const (
|
||||||
ReasonReconcileSuccess ConditionReason = "ReconcileSuccess"
|
ReasonReconcileSuccess = common.ReasonReconcileSuccess
|
||||||
ReasonReconcileError ConditionReason = "ReconcileError"
|
ReasonReconcileError = common.ReasonReconcileError
|
||||||
ReasonReconcilePaused ConditionReason = "ReconcilePaused"
|
ReasonReconcilePaused = common.ReasonReconcilePaused
|
||||||
)
|
)
|
||||||
|
|
||||||
// See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
|
// See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
|
||||||
|
|
||||||
// A Condition that may apply to a resource.
|
// A Condition that may apply to a resource.
|
||||||
type Condition struct { //nolint:recvcheck // False positive - only has non-pointer methods AFAICT.
|
type Condition = common.Condition
|
||||||
// Type of this condition. At most one of each condition type may apply to
|
|
||||||
// a resource at any point in time.
|
|
||||||
Type ConditionType `json:"type"`
|
|
||||||
|
|
||||||
// Status of this condition; is it currently True, False, or Unknown?
|
|
||||||
Status corev1.ConditionStatus `json:"status"`
|
|
||||||
|
|
||||||
// LastTransitionTime is the last time this condition transitioned from one
|
|
||||||
// status to another.
|
|
||||||
LastTransitionTime metav1.Time `json:"lastTransitionTime"`
|
|
||||||
|
|
||||||
// A Reason for this condition's last transition from one status to another.
|
|
||||||
Reason ConditionReason `json:"reason"`
|
|
||||||
|
|
||||||
// A Message containing details about this condition's last transition from
|
|
||||||
// one status to another, if any.
|
|
||||||
// +optional
|
|
||||||
Message string `json:"message,omitempty"`
|
|
||||||
|
|
||||||
// ObservedGeneration represents the .metadata.generation that the condition was set based upon.
|
|
||||||
// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
|
||||||
// with respect to the current state of the instance.
|
|
||||||
// +optional
|
|
||||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if the condition is identical to the supplied condition,
|
|
||||||
// ignoring the LastTransitionTime.
|
|
||||||
func (c Condition) Equal(other Condition) bool {
|
|
||||||
return c.Type == other.Type &&
|
|
||||||
c.Status == other.Status &&
|
|
||||||
c.Reason == other.Reason &&
|
|
||||||
c.Message == other.Message &&
|
|
||||||
c.ObservedGeneration == other.ObservedGeneration
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMessage returns a condition by adding the provided message to existing
|
|
||||||
// condition.
|
|
||||||
func (c Condition) WithMessage(msg string) Condition {
|
|
||||||
c.Message = msg
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithObservedGeneration returns a condition by adding the provided observed generation
|
|
||||||
// to existing condition.
|
|
||||||
func (c Condition) WithObservedGeneration(gen int64) Condition {
|
|
||||||
c.ObservedGeneration = gen
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSystemConditionType returns true if the condition is owned by the
|
// IsSystemConditionType returns true if the condition is owned by the
|
||||||
// Crossplane system (e.g, Ready, Synced, Healthy).
|
// Crossplane system (e.g, Ready, Synced, Healthy).
|
||||||
func IsSystemConditionType(t ConditionType) bool {
|
func IsSystemConditionType(t ConditionType) bool {
|
||||||
switch t {
|
return common.IsSystemConditionType(t)
|
||||||
case TypeReady, TypeSynced, TypeHealthy:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(negz): Conditions are implemented as a slice rather than a map to comply
|
// NOTE(negz): Conditions are implemented as a slice rather than a map to comply
|
||||||
|
@ -139,122 +82,29 @@ func IsSystemConditionType(t ConditionType) bool {
|
||||||
|
|
||||||
// A ConditionedStatus reflects the observed status of a resource. Only
|
// A ConditionedStatus reflects the observed status of a resource. Only
|
||||||
// one condition of each type may exist.
|
// one condition of each type may exist.
|
||||||
type ConditionedStatus struct {
|
type ConditionedStatus = common.ConditionedStatus
|
||||||
// Conditions of the resource.
|
|
||||||
// +listType=map
|
|
||||||
// +listMapKey=type
|
|
||||||
// +optional
|
|
||||||
Conditions []Condition `json:"conditions,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConditionedStatus returns a stat with the supplied conditions set.
|
// NewConditionedStatus returns a stat with the supplied conditions set.
|
||||||
func NewConditionedStatus(c ...Condition) *ConditionedStatus {
|
func NewConditionedStatus(c ...Condition) *ConditionedStatus {
|
||||||
s := &ConditionedStatus{}
|
return common.NewConditionedStatus(c...)
|
||||||
s.SetConditions(c...)
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCondition returns the condition for the given ConditionType if exists,
|
|
||||||
// otherwise returns nil.
|
|
||||||
func (s *ConditionedStatus) GetCondition(ct ConditionType) Condition {
|
|
||||||
for _, c := range s.Conditions {
|
|
||||||
if c.Type == ct {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Condition{Type: ct, Status: corev1.ConditionUnknown}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetConditions sets the supplied conditions, replacing any existing conditions
|
|
||||||
// of the same type. This is a no-op if all supplied conditions are identical,
|
|
||||||
// ignoring the last transition time, to those already set.
|
|
||||||
func (s *ConditionedStatus) SetConditions(c ...Condition) {
|
|
||||||
for _, cond := range c {
|
|
||||||
exists := false
|
|
||||||
|
|
||||||
for i, existing := range s.Conditions {
|
|
||||||
if existing.Type != cond.Type {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if existing.Equal(cond) {
|
|
||||||
exists = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Conditions[i] = cond
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
s.Conditions = append(s.Conditions, cond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if the status is identical to the supplied status,
|
|
||||||
// ignoring the LastTransitionTimes and order of statuses.
|
|
||||||
func (s *ConditionedStatus) Equal(other *ConditionedStatus) bool {
|
|
||||||
if s == nil || other == nil {
|
|
||||||
return s == nil && other == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(other.Conditions) != len(s.Conditions) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
sc := make([]Condition, len(s.Conditions))
|
|
||||||
copy(sc, s.Conditions)
|
|
||||||
|
|
||||||
oc := make([]Condition, len(other.Conditions))
|
|
||||||
copy(oc, other.Conditions)
|
|
||||||
|
|
||||||
// We should not have more than one condition of each type.
|
|
||||||
sort.Slice(sc, func(i, j int) bool { return sc[i].Type < sc[j].Type })
|
|
||||||
sort.Slice(oc, func(i, j int) bool { return oc[i].Type < oc[j].Type })
|
|
||||||
|
|
||||||
for i := range sc {
|
|
||||||
if !sc[i].Equal(oc[i]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creating returns a condition that indicates the resource is currently
|
// Creating returns a condition that indicates the resource is currently
|
||||||
// being created.
|
// being created.
|
||||||
func Creating() Condition {
|
func Creating() Condition {
|
||||||
return Condition{
|
return common.Creating()
|
||||||
Type: TypeReady,
|
|
||||||
Status: corev1.ConditionFalse,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonCreating,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deleting returns a condition that indicates the resource is currently
|
// Deleting returns a condition that indicates the resource is currently
|
||||||
// being deleted.
|
// being deleted.
|
||||||
func Deleting() Condition {
|
func Deleting() Condition {
|
||||||
return Condition{
|
return common.Deleting()
|
||||||
Type: TypeReady,
|
|
||||||
Status: corev1.ConditionFalse,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonDeleting,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Available returns a condition that indicates the resource is
|
// Available returns a condition that indicates the resource is
|
||||||
// currently observed to be available for use.
|
// currently observed to be available for use.
|
||||||
func Available() Condition {
|
func Available() Condition {
|
||||||
return Condition{
|
return common.Available()
|
||||||
Type: TypeReady,
|
|
||||||
Status: corev1.ConditionTrue,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonAvailable,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unavailable returns a condition that indicates the resource is not
|
// Unavailable returns a condition that indicates the resource is not
|
||||||
|
@ -262,23 +112,13 @@ func Available() Condition {
|
||||||
// expects the resource to be available but knows it is not, for example
|
// expects the resource to be available but knows it is not, for example
|
||||||
// because its API reports it is unhealthy.
|
// because its API reports it is unhealthy.
|
||||||
func Unavailable() Condition {
|
func Unavailable() Condition {
|
||||||
return Condition{
|
return common.Unavailable()
|
||||||
Type: TypeReady,
|
|
||||||
Status: corev1.ConditionFalse,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonUnavailable,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReconcileSuccess returns a condition indicating that Crossplane successfully
|
// ReconcileSuccess returns a condition indicating that Crossplane successfully
|
||||||
// completed the most recent reconciliation of the resource.
|
// completed the most recent reconciliation of the resource.
|
||||||
func ReconcileSuccess() Condition {
|
func ReconcileSuccess() Condition {
|
||||||
return Condition{
|
return common.ReconcileSuccess()
|
||||||
Type: TypeSynced,
|
|
||||||
Status: corev1.ConditionTrue,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonReconcileSuccess,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReconcileError returns a condition indicating that Crossplane encountered an
|
// ReconcileError returns a condition indicating that Crossplane encountered an
|
||||||
|
@ -286,22 +126,11 @@ func ReconcileSuccess() Condition {
|
||||||
// unable to update the resource to reflect its desired state, or that
|
// unable to update the resource to reflect its desired state, or that
|
||||||
// Crossplane was unable to determine the current actual state of the resource.
|
// Crossplane was unable to determine the current actual state of the resource.
|
||||||
func ReconcileError(err error) Condition {
|
func ReconcileError(err error) Condition {
|
||||||
return Condition{
|
return common.ReconcileError(err)
|
||||||
Type: TypeSynced,
|
|
||||||
Status: corev1.ConditionFalse,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonReconcileError,
|
|
||||||
Message: err.Error(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReconcilePaused returns a condition that indicates reconciliation on
|
// ReconcilePaused returns a condition that indicates reconciliation on
|
||||||
// the managed resource is paused via the pause annotation.
|
// the managed resource is paused via the pause annotation.
|
||||||
func ReconcilePaused() Condition {
|
func ReconcilePaused() Condition {
|
||||||
return Condition{
|
return common.ReconcilePaused()
|
||||||
Type: TypeSynced,
|
|
||||||
Status: corev1.ConditionFalse,
|
|
||||||
LastTransitionTime: metav1.Now(),
|
|
||||||
Reason: ReasonReconcilePaused,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,38 +17,8 @@ limitations under the License.
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"dario.cat/mergo"
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MergeOptions Specifies merge options on a field path.
|
// MergeOptions Specifies merge options on a field path.
|
||||||
type MergeOptions struct { // TODO(aru): add more options that control merging behavior
|
type MergeOptions = common.MergeOptions
|
||||||
// Specifies that already existing values in a merged map should be preserved
|
|
||||||
// +optional
|
|
||||||
KeepMapValues *bool `json:"keepMapValues,omitempty"`
|
|
||||||
// Specifies that already existing elements in a merged slice should be preserved
|
|
||||||
// +optional
|
|
||||||
AppendSlice *bool `json:"appendSlice,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergoConfiguration the default behavior is to replace maps and slices.
|
|
||||||
func (mo *MergeOptions) MergoConfiguration() []func(*mergo.Config) {
|
|
||||||
config := []func(*mergo.Config){mergo.WithOverride}
|
|
||||||
if mo == nil {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
if mo.KeepMapValues != nil && *mo.KeepMapValues {
|
|
||||||
config = config[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if mo.AppendSlice != nil && *mo.AppendSlice {
|
|
||||||
config = append(config, mergo.WithAppendSlice)
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAppendSlice returns true if mo.AppendSlice is set to true.
|
|
||||||
func (mo *MergeOptions) IsAppendSlice() bool {
|
|
||||||
return mo != nil && mo.AppendSlice != nil && *mo.AppendSlice
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,22 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
|
)
|
||||||
|
|
||||||
// ObservedStatus contains the recent reconciliation stats.
|
// ObservedStatus contains the recent reconciliation stats.
|
||||||
type ObservedStatus struct {
|
type ObservedStatus = common.ObservedStatus
|
||||||
// ObservedGeneration is the latest metadata.generation
|
|
||||||
// which resulted in either a ready state, or stalled due to error
|
|
||||||
// it can not recover from without human intervention.
|
|
||||||
// +optional
|
|
||||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetObservedGeneration sets the generation of the main resource
|
|
||||||
// during the last reconciliation.
|
|
||||||
func (s *ObservedStatus) SetObservedGeneration(generation int64) {
|
|
||||||
s.ObservedGeneration = generation
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetObservedGeneration returns the last observed generation of the main resource.
|
|
||||||
func (s *ObservedStatus) GetObservedGeneration() int64 {
|
|
||||||
return s.ObservedGeneration
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,39 +16,42 @@ limitations under the License.
|
||||||
|
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
|
)
|
||||||
|
|
||||||
// ManagementPolicies determine how should Crossplane controllers manage an
|
// ManagementPolicies determine how should Crossplane controllers manage an
|
||||||
// external resource through an array of ManagementActions.
|
// external resource through an array of ManagementActions.
|
||||||
type ManagementPolicies []ManagementAction
|
type ManagementPolicies = common.ManagementPolicies
|
||||||
|
|
||||||
// A ManagementAction represents an action that the Crossplane controllers
|
// A ManagementAction represents an action that the Crossplane controllers
|
||||||
// can take on an external resource.
|
// can take on an external resource.
|
||||||
// +kubebuilder:validation:Enum=Observe;Create;Update;Delete;LateInitialize;*
|
type ManagementAction = common.ManagementAction
|
||||||
type ManagementAction string
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ManagementActionObserve means that the managed resource status.atProvider
|
// ManagementActionObserve means that the managed resource status.atProvider
|
||||||
// will be updated with the external resource state.
|
// will be updated with the external resource state.
|
||||||
ManagementActionObserve ManagementAction = "Observe"
|
ManagementActionObserve = common.ManagementActionObserve
|
||||||
|
|
||||||
// ManagementActionCreate means that the external resource will be created
|
// ManagementActionCreate means that the external resource will be created
|
||||||
// using the managed resource spec.initProvider and spec.forProvider.
|
// using the managed resource spec.initProvider and spec.forProvider.
|
||||||
ManagementActionCreate ManagementAction = "Create"
|
ManagementActionCreate = common.ManagementActionCreate
|
||||||
|
|
||||||
// ManagementActionUpdate means that the external resource will be updated
|
// ManagementActionUpdate means that the external resource will be updated
|
||||||
// using the managed resource spec.forProvider.
|
// using the managed resource spec.forProvider.
|
||||||
ManagementActionUpdate ManagementAction = "Update"
|
ManagementActionUpdate = common.ManagementActionUpdate
|
||||||
|
|
||||||
// ManagementActionDelete means that the external resource will be deleted
|
// ManagementActionDelete means that the external resource will be deleted
|
||||||
// when the managed resource is deleted.
|
// when the managed resource is deleted.
|
||||||
ManagementActionDelete ManagementAction = "Delete"
|
ManagementActionDelete = common.ManagementActionDelete
|
||||||
|
|
||||||
// ManagementActionLateInitialize means that unspecified fields of the managed
|
// ManagementActionLateInitialize means that unspecified fields of the managed
|
||||||
// resource spec.forProvider will be updated with the external resource state.
|
// resource spec.forProvider will be updated with the external resource state.
|
||||||
ManagementActionLateInitialize ManagementAction = "LateInitialize"
|
ManagementActionLateInitialize = common.ManagementActionLateInitialize
|
||||||
|
|
||||||
// ManagementActionAll means that all of the above actions will be taken
|
// ManagementActionAll means that all of the above actions will be taken
|
||||||
// by the Crossplane controllers.
|
// by the Crossplane controllers.
|
||||||
ManagementActionAll ManagementAction = "*"
|
ManagementActionAll = common.ManagementActionAll
|
||||||
)
|
)
|
||||||
|
|
||||||
// A DeletionPolicy determines what should happen to the underlying external
|
// A DeletionPolicy determines what should happen to the underlying external
|
||||||
|
@ -68,53 +71,51 @@ const (
|
||||||
|
|
||||||
// A CompositeDeletePolicy determines how the composite resource should be deleted
|
// A CompositeDeletePolicy determines how the composite resource should be deleted
|
||||||
// when the corresponding claim is deleted.
|
// when the corresponding claim is deleted.
|
||||||
// +kubebuilder:validation:Enum=Background;Foreground
|
type CompositeDeletePolicy = common.CompositeDeletePolicy
|
||||||
type CompositeDeletePolicy string
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// CompositeDeleteBackground means the composite resource will be deleted using
|
// CompositeDeleteBackground means the composite resource will be deleted using
|
||||||
// the Background Propagation Policy when the claim is deleted.
|
// the Background Propagation Policy when the claim is deleted.
|
||||||
CompositeDeleteBackground CompositeDeletePolicy = "Background"
|
CompositeDeleteBackground = common.CompositeDeleteBackground
|
||||||
|
|
||||||
// CompositeDeleteForeground means the composite resource will be deleted using
|
// CompositeDeleteForeground means the composite resource will be deleted using
|
||||||
// the Foreground Propagation Policy when the claim is deleted.
|
// the Foreground Propagation Policy when the claim is deleted.
|
||||||
CompositeDeleteForeground CompositeDeletePolicy = "Foreground"
|
CompositeDeleteForeground = common.CompositeDeleteForeground
|
||||||
)
|
)
|
||||||
|
|
||||||
// An UpdatePolicy determines how something should be updated - either
|
// An UpdatePolicy determines how something should be updated - either
|
||||||
// automatically (without human intervention) or manually.
|
// automatically (without human intervention) or manually.
|
||||||
// +kubebuilder:validation:Enum=Automatic;Manual
|
type UpdatePolicy = common.UpdatePolicy
|
||||||
type UpdatePolicy string
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// UpdateAutomatic means the resource should be updated automatically,
|
// UpdateAutomatic means the resource should be updated automatically,
|
||||||
// without any human intervention.
|
// without any human intervention.
|
||||||
UpdateAutomatic UpdatePolicy = "Automatic"
|
UpdateAutomatic = common.UpdateAutomatic
|
||||||
|
|
||||||
// UpdateManual means the resource requires human intervention to
|
// UpdateManual means the resource requires human intervention to
|
||||||
// update.
|
// update.
|
||||||
UpdateManual UpdatePolicy = "Manual"
|
UpdateManual = common.UpdateManual
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResolvePolicy is a type for resolve policy.
|
// ResolvePolicy is a type for resolve policy.
|
||||||
type ResolvePolicy string
|
type ResolvePolicy = common.ResolvePolicy
|
||||||
|
|
||||||
// ResolutionPolicy is a type for resolution policy.
|
// ResolutionPolicy is a type for resolution policy.
|
||||||
type ResolutionPolicy string
|
type ResolutionPolicy = common.ResolutionPolicy
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ResolvePolicyAlways is a resolve option.
|
// ResolvePolicyAlways is a resolve option.
|
||||||
// When the ResolvePolicy is set to ResolvePolicyAlways the reference will
|
// When the ResolvePolicy is set to ResolvePolicyAlways the reference will
|
||||||
// be tried to resolve for every reconcile loop.
|
// be tried to resolve for every reconcile loop.
|
||||||
ResolvePolicyAlways ResolvePolicy = "Always"
|
ResolvePolicyAlways = common.ResolvePolicyAlways
|
||||||
|
|
||||||
// ResolutionPolicyRequired is a resolution option.
|
// ResolutionPolicyRequired is a resolution option.
|
||||||
// When the ResolutionPolicy is set to ResolutionPolicyRequired the execution
|
// When the ResolutionPolicy is set to ResolutionPolicyRequired the execution
|
||||||
// could not continue even if the reference cannot be resolved.
|
// could not continue even if the reference cannot be resolved.
|
||||||
ResolutionPolicyRequired ResolutionPolicy = "Required"
|
ResolutionPolicyRequired = common.ResolutionPolicyRequired
|
||||||
|
|
||||||
// ResolutionPolicyOptional is a resolution option.
|
// ResolutionPolicyOptional is a resolution option.
|
||||||
// When the ReferenceResolutionPolicy is set to ReferencePolicyOptional the
|
// When the ReferenceResolutionPolicy is set to ReferencePolicyOptional the
|
||||||
// execution could continue even if the reference cannot be resolved.
|
// execution could continue even if the reference cannot be resolved.
|
||||||
ResolutionPolicyOptional ResolutionPolicy = "Optional"
|
ResolutionPolicyOptional = common.ResolutionPolicyOptional
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,8 +18,8 @@ package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -45,11 +45,11 @@ const (
|
||||||
|
|
||||||
// LabelKeyProviderKind is added to ProviderConfigUsages to relate them to their
|
// LabelKeyProviderKind is added to ProviderConfigUsages to relate them to their
|
||||||
// ProviderConfig.
|
// ProviderConfig.
|
||||||
const LabelKeyProviderKind = "crossplane.io/provider-config-kind"
|
const LabelKeyProviderKind = common.LabelKeyProviderKind
|
||||||
|
|
||||||
// LabelKeyProviderName is added to ProviderConfigUsages to relate them to their
|
// LabelKeyProviderName is added to ProviderConfigUsages to relate them to their
|
||||||
// ProviderConfig.
|
// ProviderConfig.
|
||||||
const LabelKeyProviderName = "crossplane.io/provider-config"
|
const LabelKeyProviderName = common.LabelKeyProviderName
|
||||||
|
|
||||||
// NOTE(negz): The below secret references differ from ObjectReference and
|
// NOTE(negz): The below secret references differ from ObjectReference and
|
||||||
// LocalObjectReference in that they include only the fields Crossplane needs to
|
// LocalObjectReference in that they include only the fields Crossplane needs to
|
||||||
|
@ -58,180 +58,41 @@ const LabelKeyProviderName = "crossplane.io/provider-config"
|
||||||
|
|
||||||
// A LocalSecretReference is a reference to a secret in the same namespace as
|
// A LocalSecretReference is a reference to a secret in the same namespace as
|
||||||
// the referencer.
|
// the referencer.
|
||||||
type LocalSecretReference struct {
|
type LocalSecretReference = common.LocalSecretReference
|
||||||
// Name of the secret.
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A SecretReference is a reference to a secret in an arbitrary namespace.
|
// A SecretReference is a reference to a secret in an arbitrary namespace.
|
||||||
type SecretReference struct {
|
type SecretReference = common.SecretReference
|
||||||
// Name of the secret.
|
|
||||||
Name string `json:"name"`
|
|
||||||
// Namespace of the secret.
|
|
||||||
Namespace string `json:"namespace"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A SecretKeySelector is a reference to a secret key in an arbitrary namespace.
|
// A SecretKeySelector is a reference to a secret key in an arbitrary namespace.
|
||||||
type SecretKeySelector struct {
|
type SecretKeySelector = common.SecretKeySelector
|
||||||
SecretReference `json:",inline"`
|
|
||||||
|
|
||||||
// The key to select.
|
|
||||||
Key string `json:"key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A LocalSecretKeySelector is a reference to a secret key
|
// A LocalSecretKeySelector is a reference to a secret key
|
||||||
// in the same namespace with the referencing object.
|
// in the same namespace with the referencing object.
|
||||||
type LocalSecretKeySelector struct {
|
type LocalSecretKeySelector = common.LocalSecretKeySelector
|
||||||
LocalSecretReference `json:",inline"`
|
|
||||||
|
|
||||||
Key string `json:"key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToSecretKeySelector is a convenience method for converting the
|
|
||||||
// LocalSecretKeySelector to a SecretKeySelector with the given namespace.
|
|
||||||
func (ls *LocalSecretKeySelector) ToSecretKeySelector(namespace string) *SecretKeySelector {
|
|
||||||
return &SecretKeySelector{
|
|
||||||
SecretReference: SecretReference{
|
|
||||||
Name: ls.Name,
|
|
||||||
Namespace: namespace,
|
|
||||||
},
|
|
||||||
Key: ls.Key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Policy represents the Resolve and Resolution policies of Reference instance.
|
// Policy represents the Resolve and Resolution policies of Reference instance.
|
||||||
type Policy struct {
|
type Policy = common.Policy
|
||||||
// Resolve specifies when this reference should be resolved. The default
|
|
||||||
// is 'IfNotPresent', which will attempt to resolve the reference only when
|
|
||||||
// the corresponding field is not present. Use 'Always' to resolve the
|
|
||||||
// reference on every reconcile.
|
|
||||||
// +optional
|
|
||||||
// +kubebuilder:validation:Enum=Always;IfNotPresent
|
|
||||||
Resolve *ResolvePolicy `json:"resolve,omitempty"`
|
|
||||||
|
|
||||||
// Resolution specifies whether resolution of this reference is required.
|
|
||||||
// The default is 'Required', which means the reconcile will fail if the
|
|
||||||
// reference cannot be resolved. 'Optional' means this reference will be
|
|
||||||
// a no-op if it cannot be resolved.
|
|
||||||
// +optional
|
|
||||||
// +kubebuilder:default=Required
|
|
||||||
// +kubebuilder:validation:Enum=Required;Optional
|
|
||||||
Resolution *ResolutionPolicy `json:"resolution,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsResolutionPolicyOptional checks whether the resolution policy of relevant reference is Optional.
|
|
||||||
func (p *Policy) IsResolutionPolicyOptional() bool {
|
|
||||||
if p == nil || p.Resolution == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return *p.Resolution == ResolutionPolicyOptional
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsResolvePolicyAlways checks whether the resolution policy of relevant reference is Always.
|
|
||||||
func (p *Policy) IsResolvePolicyAlways() bool {
|
|
||||||
if p == nil || p.Resolve == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return *p.Resolve == ResolvePolicyAlways
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Reference to a named object.
|
// A Reference to a named object.
|
||||||
type Reference struct {
|
type Reference = common.Reference
|
||||||
// Name of the referenced object.
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Policies for referencing.
|
|
||||||
// +optional
|
|
||||||
Policy *Policy `json:"policy,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A NamespacedReference to a named object.
|
// A NamespacedReference to a named object.
|
||||||
type NamespacedReference struct {
|
type NamespacedReference = common.NamespacedReference
|
||||||
// Name of the referenced object.
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Namespace of the referenced object
|
|
||||||
// +optional
|
|
||||||
Namespace string `json:"namespace,omitempty"`
|
|
||||||
// Policies for referencing.
|
|
||||||
// +optional
|
|
||||||
Policy *Policy `json:"policy,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A TypedReference refers to an object by Name, Kind, and APIVersion. It is
|
// A TypedReference refers to an object by Name, Kind, and APIVersion. It is
|
||||||
// commonly used to reference cluster-scoped objects or objects where the
|
// commonly used to reference cluster-scoped objects or objects where the
|
||||||
// namespace is already known.
|
// namespace is already known.
|
||||||
type TypedReference struct {
|
type TypedReference = common.TypedReference
|
||||||
// APIVersion of the referenced object.
|
|
||||||
APIVersion string `json:"apiVersion"`
|
|
||||||
|
|
||||||
// Kind of the referenced object.
|
|
||||||
Kind string `json:"kind"`
|
|
||||||
|
|
||||||
// Name of the referenced object.
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// UID of the referenced object.
|
|
||||||
// +optional
|
|
||||||
UID types.UID `json:"uid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Selector selects an object.
|
// A Selector selects an object.
|
||||||
type Selector struct {
|
type Selector = common.Selector
|
||||||
// MatchLabels ensures an object with matching labels is selected.
|
|
||||||
MatchLabels map[string]string `json:"matchLabels,omitempty"`
|
|
||||||
|
|
||||||
// MatchControllerRef ensures an object with the same controller reference
|
|
||||||
// as the selecting object is selected.
|
|
||||||
MatchControllerRef *bool `json:"matchControllerRef,omitempty"`
|
|
||||||
|
|
||||||
// Policies for selection.
|
|
||||||
// +optional
|
|
||||||
Policy *Policy `json:"policy,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NamespacedSelector selects a namespaced object.
|
// NamespacedSelector selects a namespaced object.
|
||||||
type NamespacedSelector struct {
|
type NamespacedSelector = common.NamespacedSelector
|
||||||
// MatchLabels ensures an object with matching labels is selected.
|
|
||||||
MatchLabels map[string]string `json:"matchLabels,omitempty"`
|
|
||||||
|
|
||||||
// MatchControllerRef ensures an object with the same controller reference
|
|
||||||
// as the selecting object is selected.
|
|
||||||
MatchControllerRef *bool `json:"matchControllerRef,omitempty"`
|
|
||||||
|
|
||||||
// Policies for selection.
|
|
||||||
// +optional
|
|
||||||
Policy *Policy `json:"policy,omitempty"`
|
|
||||||
|
|
||||||
// Namespace for the selector
|
|
||||||
// +optional
|
|
||||||
Namespace string `json:"namespace,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProviderConfigReference is a typed reference to a ProviderConfig
|
// ProviderConfigReference is a typed reference to a ProviderConfig
|
||||||
// object, with a known api group.
|
// object, with a known api group.
|
||||||
type ProviderConfigReference struct {
|
type ProviderConfigReference = common.ProviderConfigReference
|
||||||
// Kind of the referenced object.
|
|
||||||
Kind string `json:"kind"`
|
|
||||||
|
|
||||||
// Name of the referenced object.
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGroupVersionKind sets the Kind and APIVersion of a TypedReference.
|
|
||||||
func (obj *TypedReference) SetGroupVersionKind(gvk schema.GroupVersionKind) {
|
|
||||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GroupVersionKind gets the GroupVersionKind of a TypedReference.
|
|
||||||
func (obj *TypedReference) GroupVersionKind() schema.GroupVersionKind {
|
|
||||||
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetObjectKind get the ObjectKind of a TypedReference.
|
|
||||||
func (obj *TypedReference) GetObjectKind() schema.ObjectKind { return obj }
|
|
||||||
|
|
||||||
// TODO(negz): Rename Resource* to Managed* to clarify that they enable the
|
// TODO(negz): Rename Resource* to Managed* to clarify that they enable the
|
||||||
// resource.Managed interface.
|
// resource.Managed interface.
|
||||||
|
@ -285,80 +146,48 @@ type ResourceStatus struct {
|
||||||
|
|
||||||
// A CredentialsSource is a source from which provider credentials may be
|
// A CredentialsSource is a source from which provider credentials may be
|
||||||
// acquired.
|
// acquired.
|
||||||
type CredentialsSource string
|
type CredentialsSource = common.CredentialsSource
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// CredentialsSourceNone indicates that a provider does not require
|
// CredentialsSourceNone indicates that a provider does not require
|
||||||
// credentials.
|
// credentials.
|
||||||
CredentialsSourceNone CredentialsSource = "None"
|
CredentialsSourceNone = common.CredentialsSourceNone
|
||||||
|
|
||||||
// CredentialsSourceSecret indicates that a provider should acquire
|
// CredentialsSourceSecret indicates that a provider should acquire
|
||||||
// credentials from a secret.
|
// credentials from a secret.
|
||||||
CredentialsSourceSecret CredentialsSource = "Secret"
|
CredentialsSourceSecret = common.CredentialsSourceSecret
|
||||||
|
|
||||||
// CredentialsSourceInjectedIdentity indicates that a provider should use
|
// CredentialsSourceInjectedIdentity indicates that a provider should use
|
||||||
// credentials via its (pod's) identity; i.e. via IRSA for AWS,
|
// credentials via its (pod's) identity; i.e. via IRSA for AWS,
|
||||||
// Workload Identity for GCP, Pod Identity for Azure, or in-cluster
|
// Workload Identity for GCP, Pod Identity for Azure, or in-cluster
|
||||||
// authentication for the Kubernetes API.
|
// authentication for the Kubernetes API.
|
||||||
CredentialsSourceInjectedIdentity CredentialsSource = "InjectedIdentity"
|
CredentialsSourceInjectedIdentity = common.CredentialsSourceInjectedIdentity
|
||||||
|
|
||||||
// CredentialsSourceEnvironment indicates that a provider should acquire
|
// CredentialsSourceEnvironment indicates that a provider should acquire
|
||||||
// credentials from an environment variable.
|
// credentials from an environment variable.
|
||||||
CredentialsSourceEnvironment CredentialsSource = "Environment"
|
CredentialsSourceEnvironment = common.CredentialsSourceEnvironment
|
||||||
|
|
||||||
// CredentialsSourceFilesystem indicates that a provider should acquire
|
// CredentialsSourceFilesystem indicates that a provider should acquire
|
||||||
// credentials from the filesystem.
|
// credentials from the filesystem.
|
||||||
CredentialsSourceFilesystem CredentialsSource = "Filesystem"
|
CredentialsSourceFilesystem = common.CredentialsSourceFilesystem
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommonCredentialSelectors provides common selectors for extracting
|
// CommonCredentialSelectors provides common selectors for extracting
|
||||||
// credentials.
|
// credentials.
|
||||||
type CommonCredentialSelectors struct {
|
type CommonCredentialSelectors = common.CommonCredentialSelectors
|
||||||
// Fs is a reference to a filesystem location that contains credentials that
|
|
||||||
// must be used to connect to the provider.
|
|
||||||
// +optional
|
|
||||||
Fs *FsSelector `json:"fs,omitempty"`
|
|
||||||
|
|
||||||
// Env is a reference to an environment variable that contains credentials
|
|
||||||
// that must be used to connect to the provider.
|
|
||||||
// +optional
|
|
||||||
Env *EnvSelector `json:"env,omitempty"`
|
|
||||||
|
|
||||||
// A SecretRef is a reference to a secret key that contains the credentials
|
|
||||||
// that must be used to connect to the provider.
|
|
||||||
// +optional
|
|
||||||
SecretRef *SecretKeySelector `json:"secretRef,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvSelector selects an environment variable.
|
// EnvSelector selects an environment variable.
|
||||||
type EnvSelector struct {
|
type EnvSelector = common.EnvSelector
|
||||||
// Name is the name of an environment variable.
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FsSelector selects a filesystem location.
|
// FsSelector selects a filesystem location.
|
||||||
type FsSelector struct {
|
type FsSelector = common.FsSelector
|
||||||
// Path is a filesystem path.
|
|
||||||
Path string `json:"path"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ProviderConfigStatus defines the observed status of a ProviderConfig.
|
// A ProviderConfigStatus defines the observed status of a ProviderConfig.
|
||||||
type ProviderConfigStatus struct {
|
type ProviderConfigStatus = common.ProviderConfigStatus
|
||||||
ConditionedStatus `json:",inline"`
|
|
||||||
|
|
||||||
// Users of this provider configuration.
|
|
||||||
Users int64 `json:"users,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ProviderConfigUsage is a record that a particular managed resource is using
|
// A ProviderConfigUsage is a record that a particular managed resource is using
|
||||||
// a particular provider configuration.
|
// a particular provider configuration.
|
||||||
type ProviderConfigUsage struct {
|
type ProviderConfigUsage = common.ProviderConfigUsage
|
||||||
// ProviderConfigReference to the provider config being used.
|
|
||||||
ProviderConfigReference Reference `json:"providerConfigRef"`
|
|
||||||
|
|
||||||
// ResourceReference to the managed resource using the provider config.
|
|
||||||
ResourceReference TypedReference `json:"resourceRef"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A TargetSpec defines the common fields of objects used for exposing
|
// A TargetSpec defines the common fields of objects used for exposing
|
||||||
// infrastructure to workloads that can be scheduled to.
|
// infrastructure to workloads that can be scheduled to.
|
||||||
|
|
|
@ -16,7 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
package v2
|
package v2
|
||||||
|
|
||||||
import v1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
|
import (
|
||||||
|
"github.com/crossplane/crossplane-runtime/apis/common"
|
||||||
|
)
|
||||||
|
|
||||||
// A ManagedResourceSpec defines the desired state of a managed resource.
|
// A ManagedResourceSpec defines the desired state of a managed resource.
|
||||||
type ManagedResourceSpec struct {
|
type ManagedResourceSpec struct {
|
||||||
|
@ -25,13 +27,13 @@ type ManagedResourceSpec struct {
|
||||||
// be written. Connection details frequently include the endpoint, username,
|
// be written. Connection details frequently include the endpoint, username,
|
||||||
// and password required to connect to the managed resource.
|
// and password required to connect to the managed resource.
|
||||||
// +optional
|
// +optional
|
||||||
WriteConnectionSecretToReference *v1.LocalSecretReference `json:"writeConnectionSecretToRef,omitempty"`
|
WriteConnectionSecretToReference *common.LocalSecretReference `json:"writeConnectionSecretToRef,omitempty"`
|
||||||
|
|
||||||
// ProviderConfigReference specifies how the provider that will be used to
|
// ProviderConfigReference specifies how the provider that will be used to
|
||||||
// create, observe, update, and delete this managed resource should be
|
// create, observe, update, and delete this managed resource should be
|
||||||
// configured.
|
// configured.
|
||||||
// +kubebuilder:default={"kind": "ClusterProviderConfig", "name": "default"}
|
// +kubebuilder:default={"kind": "ClusterProviderConfig", "name": "default"}
|
||||||
ProviderConfigReference *v1.ProviderConfigReference `json:"providerConfigRef,omitempty"`
|
ProviderConfigReference *common.ProviderConfigReference `json:"providerConfigRef,omitempty"`
|
||||||
|
|
||||||
// THIS IS A BETA FIELD. It is on by default but can be opted out
|
// THIS IS A BETA FIELD. It is on by default but can be opted out
|
||||||
// through a Crossplane feature flag.
|
// through a Crossplane feature flag.
|
||||||
|
@ -41,15 +43,9 @@ type ManagedResourceSpec struct {
|
||||||
// and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md
|
// and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md
|
||||||
// +optional
|
// +optional
|
||||||
// +kubebuilder:default={"*"}
|
// +kubebuilder:default={"*"}
|
||||||
ManagementPolicies v1.ManagementPolicies `json:"managementPolicies,omitempty"`
|
ManagementPolicies common.ManagementPolicies `json:"managementPolicies,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// A TypedProviderConfigUsage is a record that a particular managed resource is using
|
// A TypedProviderConfigUsage is a record that a particular managed resource is using
|
||||||
// a particular provider configuration.
|
// a particular provider configuration.
|
||||||
type TypedProviderConfigUsage struct {
|
type TypedProviderConfigUsage = common.TypedProviderConfigUsage
|
||||||
// ProviderConfigReference to the provider config being used.
|
|
||||||
ProviderConfigReference v1.ProviderConfigReference `json:"providerConfigRef"`
|
|
||||||
|
|
||||||
// ResourceReference to the managed resource using the provider config.
|
|
||||||
ResourceReference v1.TypedReference `json:"resourceRef"`
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue