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
2 changes: 1 addition & 1 deletion .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: "setup go"
uses: actions/setup-go@v4
with:
go-version: '^1.18.1'
go-version: '1.20'
- name: "shardingsphere operator test"
run: |
cd shardingsphere-operator
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: "setup go"
uses: actions/setup-go@v4
with:
go-version: '^1.18.1'
go-version: '1.20'
- name: "shardingsphere operator test"
run: |
cd shardingsphere-operator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ apiVersion: shardingsphere.apache.org/v1alpha1
kind: StorageProvider
metadata:
name: aws-aurora-cluster-mysql-5.7
annotations:
storageproviders.shardingsphere.apache.org/allowed-namespaces: default
spec:
provisioner: storageproviders.shardingsphere.apache.org/aws-aurora
reclaimPolicy: Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ apiVersion: shardingsphere.apache.org/v1alpha1
kind: StorageProvider
metadata:
name: aws-rds-cluster-mysql-8.0.32
annotations:
storageproviders.shardingsphere.apache.org/allowed-namespaces: default
spec:
provisioner: storageproviders.shardingsphere.apache.org/aws-rds-cluster
reclaimPolicy: Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ apiVersion: shardingsphere.apache.org/v1alpha1
kind: StorageProvider
metadata:
name: aws-rds-instance-mysql-5.7
annotations:
storageproviders.shardingsphere.apache.org/allowed-namespaces: default
spec:
provisioner: storageproviders.shardingsphere.apache.org/aws-rds-instance
reclaimPolicy: Delete
Expand Down
4 changes: 4 additions & 0 deletions shardingsphere-operator/.cache/go-build/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This directory holds cached build artifacts from the Go build system.
Run "go clean -cache" if the directory is getting too large.
Run "go clean -fuzzcache" to delete the fuzz cache.
See golang.org to learn more about Go.
3 changes: 2 additions & 1 deletion shardingsphere-operator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ CHECK_MOCKGEN ?= $(LOCALBIN)/mockgen
## Tool Versions
KUSTOMIZE_VERSION ?= v4.5.7
CONTROLLER_TOOLS_VERSION ?= v0.9.0
ENVTEST_SETUP_VERSION ?= release-0.14

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
Expand All @@ -136,7 +137,7 @@ $(CONTROLLER_GEN): $(LOCALBIN)
.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(ENVTEST_SETUP_VERSION)

.PHONY: lint
lint: check-lint
Expand Down
3 changes: 3 additions & 0 deletions shardingsphere-operator/api/v1alpha1/storageprovider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const (
AnnotationsMasterUsername = "storageproviders.shardingsphere.apache.org/master-username"
AnnotationsMasterUserPassword = "storageproviders.shardingsphere.apache.org/master-user-password"
AnnotationsFinalSnapshotIdentifier = "storageproviders.shardingsphere.apache.org/final-snapshot-identifier"
// AnnotationsAllowedNamespaces declares which namespaces are allowed to reference this cluster-scoped StorageProvider.
// Value is a comma-separated list, e.g. "default,tenant-a", or "*" to allow all namespaces.
AnnotationsAllowedNamespaces = "storageproviders.shardingsphere.apache.org/allowed-namespaces"

ProvisionerAWSRDSInstance = "storageproviders.shardingsphere.apache.org/aws-rds-instance"
ProvisionerAWSRDSCluster = "storageproviders.shardingsphere.apache.org/aws-rds-cluster"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ var _ = Describe("StorageNode Controller Mock Test For AWS Rds Instance", func()
// create default resource
dbClass := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: defaultTestStorageProvider,
Name: defaultTestStorageProvider,
Namespace: defaultTestNamespace,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: defaultTestNamespace,
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSRDSInstance,
Expand Down Expand Up @@ -131,7 +135,8 @@ var _ = Describe("StorageNode Controller Mock Test For AWS Rds Instance", func()
})).Should(Succeed())
Expect(fakeClient.Delete(ctx, &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: defaultTestStorageProvider,
Name: defaultTestStorageProvider,
Namespace: defaultTestNamespace,
},
})).Should(Succeed())

Expand Down Expand Up @@ -640,7 +645,11 @@ var _ = Describe("StorageNode Controller Mock Test For AWS Rds Instance", func()

storageProvider := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: defaultTestStorageProvider,
Name: defaultTestStorageProvider,
Namespace: defaultTestNamespace,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: defaultTestNamespace,
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSRDSInstance,
Expand Down Expand Up @@ -741,7 +750,11 @@ var _ = Describe("StorageNode Controller Mock Test For AWS Aurora", func() {
BeforeEach(func() {
provider = &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "aws-aurora",
Name: "aws-aurora",
Namespace: defaultTestNamespace,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: defaultTestNamespace,
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSAurora,
Expand Down Expand Up @@ -1191,7 +1204,11 @@ var _ = Describe("StorageNode Controller Mock Test For AWS RDS Cluster", func()
BeforeEach(func() {
provider = &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: providerName,
Name: providerName,
Namespace: defaultTestNamespace,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: defaultTestNamespace,
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSRDSCluster,
Expand Down Expand Up @@ -1635,3 +1652,56 @@ var _ = Describe("StorageNode Controller Mock Test For AWS RDS Cluster", func()
})
})
})

var _ = Describe("validateStorageProviderNamespace", func() {
It("should allow when namespace is in allow list", func() {
node := &v1alpha1.StorageNode{
ObjectMeta: metav1.ObjectMeta{
Namespace: "tenant-a",
},
}
provider := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "sp",
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: "tenant-a,tenant-b",
},
},
}
Expect(validateStorageProviderNamespace(node, provider)).To(Succeed())
})

It("should deny when namespace is not in allow list", func() {
node := &v1alpha1.StorageNode{
ObjectMeta: metav1.ObjectMeta{
Namespace: "tenant-c",
},
}
provider := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: "sp",
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: "tenant-a,tenant-b",
},
},
}
Expect(validateStorageProviderNamespace(node, provider)).To(HaveOccurred())
})
})

var _ = Describe("storageProviderObjectKey", func() {
It("should include storageProvider name and storagenode namespace", func() {
node := &v1alpha1.StorageNode{
ObjectMeta: metav1.ObjectMeta{
Namespace: "tenant-a",
},
Spec: v1alpha1.StorageNodeSpec{
StorageProviderName: "sp-a",
},
}

key := storageProviderObjectKey(node)
Expect(key.Name).To(Equal("sp-a"))
Expect(key.Namespace).To(Equal("tenant-a"))
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,16 @@ func (r *StorageNodeReconciler) getStorageProvider(ctx context.Context, node *v1

storageProvider = &v1alpha1.StorageProvider{}

if err := r.Get(ctx, client.ObjectKey{Name: node.Spec.StorageProviderName}, storageProvider); err != nil {
if err := r.Get(ctx, storageProviderObjectKey(node), storageProvider); err != nil {
r.Log.Error(err, fmt.Sprintf("unable to fetch storageProvider %s", node.Spec.StorageProviderName))
r.Recorder.Event(node, corev1.EventTypeWarning, "storageProviderNotFound", fmt.Sprintf("storageProvider %s not found", node.Spec.StorageProviderName))
return nil, err
}
if err := validateStorageProviderNamespace(node, storageProvider); err != nil {
r.Log.Error(err, fmt.Sprintf("storageProvider %s is not accessible from namespace %s", node.Spec.StorageProviderName, node.Namespace))
r.Recorder.Event(node, corev1.EventTypeWarning, "storageProviderNamespaceDenied", err.Error())
return nil, err
}

// check provisioner
// aws-like provisioner need aws rds client
Expand All @@ -269,6 +274,30 @@ func (r *StorageNodeReconciler) getStorageProvider(ctx context.Context, node *v1
return storageProvider, nil
}

func storageProviderObjectKey(node *v1alpha1.StorageNode) client.ObjectKey {
return client.ObjectKey{
Name: node.Spec.StorageProviderName,
Namespace: node.Namespace,
}
}

func validateStorageProviderNamespace(node *v1alpha1.StorageNode, storageProvider *v1alpha1.StorageProvider) error {
if storageProvider == nil {
return fmt.Errorf("storageProvider is nil")
}
allowedNamespaces, ok := storageProvider.Annotations[v1alpha1.AnnotationsAllowedNamespaces]
if !ok || strings.TrimSpace(allowedNamespaces) == "" {
return fmt.Errorf("storageProvider %s missing annotation %s", storageProvider.Name, v1alpha1.AnnotationsAllowedNamespaces)
}
for _, namespace := range strings.Split(allowedNamespaces, ",") {
namespace = strings.TrimSpace(namespace)
if namespace == "*" || namespace == node.Namespace {
return nil
}
}
return fmt.Errorf("namespace %s is not allowed to use storageProvider %s", node.Namespace, storageProvider.Name)
}

// nolint:gocritic
func computeDesiredState(status v1alpha1.StorageNodeStatus) v1alpha1.StorageNodeStatus {
// Initialize a new status object based on the current state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ var _ = Describe("StorageNode Controller Suite Test For AWS RDS Instance", func(
StorageProvider := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: storageProviderName,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: "default",
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSRDSInstance,
Expand Down Expand Up @@ -294,6 +297,9 @@ var _ = Describe("StorageNode Controller Suite Test For AWS Aurora Cluster", fun
provider := &v1alpha1.StorageProvider{
ObjectMeta: metav1.ObjectMeta{
Name: storageProviderName,
Annotations: map[string]string{
v1alpha1.AnnotationsAllowedNamespaces: "default",
},
},
Spec: v1alpha1.StorageProviderSpec{
Provisioner: v1alpha1.ProvisionerAWSAurora,
Expand Down
Loading