Skip to content

Commit

Permalink
feat: multi-tenancy for LinodeVPCs
Browse files Browse the repository at this point in the history
Adds a new (optional) field (CredentialsRef) to the Spec for LinodeVPCs. This references
a Secret that contains Linode credentials that will override the ones supplied by the
controller.
  • Loading branch information
cbang-akamai committed Feb 27, 2024
1 parent 6c9d03a commit 60779f6
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 70 deletions.
6 changes: 6 additions & 0 deletions api/v1alpha1/linodevpc_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)
Expand All @@ -41,6 +42,11 @@ type LinodeVPCSpec struct {
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
// +optional
Subnets []VPCSubnetCreateOptions `json:"subnets,omitempty"`

// CredentialsRef is a reference to a Secret that contains the credentials to use for provisioning this VPC. If not
// supplied then the credentials of the controller will be used.
// +optional
CredentialsRef *corev1.SecretReference `json:"credentialsRef,omitempty"`
}

// VPCSubnetCreateOptions defines subnet options
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

10 changes: 9 additions & 1 deletion cloud/scope/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,19 @@ func validateVPCScopeParams(params VPCScopeParams) error {

// NewVPCScope creates a new Scope from the supplied parameters.
// This is meant to be called for each reconcile iteration.
func NewVPCScope(apiKey string, params VPCScopeParams) (*VPCScope, error) {
func NewVPCScope(ctx context.Context, apiKey string, params VPCScopeParams) (*VPCScope, error) {
if err := validateVPCScopeParams(params); err != nil {
return nil, err
}

// Override the controller credentials with ones from the VPC's Secret reference (if supplied).
if params.LinodeVPC.Spec.CredentialsRef != nil {
data, err := getCredentialDataFromRef(ctx, params.Client, params.LinodeVPC.Spec.CredentialsRef)
if err != nil {
return nil, fmt.Errorf("credentials from secret ref: %w", err)
}
apiKey = string(data)
}
linodeClient := createLinodeClient(apiKey)

helper, err := patch.NewHelper(params.LinodeVPC, params.Client)
Expand Down
136 changes: 67 additions & 69 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_linodevpcs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.13.0
name: linodevpcs.infrastructure.cluster.x-k8s.io
spec:
group: infrastructure.cluster.x-k8s.io
Expand All @@ -20,25 +20,35 @@ spec:
description: LinodeVPC is the Schema for the linodemachines API
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.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
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. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
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.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
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. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: LinodeVPCSpec defines the desired state of LinodeVPC
properties:
credentialsRef:
description: CredentialsRef is a reference to a Secret that contains
the credentials to use for provisioning this VPC. If not supplied
then the credentials of the controller will be used.
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
x-kubernetes-map-type: atomic
description:
type: string
label:
Expand Down Expand Up @@ -83,37 +93,37 @@ spec:
operational state.
properties:
lastTransitionTime:
description: |-
Last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when
the API field changed is acceptable.
description: Last time the condition transitioned from one status
to another. This should be when the underlying condition changed.
If that is not known, then using the time when the API field
changed is acceptable.
format: date-time
type: string
message:
description: |-
A human readable message indicating details about the transition.
This field may be empty.
description: A human readable message indicating details about
the transition. This field may be empty.
type: string
reason:
description: |-
The reason for the condition's last transition in CamelCase.
The specific API may choose whether or not this field is considered a guaranteed API.
This field may not be empty.
description: The reason for the condition's last transition
in CamelCase. The specific API may choose whether or not this
field is considered a guaranteed API. This field may not be
empty.
type: string
severity:
description: |-
Severity provides an explicit classification of Reason code, so the users or machines can immediately
understand the current situation and act accordingly.
The Severity field MUST be set only when Status=False.
description: Severity provides an explicit classification of
Reason code, so the users or machines can immediately understand
the current situation and act accordingly. The Severity field
MUST be set only when Status=False.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: |-
Type of condition in CamelCase or in foo.example.com/CamelCase.
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions
can be useful (see .node.status.conditions), the ability to deconflict is important.
description: Type of condition in CamelCase or in foo.example.com/CamelCase.
Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important.
type: string
required:
- lastTransitionTime
Expand All @@ -122,46 +132,34 @@ spec:
type: object
type: array
failureMessage:
description: |-
FailureMessage will be set in the event that there is a terminal problem
reconciling the VPC and will contain a more verbose string suitable
for logging and human consumption.
This field should not be set for transitive errors that a controller
faces that are expected to be fixed automatically over
time (like service outages), but instead indicate that something is
fundamentally wrong with the VPC's spec or the configuration of
the controller, and that manual intervention is required. Examples
of terminal errors would be invalid combinations of settings in the
spec, values that are unsupported by the controller, or the
responsible controller itself being critically misconfigured.
Any transient errors that occur during the reconciliation of VPCs
can be added as events to the VPC object and/or logged in the
controller's output.
description: "FailureMessage will be set in the event that there is
a terminal problem reconciling the VPC and will contain a more verbose
string suitable for logging and human consumption. \n This field
should not be set for transitive errors that a controller faces
that are expected to be fixed automatically over time (like service
outages), but instead indicate that something is fundamentally wrong
with the VPC's spec or the configuration of the controller, and
that manual intervention is required. Examples of terminal errors
would be invalid combinations of settings in the spec, values that
are unsupported by the controller, or the responsible controller
itself being critically misconfigured. \n Any transient errors that
occur during the reconciliation of VPCs can be added as events to
the VPC object and/or logged in the controller's output."
type: string
failureReason:
description: |-
FailureReason will be set in the event that there is a terminal problem
reconciling the VPC and will contain a succinct value suitable
for machine interpretation.
This field should not be set for transitive errors that a controller
faces that are expected to be fixed automatically over
time (like service outages), but instead indicate that something is
fundamentally wrong with the VPC's spec or the configuration of
the controller, and that manual intervention is required. Examples
of terminal errors would be invalid combinations of settings in the
spec, values that are unsupported by the controller, or the
responsible controller itself being critically misconfigured.
Any transient errors that occur during the reconciliation of VPCs
can be added as events to the VPC object and/or logged in the
controller's output.
description: "FailureReason will be set in the event that there is
a terminal problem reconciling the VPC and will contain a succinct
value suitable for machine interpretation. \n This field should
not be set for transitive errors that a controller faces that are
expected to be fixed automatically over time (like service outages),
but instead indicate that something is fundamentally wrong with
the VPC's spec or the configuration of the controller, and that
manual intervention is required. Examples of terminal errors would
be invalid combinations of settings in the spec, values that are
unsupported by the controller, or the responsible controller itself
being critically misconfigured. \n Any transient errors that occur
during the reconciliation of VPCs can be added as events to the
VPC object and/or logged in the controller's output."
type: string
ready:
default: false
Expand Down
1 change: 1 addition & 0 deletions controller/linodevpc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (r *LinodeVPCReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}

vpcScope, err := scope.NewVPCScope(
ctx,
r.LinodeApiKey,
scope.VPCScopeParams{
Client: r.Client,
Expand Down

0 comments on commit 60779f6

Please sign in to comment.