Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions api/v1/config/crd/eno.azure.io_inputmirrors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: inputmirrors.eno.azure.io
spec:
group: eno.azure.io
names:
kind: InputMirror
listKind: InputMirrorList
plural: inputmirrors
singular: inputmirror
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.sourceResource.name
name: Source
type: string
- jsonPath: .status.conditions[?(@.type=="Synced")].status
name: Synced
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1
schema:
openAPIV3Schema:
description: |-
InputMirror stores a copy of a resource from an overlay cluster.
It is created and managed by the OverlaySyncController based on Symphony.spec.overlayResourceRefs.
Compositions can bind to InputMirrors just like any other resource.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
type: string
metadata:
type: object
spec:
properties:
key:
description: Key matches the Symphony's overlayResourceRef key
type: string
symphonyRef:
description: SymphonyRef points to the owning Symphony
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
sourceResource:
description: SourceResource describes what resource to sync from
the overlay
properties:
group:
description: API Group of the resource (empty string for core
API group)
type: string
kind:
description: Kind of the resource (e.g., ConfigMap, Secret)
type: string
name:
description: Name of the resource
type: string
namespace:
description: Namespace of the resource (empty for cluster-scoped
resources)
type: string
version:
description: API Version of the resource
type: string
required:
- kind
- name
- version
type: object
required:
- key
- sourceResource
- symphonyRef
type: object
status:
properties:
conditions:
description: Conditions describe the sync state
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
data:
description: |-
Data contains the actual resource data from the overlay cluster.
This is the full resource serialized as JSON.
type: object
x-kubernetes-preserve-unknown-fields: true
lastSyncTime:
description: LastSyncTime records when the resource was last successfully
synced
format: date-time
type: string
syncGeneration:
description: SyncGeneration tracks the source resource's resourceVersion
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
81 changes: 81 additions & 0 deletions api/v1/config/crd/eno.azure.io_symphonies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,87 @@ spec:
- resource
type: object
type: array
overlayCredentials:
description: |-
OverlayCredentials specifies how to access the overlay cluster.
When set, the OverlaySyncController will use these credentials to sync
resources specified in OverlayResourceRefs.
properties:
key:
default: kubeconfig
description: Key within the secret containing the kubeconfig data
type: string
secretRef:
description: SecretRef references a Secret containing the kubeconfig
for the overlay cluster
properties:
name:
description: name is unique within a namespace to reference
a secret resource.
type: string
namespace:
description: namespace defines the space within which the
secret name must be unique.
type: string
type: object
required:
- secretRef
type: object
overlayResourceRefs:
description: |-
OverlayResourceRefs specifies resources to sync from the overlay cluster.
Each ref results in an InputMirror being created that can be bound as an input.
items:
description: OverlayResourceRef defines a resource to sync from
an overlay cluster
properties:
key:
description: |-
Key that will be used to reference this input in Composition bindings.
This key maps to an auto-created InputMirror resource.
type: string
optional:
default: false
description: Optional indicates that synthesis can proceed if
this resource doesn't exist in the overlay.
type: boolean
resource:
description: Resource specifies what to fetch from the overlay
cluster
properties:
group:
description: API Group of the resource (empty string for
core API group)
type: string
kind:
description: Kind of the resource (e.g., ConfigMap, Secret)
type: string
name:
description: Name of the resource
type: string
namespace:
description: Namespace of the resource (empty for cluster-scoped
resources)
type: string
version:
description: API Version of the resource
type: string
required:
- kind
- name
- version
type: object
syncInterval:
default: 5m
description: SyncInterval determines how often to re-sync the
resource.
type: string
required:
- key
- resource
type: object
maxItems: 20
type: array
synthesisEnv:
description: |-
SynthesisEnv
Expand Down
111 changes: 111 additions & 0 deletions api/v1/inputmirror.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package v1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)

// +kubebuilder:object:root=true
type InputMirrorList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []InputMirror `json:"items"`
}

// InputMirror stores a copy of a resource from a remote cluster.
// It is created and managed by the RemoteSyncController based on Symphony.spec.remoteResourceRefs.
// Compositions can bind to InputMirrors just like any other resource.
//
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Source",type=string,JSONPath=`.spec.sourceResource.name`
// +kubebuilder:printcolumn:name="Synced",type=string,JSONPath=`.status.conditions[?(@.type=="Synced")].status`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
type InputMirror struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often do you think these values will change? I'm wondering if we could keep the API simple by configuring a static list of mirrors per eno-reconciler process in a static config file.

metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec InputMirrorSpec `json:"spec,omitempty"`
Status InputMirrorStatus `json:"status,omitempty"`
}

type InputMirrorSpec struct {
// Key matches the Symphony's remoteResourceRef key
Key string `json:"key"`

// SymphonyRef points to the owning Symphony
SymphonyRef corev1.LocalObjectReference `json:"symphonyRef"`

// SourceResource describes what resource to sync from the remote cluster
SourceResource RemoteResourceSelector `json:"sourceResource"`
}

type InputMirrorStatus struct {
// Data contains the actual resource data from the remote cluster.
// This is the full resource serialized as JSON.
// +kubebuilder:pruning:PreserveUnknownFields
Data *runtime.RawExtension `json:"data,omitempty"`

// LastSyncTime records when the resource was last successfully synced
LastSyncTime *metav1.Time `json:"lastSyncTime,omitempty"`

// SyncGeneration tracks the source resource's resourceVersion
SyncGeneration string `json:"syncGeneration,omitempty"`

// Conditions describe the sync state
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// RemoteResourceSelector describes a resource to sync from a remote cluster
type RemoteResourceSelector struct {
// API Group of the resource (empty string for core API group)
// +optional
Group string `json:"group,omitempty"`

// API Version of the resource
Version string `json:"version"`

// Kind of the resource (e.g., ConfigMap, Secret)
Kind string `json:"kind"`

// Name of the resource
Name string `json:"name"`

// Namespace of the resource (empty for cluster-scoped resources)
// +optional
Namespace string `json:"namespace,omitempty"`
}

// RemoteCredentials specifies how to access a remote cluster
type RemoteCredentials struct {
// SecretRef references a Secret containing the kubeconfig for the remote cluster
SecretRef corev1.SecretReference `json:"secretRef"`

// Key within the secret containing the kubeconfig data
// +kubebuilder:default="kubeconfig"
// +optional
Key string `json:"key,omitempty"`
}

// RemoteResourceRef defines a resource to sync from a remote cluster
type RemoteResourceRef struct {
// Key that will be used to reference this input in Composition bindings.
// This key maps to an auto-created InputMirror resource.
Key string `json:"key"`

// Resource specifies what to fetch from the remote cluster
Resource RemoteResourceSelector `json:"resource"`

// SyncInterval determines how often to re-sync the resource.
// +kubebuilder:default="5m"
// +optional
SyncInterval *metav1.Duration `json:"syncInterval,omitempty"`

// Optional indicates that synthesis can proceed if this resource doesn't exist in the remote cluster.
// +kubebuilder:default=false
// +optional
Optional bool `json:"optional,omitempty"`
}
12 changes: 12 additions & 0 deletions api/v1/symphony.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ type SymphonySpec struct {
// Copied opaquely into the compositions managed by this symphony.
// +kubebuilder:validation:MaxItems:=50
SynthesisEnv []EnvVar `json:"synthesisEnv,omitempty"` // deprecated synthesis env should always be variation scoped.

// RemoteCredentials specifies how to access the remote cluster.
// When set, the RemoteSyncController will use these credentials to sync
// resources specified in RemoteResourceRefs.
// +optional
RemoteCredentials *RemoteCredentials `json:"remoteCredentials,omitempty"`

// RemoteResourceRefs specifies resources to sync from the remote cluster.
// Each ref results in an InputMirror being created that can be bound as an input.
// +optional
// +kubebuilder:validation:MaxItems:=20
RemoteResourceRefs []RemoteResourceRef `json:"remoteResourceRefs,omitempty"`
}

type SymphonyStatus struct {
Expand Down
1 change: 1 addition & 0 deletions api/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ func init() {
SchemeBuilder.Register(&CompositionList{}, &Composition{})
SchemeBuilder.Register(&SymphonyList{}, &Symphony{})
SchemeBuilder.Register(&ResourceSliceList{}, &ResourceSlice{})
SchemeBuilder.Register(&InputMirrorList{}, &InputMirror{})
}
Loading
Loading