-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Provider and Secret sync controllers
Signed-off-by: Danil Grigorev <danil.grigorev@suse.com>
- Loading branch information
1 parent
1a8c005
commit 2f6d1d5
Showing
3 changed files
with
192 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package sync | ||
|
||
import ( | ||
"context" | ||
|
||
"sigs.k8s.io/cluster-api/util/conditions" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2" | ||
|
||
turtlesv1 "github.com/rancher-sandbox/rancher-turtles/api/v1alpha1" | ||
) | ||
|
||
// ProviderSync is a structure mirroring state of the CAPI Operator Provider object. | ||
type ProviderSync struct { | ||
*DefaultSynchronizer | ||
} | ||
|
||
// NewProviderSync creates a new mirror object. | ||
func NewProviderSync(cl client.Client, capiProvider *turtlesv1.CAPIProvider) Sync { | ||
return &ProviderSync{ | ||
DefaultSynchronizer: NewDefaultSynchronizer(cl, capiProvider, ProviderSync{}.Template(capiProvider)), | ||
} | ||
} | ||
|
||
// Template returning the mirrored CAPI Operator manifest template. | ||
func (ProviderSync) Template(capiProvider *turtlesv1.CAPIProvider) client.Object { | ||
meta := metav1.ObjectMeta{ | ||
Name: string(capiProvider.Spec.Name), | ||
Namespace: capiProvider.GetNamespace(), | ||
} | ||
|
||
switch capiProvider.Spec.Type { | ||
case turtlesv1.Infrastructure: | ||
return &operatorv1.InfrastructureProvider{ObjectMeta: meta} | ||
case turtlesv1.Core: | ||
return &operatorv1.CoreProvider{ObjectMeta: meta} | ||
case turtlesv1.ControlPlane: | ||
return &operatorv1.ControlPlaneProvider{ObjectMeta: meta} | ||
case turtlesv1.Bootstrap: | ||
return &operatorv1.BootstrapProvider{ObjectMeta: meta} | ||
case turtlesv1.Addon: | ||
return &operatorv1.AddonProvider{ObjectMeta: meta} | ||
default: | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Sync updates the mirror object state from the upstream source object | ||
// Direction of updates: | ||
// Spec -> down | ||
// up <- Status. | ||
func (s *ProviderSync) Sync(_ context.Context) error { | ||
s.SyncObjects() | ||
|
||
return nil | ||
} | ||
|
||
// SyncObjects updates the Source CAPIProvider object and the destination provider object states. | ||
// Direction of updates: | ||
// Spec -> <Common>Provider | ||
// CAPIProvider <- Status. | ||
func (s *ProviderSync) SyncObjects() { | ||
switch mirror := s.Destination.(type) { | ||
case *operatorv1.InfrastructureProvider: | ||
s.Source.Spec.ProviderSpec.DeepCopyInto(&mirror.Spec.ProviderSpec) | ||
mirror.Status.ProviderStatus.DeepCopyInto(&s.Source.Status.ProviderStatus) | ||
case *operatorv1.CoreProvider: | ||
s.Source.Spec.ProviderSpec.DeepCopyInto(&mirror.Spec.ProviderSpec) | ||
mirror.Status.ProviderStatus.DeepCopyInto(&s.Source.Status.ProviderStatus) | ||
case *operatorv1.ControlPlaneProvider: | ||
s.Source.Spec.ProviderSpec.DeepCopyInto(&mirror.Spec.ProviderSpec) | ||
mirror.Status.ProviderStatus.DeepCopyInto(&s.Source.Status.ProviderStatus) | ||
case *operatorv1.BootstrapProvider: | ||
s.Source.Spec.ProviderSpec.DeepCopyInto(&mirror.Spec.ProviderSpec) | ||
mirror.Status.ProviderStatus.DeepCopyInto(&s.Source.Status.ProviderStatus) | ||
case *operatorv1.AddonProvider: | ||
s.Source.Spec.ProviderSpec.DeepCopyInto(&mirror.Spec.ProviderSpec) | ||
mirror.Status.ProviderStatus.DeepCopyInto(&s.Source.Status.ProviderStatus) | ||
default: | ||
} | ||
|
||
s.syncStatus() | ||
} | ||
|
||
func (s *ProviderSync) syncStatus() { | ||
switch { | ||
case conditions.IsTrue(s.Source, operatorv1.ProviderInstalledCondition): | ||
s.Source.Status.Phase = turtlesv1.Ready | ||
case conditions.IsFalse(s.Source, operatorv1.PreflightCheckCondition): | ||
s.Source.Status.Phase = turtlesv1.Failed | ||
default: | ||
s.Source.Status.Phase = turtlesv1.Provisioning | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package sync | ||
|
||
import ( | ||
"context" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
turtlesv1 "github.com/rancher-sandbox/rancher-turtles/api/v1alpha1" | ||
) | ||
|
||
// SecretSync is a structure mirroring variable secret state of the CAPI Operator Provider object. | ||
type SecretSync struct { | ||
*DefaultSynchronizer | ||
|
||
Secret *corev1.Secret | ||
} | ||
|
||
// NewSecretSync creates a new secret object sync. | ||
func NewSecretSync(cl client.Client, capiProvider *turtlesv1.CAPIProvider) Sync { | ||
secret := SecretSync{}.GetSecret(capiProvider) | ||
|
||
return &SecretSync{ | ||
DefaultSynchronizer: NewDefaultSynchronizer(cl, capiProvider, secret), | ||
Secret: secret, | ||
} | ||
} | ||
|
||
// GetSecret returning the mirrored secret resource template. | ||
func (SecretSync) GetSecret(capiProvider *turtlesv1.CAPIProvider) *corev1.Secret { | ||
meta := metav1.ObjectMeta{ | ||
Name: capiProvider.Name, | ||
Namespace: capiProvider.Namespace, | ||
} | ||
|
||
if capiProvider.Spec.ConfigSecret != nil { | ||
meta.Name = capiProvider.Spec.ConfigSecret.Name | ||
} | ||
|
||
return &corev1.Secret{ObjectMeta: meta} | ||
} | ||
|
||
// Template returning the mirrored secret resource template. | ||
func (SecretSync) Template(capiProvider *turtlesv1.CAPIProvider) client.Object { | ||
return SecretSync{}.GetSecret(capiProvider) | ||
} | ||
|
||
// Sync updates the mirror object state from the upstream source object | ||
// Direction of updates: | ||
// Spec -> down | ||
// up <- Status. | ||
func (s *SecretSync) Sync(_ context.Context) error { | ||
s.SyncObjects() | ||
|
||
return nil | ||
} | ||
|
||
// SyncObjects updates the Source CAPIProvider object and the environment secret state. | ||
// Direction of updates: | ||
// Spec.Features + Spec.Variables -> Status.Variables -> Secret. | ||
func (s *SecretSync) SyncObjects() { | ||
setVariables(s.DefaultSynchronizer.Source) | ||
setFeatures(s.DefaultSynchronizer.Source) | ||
|
||
s.Secret.StringData = s.DefaultSynchronizer.Source.Status.Variables | ||
} | ||
|
||
func setVariables(capiProvider *turtlesv1.CAPIProvider) { | ||
if capiProvider.Spec.Variables != nil { | ||
capiProvider.Status.Variables = capiProvider.Spec.Variables | ||
} | ||
} | ||
|
||
func setFeatures(capiProvider *turtlesv1.CAPIProvider) { | ||
value := "true" | ||
features := capiProvider.Spec.Features | ||
variables := capiProvider.Status.Variables | ||
|
||
if features != nil { | ||
if features.ClusterResourceSet { | ||
variables["EXP_CLUSTER_RESOURCE_SET"] = value | ||
} | ||
if features.ClusterTopology { | ||
variables["CLUSTER_TOPOLOGY"] = value | ||
} | ||
if features.MachinePool { | ||
variables["EXP_MACHINE_POOL"] = value | ||
} | ||
} | ||
} |