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

[feat] Add LinodeObjectStorageBucket #154

Merged
merged 33 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fbc884c
init new objectstoragebucket api
Feb 23, 2024
d28fbc5
add keyGeneration field for access key rotations
Feb 23, 2024
7ec10a5
define accessKeySecretName status field for eventual secret creation
Feb 23, 2024
8bc334e
implement create
Feb 26, 2024
f703696
WIP create bucket
Feb 26, 2024
c349836
create
Feb 26, 2024
0878781
add owner ref for secret
Feb 26, 2024
0499fd8
add finalizer
Feb 26, 2024
b9f3b8c
add hostname to status
Feb 26, 2024
60066cc
enable credentials ref from any namespace
Feb 27, 2024
f18950e
Merge branch 'main' into add-obj-storage-bucket
Feb 27, 2024
4a93b3f
dedupe access keys
Feb 27, 2024
36f51dd
fix dedupe access keys
Feb 27, 2024
fe0b237
restore finalizer
Feb 27, 2024
8312789
secret create/apply logic
Feb 28, 2024
8a10e53
all create/apply logic
Feb 29, 2024
558e423
update naming
Feb 29, 2024
202ba77
handle patching secret
Feb 29, 2024
8697f7d
update tests
Feb 29, 2024
c2b6a7b
[feat] Add deleteBucket logic for Linode OBJ (#145)
amold1 Feb 29, 2024
77494cf
add finalizer to secret
Feb 29, 2024
58db62d
always log object storage key revocation
Mar 1, 2024
3c0f5ed
Merge branch 'main' into add-obj-storage-bucket
Mar 1, 2024
f5ef7f5
move test files
Mar 1, 2024
ba38ade
use obj name for bucket label
Mar 1, 2024
751bffa
fix test suite
Mar 1, 2024
48fb2d1
remove controller test
Mar 1, 2024
1ffc897
tweak revocation logic
Mar 4, 2024
3c4e9f6
clean up logging
Mar 4, 2024
fd109f5
lint errors
Mar 4, 2024
0c45be9
start e2e with no bucket
Mar 4, 2024
8920834
remove tmp mock package
Mar 4, 2024
5a68342
address nits
Mar 4, 2024
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
9 changes: 9 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,13 @@ resources:
kind: LinodeMachineTemplate
path: github.com/linode/cluster-api-provider-linode/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: cluster.x-k8s.io
group: infrastructure
kind: LinodeObjectStorageBucket
path: github.com/linode/cluster-api-provider-linode/api/v1alpha1
version: v1alpha1
version: "3"
120 changes: 120 additions & 0 deletions api/v1alpha1/linodeobjectstoragebucket_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
Copyright 2023 Akamai Technologies, Inc.

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 v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// LinodeObjectStorageBucketSpec defines the desired state of LinodeObjectStorageBucket
type LinodeObjectStorageBucketSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Cluster is the ID of the Object Storage cluster for the bucket.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
Cluster string `json:"cluster"`

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

// KeyGeneration may be modified to trigger rotations of access keys created for the bucket.
// +optional
// +kubebuilder:default=0
KeyGeneration *int `json:"keyGeneration,omitempty"`
}

// LinodeObjectStorageBucketStatus defines the observed state of LinodeObjectStorageBucket
type LinodeObjectStorageBucketStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Ready denotes that the bucket has been provisioned along with access keys.
// +optional
// +kubebuilder:default=false
Ready bool `json:"ready"`

// FailureMessage will be set in the event that there is a terminal problem
// reconciling the Object Storage Bucket and will contain a verbose string
// suitable for logging and human consumption.
// +optional
FailureMessage *string `json:"failureMessage,omitempty"`

// Conditions specify the service state of the LinodeObjectStorageBucket.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`

// Hostname is the address assigned to the bucket.
// +optional
Hostname *string `json:"hostname,omitempty"`

// CreationTime specifies the creation timestamp for the bucket.
// +optional
CreationTime *metav1.Time `json:"creationTime,omitempty"`

// LastKeyGeneration tracks the last known value of .spec.keyGeneration.
// +optional
LastKeyGeneration *int `json:"lastKeyGeneration,omitempty"`

// KeySecretName specifies the name of the Secret containing access keys for the bucket.
// +optional
KeySecretName *string `json:"keySecretName,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=linodeobjectstoragebuckets,scope=Namespaced,shortName=lobj
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Label",type="string",JSONPath=".spec.label",description="The name of the bucket"
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".spec.cluster",description="The ID of the Object Storage cluster for the bucket"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Bucket and keys have been provisioned"

// LinodeObjectStorageBucket is the Schema for the linodeobjectstoragebuckets API
type LinodeObjectStorageBucket struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec LinodeObjectStorageBucketSpec `json:"spec,omitempty"`
Status LinodeObjectStorageBucketStatus `json:"status,omitempty"`
}

func (b *LinodeObjectStorageBucket) GetConditions() clusterv1.Conditions {
return b.Status.Conditions
}

func (b *LinodeObjectStorageBucket) SetConditions(conditions clusterv1.Conditions) {
b.Status.Conditions = conditions
}

//+kubebuilder:object:root=true

// LinodeObjectStorageBucketList contains a list of LinodeObjectStorageBucket
type LinodeObjectStorageBucketList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []LinodeObjectStorageBucket `json:"items"`
}

func init() {
SchemeBuilder.Register(&LinodeObjectStorageBucket{}, &LinodeObjectStorageBucketList{})
}
130 changes: 130 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.

25 changes: 24 additions & 1 deletion cloud/scope/common.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package scope

import (
"context"
"fmt"
"net/http"

"github.com/linode/cluster-api-provider-linode/version"
"github.com/linode/linodego"
"golang.org/x/oauth2"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/linode/cluster-api-provider-linode/version"
)

func createLinodeClient(apiKey string) *linodego.Client {
Expand All @@ -23,3 +27,22 @@ func createLinodeClient(apiKey string) *linodego.Client {

return &linodeClient
}

func getCredentialDataFromRef(ctx context.Context, crClient client.Client, credentialsRef *corev1.SecretReference) ([]byte, error) {
secretRefName := client.ObjectKey{
Name: credentialsRef.Name,
Namespace: credentialsRef.Namespace,
}

var credSecret corev1.Secret
if err := crClient.Get(ctx, secretRefName, &credSecret); err != nil {
return nil, fmt.Errorf("failed to retrieve configured credentials secret %s: %w", secretRefName.String(), err)
}

rawData, ok := credSecret.Data["apiToken"]
if !ok {
return nil, fmt.Errorf("credentials secret %s is missing an apiToken key", secretRefName.String())
}

return rawData, nil
}
Loading