Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PHX-35) Updating GcpNfsVolume CR and adding parts of SKR reconciler … #59

Merged
merged 1 commit into from
Jan 26, 2024
Merged
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
6 changes: 6 additions & 0 deletions components/kcp/api/cloud-control/v1beta1/iprange_ref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package v1beta1

type IpRangeRef struct {
// +kubebuilder:validation:Required
Name string `json:"name"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type NfsInstanceSpec struct {
RemoteRef RemoteRef `json:"remoteRef"`

// +kubebuilder:validation:Required
IpRange string `json:"ipRange"`
IpRange IpRangeRef `json:"ipRange"`

// +kubebuilder:validation:Required
Scope ScopeRef `json:"scope"`
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,30 @@ import (

// GcpNfsVolumeSpec defines the desired state of GcpNfsVolume
type GcpNfsVolumeSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// +kubebuilder:validation:Required
IpRange IpRangeRef `json:"ipRange"`
// +kubebuilder:validation:Required
Location string `json:"location"`

// Foo is an example field of GcpNfsVolume. Edit gcpnfsvolume_types.go to remove/update
Foo string `json:"foo,omitempty"`
// +kubebuilder:default=BASIC_HDD
Tier GcpFileTier `json:"tier"`

// +kubebuilder:validation:Pattern="^[a-z][a-z0-9_]*[a-z0-9]$"
// +kubebuilder:default=vol1
FileShareName string `json:"fileShareName"`

// +kubebuilder:default=2560
CapacityGb int `json:"capacityGb"`
}

// GcpNfsVolumeStatus defines the observed state of GcpNfsVolume
type GcpNfsVolumeStatus struct {
State StatusState `json:"state,omitempty"`

//List of NFS Hosts (DNS Names or IP Addresses) that clients can use to connect
// +optional
Hosts []string `json:"hosts,omitempty"`

// List of status conditions
// +optional
// +listType=map
Expand All @@ -50,6 +65,14 @@ type GcpNfsVolume struct {
Status GcpNfsVolumeStatus `json:"status,omitempty"`
}

func (in *GcpNfsVolume) Conditions() *[]metav1.Condition {
return &in.Status.Conditions
}

func (in *GcpNfsVolume) GetObjectMeta() *metav1.ObjectMeta {
return &in.ObjectMeta
}

//+kubebuilder:object:root=true

// GcpNfsVolumeList contains a list of GcpNfsVolume
Expand All @@ -62,3 +85,16 @@ type GcpNfsVolumeList struct {
func init() {
SchemeBuilder.Register(&GcpNfsVolume{}, &GcpNfsVolumeList{})
}

type GcpFileTier string

const (
STANDARD = GcpFileTier("STANDARD")
PREMIUM = GcpFileTier("PREMIUM")
BASIC_HDD = GcpFileTier("BASIC_HDD")
BASIC_SSD = GcpFileTier("BASIC_SSD")
HIGH_SCALE_SSD = GcpFileTier("HIGH_SCALE_SSD")
ENTERPRISE = GcpFileTier("ENTERPRISE")
ZONAL = GcpFileTier("ZONAL")
REGIONAL = GcpFileTier("REGIONAL")
)
6 changes: 6 additions & 0 deletions components/kcp/api/cloud-resources/v1beta1/iprange_ref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package v1beta1

type IpRangeRef struct {
// +kubebuilder:validation:Required
Name string `json:"name"`
}
9 changes: 9 additions & 0 deletions components/kcp/api/cloud-resources/v1beta1/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package v1beta1

type StatusState string

const (
UnknownState StatusState = "Unknown"
ReadyState StatusState = "Ready"
ErrorState StatusState = "Error"
)

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ spec:
type: object
type: object
ipRange:
type: string
properties:
name:
type: string
required:
- name
type: object
remoteRef:
properties:
name:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,31 @@ spec:
spec:
description: GcpNfsVolumeSpec defines the desired state of GcpNfsVolume
properties:
foo:
description: Foo is an example field of GcpNfsVolume. Edit gcpnfsvolume_types.go
to remove/update
capacityGb:
default: 2560
type: integer
fileShareName:
default: vol1
pattern: ^[a-z][a-z0-9_]*[a-z0-9]$
type: string
ipRange:
properties:
name:
type: string
required:
- name
type: object
location:
type: string
tier:
default: BASIC_HDD
type: string
required:
- capacityGb
- fileShareName
- ipRange
- location
- tier
type: object
status:
description: GcpNfsVolumeStatus defines the observed state of GcpNfsVolume
Expand Down Expand Up @@ -114,6 +135,14 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
hosts:
description: List of NFS Hosts (DNS Names or IP Addresses) that clients
can use to connect
items:
type: string
type: array
state:
type: string
type: object
type: object
served: true
Expand Down
6 changes: 3 additions & 3 deletions components/kcp/pkg/nfsinstance/loadIpRange.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func loadIpRange(ctx context.Context, st composed.State) (error, context.Context
ipRange := &cloudresourcesv1beta1.IpRange{}
err := state.Cluster().K8sClient().Get(ctx, types.NamespacedName{
Namespace: state.Obj().GetNamespace(),
Name: state.ObjAsNfsInstance().Spec.IpRange,
Name: state.ObjAsNfsInstance().Spec.IpRange.Name,
}, ipRange)

if client.IgnoreNotFound(err) != nil {
Expand All @@ -30,13 +30,13 @@ func loadIpRange(ctx context.Context, st composed.State) (error, context.Context

if apierrors.IsNotFound(err) {
logger.
WithValues("ipRange", state.ObjAsNfsInstance().Spec.IpRange).
WithValues("ipRange", state.ObjAsNfsInstance().Spec.IpRange.Name).
Error(err, "Referred IpRange does not exist")
meta.SetStatusCondition(state.ObjAsNfsInstance().Conditions(), metav1.Condition{
Type: cloudresourcesv1beta1.ConditionTypeError,
Status: "True",
Reason: cloudresourcesv1beta1.ReasonInvalidIpRangeReference,
Message: fmt.Sprintf("Referred IpRange %s/%s does not exist", state.Obj().GetNamespace(), state.ObjAsNfsInstance().Spec.IpRange),
Message: fmt.Sprintf("Referred IpRange %s/%s does not exist", state.Obj().GetNamespace(), state.ObjAsNfsInstance().Spec.IpRange.Name),
})
state.ObjAsNfsInstance().Status.State = cloudresourcesv1beta1.ErrorState
err = state.UpdateObjStatus(ctx)
Expand Down
27 changes: 27 additions & 0 deletions components/kcp/pkg/skr/nfs/crgcpnfsvolume/addFinalizer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package crgcpnfsvolume

import (
"context"
cloudresourcesv1beta1 "github.com/kyma-project/cloud-manager/components/kcp/api/cloud-resources/v1beta1"
"github.com/kyma-project/cloud-manager/components/lib/composed"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func addFinalizer(ctx context.Context, st composed.State) (error, context.Context) {
if composed.MarkedForDeletionPredicate(ctx, st) {
return nil, nil
}

added := controllerutil.AddFinalizer(st.Obj(), cloudresourcesv1beta1.Finalizer)
if !added {
// finalizer already added
return nil, nil
}

err := st.UpdateObj(ctx)
if err != nil {
return composed.LogErrorAndReturn(err, "Error saving object after finalizer added", composed.StopWithRequeue, nil)
}

return nil, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package crgcpnfsvolume

import (
"context"
"github.com/google/uuid"
cloudcontrolv1beta1 "github.com/kyma-project/cloud-manager/components/kcp/api/cloud-control/v1beta1"
cloudresourcesv1beta1 "github.com/kyma-project/cloud-manager/components/kcp/api/cloud-resources/v1beta1"
"github.com/kyma-project/cloud-manager/components/lib/composed"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func createKcpNfsInstance(ctx context.Context, st composed.State) (error, context.Context) {
state := st.(*State)
logger := composed.LoggerFromCtx(ctx)

if composed.MarkedForDeletionPredicate(ctx, st) {
// SKR GcpNfsVolume is marked for deletion, do not create mirror in KCP
return nil, nil
}

if state.KcpNfsInstance != nil {
// mirror NfsInstance in KCP is already created
return nil, nil
}

state.KcpNfsInstance = &cloudcontrolv1beta1.NfsInstance{
ObjectMeta: metav1.ObjectMeta{
Name: uuid.NewString(),
Namespace: state.KymaRef.Namespace,
Labels: map[string]string{
labelKymaName: state.KymaRef.Name,
labelRemoteName: state.Name().Name,
labelRemoteNamespace: state.Name().Namespace,
},
},
Spec: cloudcontrolv1beta1.NfsInstanceSpec{
Scope: cloudcontrolv1beta1.ScopeRef{
Name: state.KymaRef.Name,
},
RemoteRef: cloudcontrolv1beta1.RemoteRef{
Namespace: state.ObjAsGcpNfsVolume().Namespace,
Name: state.ObjAsGcpNfsVolume().Name,
},
IpRange: cloudcontrolv1beta1.IpRangeRef{
Name: state.ObjAsGcpNfsVolume().Spec.IpRange.Name,
},
Instance: cloudcontrolv1beta1.NfsInstanceInfo{
Gcp: &cloudcontrolv1beta1.NfsInstanceGcp{
Location: state.ObjAsGcpNfsVolume().Spec.Location,
Tier: cloudcontrolv1beta1.GcpFileTier(state.ObjAsGcpNfsVolume().Spec.Tier),
FileShareName: state.ObjAsGcpNfsVolume().Spec.FileShareName,
CapacityGb: state.ObjAsGcpNfsVolume().Spec.CapacityGb,
},
},
},
}

err := state.KcpCluster.K8sClient().Create(ctx, state.KcpNfsInstance)
if err != nil {
logger.Error(err, "Error creating KCP NfsInstance")
return composed.StopWithRequeue, nil
}
logger.
WithValues("kcpNfsInstanceName", state.KcpNfsInstance.Name).
Info("KCP NFS instance created")

return composed.UpdateStatus(state.ObjAsGcpNfsVolume()).
SetCondition(metav1.Condition{
Type: cloudresourcesv1beta1.ConditionTypeSubmitted,
Status: metav1.ConditionTrue,
Reason: cloudresourcesv1beta1.ConditionReasonSubmissionSucceeded,
Message: "Resource is submitted for provisioning",
}).
ErrorLogMessage("Error updating GcpNfsVolume status with submitted condition").
Run(ctx, state)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package crgcpnfsvolume

import (
"context"
"github.com/kyma-project/cloud-manager/components/lib/composed"
"time"
)

func deleteKcpNfsInstance(ctx context.Context, st composed.State) (error, context.Context) {
state := st.(*State)

if !composed.MarkedForDeletionPredicate(ctx, st) {
// SKR GcpNfsVolume is NOT marked for deletion, do not delete mirror in KCP
return nil, nil
}

if state.KcpNfsInstance == nil {
// SKR GcpNfsVolume is marked for deletion, but none found in KCP, probably already deleted
return nil, nil
}

err := state.KcpCluster.K8sClient().Delete(ctx, state.KcpNfsInstance)
if err != nil {
return composed.LogErrorAndReturn(err, "Error deleting KCP NfsInstance", composed.StopWithRequeue, nil)
}

// give some time to cloud-control and cloud providers to delete it, and then run again
return composed.StopWithRequeueDelay(3 * time.Second), nil
}
Loading
Loading