refactor shared api types to common package

Signed-off-by: Erhan Cagirici <erhan@upbound.io>
This commit is contained in:
Erhan Cagirici 2025-07-22 13:12:01 +03:00
parent 54f050c217
commit c056ae9de1
15 changed files with 945 additions and 477 deletions

View File

@ -219,6 +219,13 @@ linters:
- staticcheck
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:
- zz_generated\..+\.go$
- .+\.pb.go$

307
apis/common/condition.go Normal file
View File

@ -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,
}
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
package common
import (
"testing"

3
apis/common/doc.go Normal file
View File

@ -0,0 +1,3 @@
// Package common contains core API types used by most Crossplane resources.
// +kubebuilder:object:generate=true
package common

54
apis/common/merge.go Normal file
View File

@ -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
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
package common
import (
"reflect"

View File

@ -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
}

120
apis/common/policies.go Normal file
View File

@ -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"
)

328
apis/common/resource.go Normal file
View File

@ -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"`
}

View File

@ -17,23 +17,20 @@ limitations under the License.
package v1
import (
"sort"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/crossplane/crossplane-runtime/apis/common"
)
// A ConditionType represents a condition a resource could be in.
type ConditionType string
type ConditionType = common.ConditionType
// Condition types.
const (
// 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
// 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
// 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
// as a system condition. See the tracking issue for more details
// 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.
type ConditionReason string
type ConditionReason = common.ConditionReason
// Reasons a resource is or is not ready.
const (
ReasonAvailable ConditionReason = "Available"
ReasonUnavailable ConditionReason = "Unavailable"
ReasonCreating ConditionReason = "Creating"
ReasonDeleting ConditionReason = "Deleting"
ReasonAvailable = common.ReasonAvailable
ReasonUnavailable = common.ReasonUnavailable
ReasonCreating = common.ReasonCreating
ReasonDeleting = common.ReasonDeleting
)
// Reasons a resource is or is not synced.
const (
ReasonReconcileSuccess ConditionReason = "ReconcileSuccess"
ReasonReconcileError ConditionReason = "ReconcileError"
ReasonReconcilePaused ConditionReason = "ReconcilePaused"
ReasonReconcileSuccess = common.ReasonReconcileSuccess
ReasonReconcileError = common.ReasonReconcileError
ReasonReconcilePaused = common.ReasonReconcilePaused
)
// 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
}
type Condition = common.Condition
// 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
return common.IsSystemConditionType(t)
}
// 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
// one condition of each type may exist.
type ConditionedStatus struct {
// Conditions of the resource.
// +listType=map
// +listMapKey=type
// +optional
Conditions []Condition `json:"conditions,omitempty"`
}
type ConditionedStatus = common.ConditionedStatus
// 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
return common.NewConditionedStatus(c...)
}
// 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,
}
return common.Creating()
}
// 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,
}
return common.Deleting()
}
// 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,
}
return common.Available()
}
// 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
// because its API reports it is unhealthy.
func Unavailable() Condition {
return Condition{
Type: TypeReady,
Status: corev1.ConditionFalse,
LastTransitionTime: metav1.Now(),
Reason: ReasonUnavailable,
}
return common.Unavailable()
}
// 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,
}
return common.ReconcileSuccess()
}
// 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
// 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(),
}
return common.ReconcileError(err)
}
// 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,
}
return common.ReconcilePaused()
}

View File

@ -17,38 +17,8 @@ limitations under the License.
package v1
import (
"dario.cat/mergo"
"github.com/crossplane/crossplane-runtime/apis/common"
)
// 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
}
type MergeOptions = common.MergeOptions

View File

@ -16,22 +16,9 @@ limitations under the License.
package v1
import (
"github.com/crossplane/crossplane-runtime/apis/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
}
type ObservedStatus = common.ObservedStatus

View File

@ -16,39 +16,42 @@ limitations under the License.
package v1
import (
"github.com/crossplane/crossplane-runtime/apis/common"
)
// ManagementPolicies determine how should Crossplane controllers manage an
// external resource through an array of ManagementActions.
type ManagementPolicies []ManagementAction
type ManagementPolicies = common.ManagementPolicies
// 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
type ManagementAction = common.ManagementAction
const (
// ManagementActionObserve means that the managed resource status.atProvider
// will be updated with the external resource state.
ManagementActionObserve ManagementAction = "Observe"
ManagementActionObserve = common.ManagementActionObserve
// ManagementActionCreate means that the external resource will be created
// using the managed resource spec.initProvider and spec.forProvider.
ManagementActionCreate ManagementAction = "Create"
ManagementActionCreate = common.ManagementActionCreate
// ManagementActionUpdate means that the external resource will be updated
// using the managed resource spec.forProvider.
ManagementActionUpdate ManagementAction = "Update"
ManagementActionUpdate = common.ManagementActionUpdate
// ManagementActionDelete means that the external resource will be deleted
// when the managed resource is deleted.
ManagementActionDelete ManagementAction = "Delete"
ManagementActionDelete = common.ManagementActionDelete
// ManagementActionLateInitialize means that unspecified fields of the managed
// 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
// by the Crossplane controllers.
ManagementActionAll ManagementAction = "*"
ManagementActionAll = common.ManagementActionAll
)
// 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
// when the corresponding claim is deleted.
// +kubebuilder:validation:Enum=Background;Foreground
type CompositeDeletePolicy string
type CompositeDeletePolicy = common.CompositeDeletePolicy
const (
// CompositeDeleteBackground means the composite resource will be deleted using
// the Background Propagation Policy when the claim is deleted.
CompositeDeleteBackground CompositeDeletePolicy = "Background"
CompositeDeleteBackground = common.CompositeDeleteBackground
// CompositeDeleteForeground means the composite resource will be deleted using
// the Foreground Propagation Policy when the claim is deleted.
CompositeDeleteForeground CompositeDeletePolicy = "Foreground"
CompositeDeleteForeground = common.CompositeDeleteForeground
)
// An UpdatePolicy determines how something should be updated - either
// automatically (without human intervention) or manually.
// +kubebuilder:validation:Enum=Automatic;Manual
type UpdatePolicy string
type UpdatePolicy = common.UpdatePolicy
const (
// UpdateAutomatic means the resource should be updated automatically,
// without any human intervention.
UpdateAutomatic UpdatePolicy = "Automatic"
UpdateAutomatic = common.UpdateAutomatic
// UpdateManual means the resource requires human intervention to
// update.
UpdateManual UpdatePolicy = "Manual"
UpdateManual = common.UpdateManual
)
// ResolvePolicy is a type for resolve policy.
type ResolvePolicy string
type ResolvePolicy = common.ResolvePolicy
// ResolutionPolicy is a type for resolution policy.
type ResolutionPolicy string
type ResolutionPolicy = common.ResolutionPolicy
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"
ResolvePolicyAlways = common.ResolvePolicyAlways
// 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"
ResolutionPolicyRequired = common.ResolutionPolicyRequired
// 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"
ResolutionPolicyOptional = common.ResolutionPolicyOptional
)

View File

@ -18,8 +18,8 @@ package v1
import (
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 (
@ -45,11 +45,11 @@ const (
// LabelKeyProviderKind is added to ProviderConfigUsages to relate them to their
// ProviderConfig.
const LabelKeyProviderKind = "crossplane.io/provider-config-kind"
const LabelKeyProviderKind = common.LabelKeyProviderKind
// LabelKeyProviderName is added to ProviderConfigUsages to relate them to their
// ProviderConfig.
const LabelKeyProviderName = "crossplane.io/provider-config"
const LabelKeyProviderName = common.LabelKeyProviderName
// NOTE(negz): The below secret references differ from ObjectReference and
// 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
// the referencer.
type LocalSecretReference struct {
// Name of the secret.
Name string `json:"name"`
}
type LocalSecretReference = common.LocalSecretReference
// 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"`
}
type SecretReference = common.SecretReference
// 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"`
}
type SecretKeySelector = common.SecretKeySelector
// 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,
}
}
type LocalSecretKeySelector = common.LocalSecretKeySelector
// 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
}
type Policy = common.Policy
// 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"`
}
type Reference = common.Reference
// 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"`
}
type NamespacedReference = common.NamespacedReference
// 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"`
}
type TypedReference = common.TypedReference
// 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"`
}
type Selector = common.Selector
// 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"`
}
type NamespacedSelector = common.NamespacedSelector
// 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 }
type ProviderConfigReference = common.ProviderConfigReference
// TODO(negz): Rename Resource* to Managed* to clarify that they enable the
// resource.Managed interface.
@ -285,80 +146,48 @@ type ResourceStatus struct {
// A CredentialsSource is a source from which provider credentials may be
// acquired.
type CredentialsSource string
type CredentialsSource = common.CredentialsSource
const (
// CredentialsSourceNone indicates that a provider does not require
// credentials.
CredentialsSourceNone CredentialsSource = "None"
CredentialsSourceNone = common.CredentialsSourceNone
// CredentialsSourceSecret indicates that a provider should acquire
// credentials from a secret.
CredentialsSourceSecret CredentialsSource = "Secret"
CredentialsSourceSecret = common.CredentialsSourceSecret
// 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"
CredentialsSourceInjectedIdentity = common.CredentialsSourceInjectedIdentity
// CredentialsSourceEnvironment indicates that a provider should acquire
// credentials from an environment variable.
CredentialsSourceEnvironment CredentialsSource = "Environment"
CredentialsSourceEnvironment = common.CredentialsSourceEnvironment
// CredentialsSourceFilesystem indicates that a provider should acquire
// credentials from the filesystem.
CredentialsSourceFilesystem CredentialsSource = "Filesystem"
CredentialsSourceFilesystem = common.CredentialsSourceFilesystem
)
// CommonCredentialSelectors provides common selectors for extracting
// credentials.
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"`
}
type CommonCredentialSelectors = common.CommonCredentialSelectors
// EnvSelector selects an environment variable.
type EnvSelector struct {
// Name is the name of an environment variable.
Name string `json:"name"`
}
type EnvSelector = common.EnvSelector
// FsSelector selects a filesystem location.
type FsSelector struct {
// Path is a filesystem path.
Path string `json:"path"`
}
type FsSelector = common.FsSelector
// 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"`
}
type ProviderConfigStatus = common.ProviderConfigStatus
// 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"`
}
type ProviderConfigUsage = common.ProviderConfigUsage
// A TargetSpec defines the common fields of objects used for exposing
// infrastructure to workloads that can be scheduled to.

View File

@ -16,7 +16,9 @@ limitations under the License.
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.
type ManagedResourceSpec struct {
@ -25,13 +27,13 @@ type ManagedResourceSpec struct {
// be written. Connection details frequently include the endpoint, username,
// and password required to connect to the managed resource.
// +optional
WriteConnectionSecretToReference *v1.LocalSecretReference `json:"writeConnectionSecretToRef,omitempty"`
WriteConnectionSecretToReference *common.LocalSecretReference `json:"writeConnectionSecretToRef,omitempty"`
// ProviderConfigReference specifies how the provider that will be used to
// create, observe, update, and delete this managed resource should be
// configured.
// +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
// 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
// +optional
// +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 particular provider configuration.
type TypedProviderConfigUsage struct {
// 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"`
}
type TypedProviderConfigUsage = common.TypedProviderConfigUsage