Skip to content

Commit

Permalink
Add user management
Browse files Browse the repository at this point in the history
With this commit the provider is able to manage users as well. The
users can't yet do anything as a user without any policy has no
permissions at all.
  • Loading branch information
Kidswiss committed Aug 30, 2023
1 parent 1fbe956 commit a359e98
Show file tree
Hide file tree
Showing 29 changed files with 2,032 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/package/*.xpkg
/package/crossplane.yaml
/kubeconfig
__debug*

# Docs
/.cache/
Expand Down
690 changes: 661 additions & 29 deletions LICENSE

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,12 @@ webhook_service_name = host.docker.internal

webhook-debug: $(webhook_cert) ## Creates certificates, patches the webhook registrations and applies everything to the given kube cluster
webhook-debug:
#
# kubectl -n syn-appcat scale deployment appcat-controller --replicas 0
# cabundle=$$(cat .work/webhook/tls.crt | base64) && \
# HOSTIP=$(webhook_service_name) && \
# kubectl annotate validatingwebhookconfigurations.admissionregistration.k8s.io appcat-pg-validation cert-manager.io/inject-ca-from- && \
# kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io appcat-pg-validation -oyaml | \
# yq e "del(.webhooks[0].clientConfig.service) | .webhooks[0].clientConfig.caBundle |= \"$$cabundle\" | .webhooks[0].clientConfig.url |= \"https://$$HOSTIP:9443/validate-vshn-appcat-vshn-io-v1-vshnpostgresql\"" - | \
# kubectl apply -f - && \
# kubectl annotate validatingwebhookconfigurations.admissionregistration.k8s.io appcat-redis-validation cert-manager.io/inject-ca-from- && \
# kubectl annotate validatingwebhookconfigurations.admissionregistration.k8s.io appcat-pg-validation kubectl.kubernetes.io/last-applied-configuration- && \
kubectl apply -f package/webhook
cabundle=$$(cat .work/webhook/tls.crt | base64) && \
HOSTIP=$(webhook_service_name) && \
kubectl annotate validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration cert-manager.io/inject-ca-from- && \
kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration -oyaml | \
yq e "del(.webhooks[0].clientConfig.service) | .webhooks[0].clientConfig.caBundle |= \"$$cabundle\" | .webhooks[0].clientConfig.url |= \"https://$$HOSTIP:9443//validate-minio-crossplane-io-v1-bucket\"" - | \
yq e "del(.webhooks[1].clientConfig.service) | .webhooks[1].clientConfig.caBundle |= \"$$cabundle\" | .webhooks[1].clientConfig.url |= \"https://$$HOSTIP:9443//validate-minio-crossplane-io-v1-user\"" - | \
kubectl apply -f - && \
kubectl annotate validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration kubectl.kubernetes.io/last-applied-configuration-
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ See all targets with `make help`
2. `make local-install`

### Kubernetes Webhook Troubleshooting
TODO: there are currently no webhooks configured.

The provider comes with mutating and validation admission webhook server.

To test and troubleshoot the webhooks on the cluster, simply apply your changes with `kubectl`.
Expand Down Expand Up @@ -79,8 +77,6 @@ To execute tests, run `make test-e2e` from the root dir.
If a test fails, kuttl leaves the resources in the kind-cluster intact, so you can inspect the resources and events if necessary.
Please note that Kubernetes Events from cluster-scoped resources appear in the `default` namespace only, but `kubectl describe ...` should show you the events.

If tests succeed, the relevant resources are deleted to not use up costs on the cloud providers.

### Cleaning up e2e tests

`make clean`
78 changes: 78 additions & 0 deletions apis/minio/v1/user_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package v1

import (
"reflect"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func init() {
SchemeBuilder.Register(&User{}, &UserList{})
}

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
// +kubebuilder:printcolumn:name="Synced",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
// +kubebuilder:printcolumn:name="External Name",type="string",JSONPath=".metadata.annotations.crossplane\\.io/external-name"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster,categories={crossplane,minio}
// +kubebuilder:webhook:verbs=create;update,path=/validate-minio-crossplane-io-v1-user,mutating=false,failurePolicy=fail,groups=minio.crossplane.io,resources=users,versions=v1,name=users.minio.crossplane.io,sideEffects=None,admissionReviewVersions=v1

type User struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec UserSpec `json:"spec"`
Status UserStatus `json:"status,omitempty"`
}

type UserSpec struct {
xpv1.ResourceSpec `json:",inline"`
ForProvider UserParameters `json:"forProvider,omitempty"`
}

type UserStatus struct {
xpv1.ResourceStatus `json:",inline"`
AtProvider UserProviderStatus `json:"atProvider,omitempty"`
}

type UserProviderStatus struct {
// UserName is populated it the user actually exists in minio during observe.
UserName string `json:"userName,omitempty"`
// Status indicates the user's status on the minio instance.
Status string `json:"status,omitempty"`
}

type UserParameters struct {
// UserName is the name of the user to create.
// Defaults to `metadata.name` if unset.
// Cannot be changed after user is created.
UserName string `json:"userName,omitempty"`
}

// +kubebuilder:object:root=true

type UserList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []User `json:"items"`
}

// GetUserName returns the spec.forProvider.userName if given, otherwise defaults to metadata.name.
func (in *User) GetUserName() string {
if in.Spec.ForProvider.UserName == "" {
return in.Name
}
return in.Spec.ForProvider.UserName
}

// Dummy type metadata.
var (
UserKind = reflect.TypeOf(User{}).Name()
UserGroupKind = schema.GroupKind{Group: Group, Kind: UserKind}.String()
UserKindAPIVersion = UserKind + "." + SchemeGroupVersion.String()
UserGroupVersionKind = SchemeGroupVersion.WithKind(UserKind)
)
123 changes: 123 additions & 0 deletions apis/minio/v1/zz_generated.deepcopy.go

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

76 changes: 76 additions & 0 deletions apis/minio/v1/zz_generated.managed.go

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

9 changes: 9 additions & 0 deletions apis/minio/v1/zz_generated.managedlist.go

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

27 changes: 27 additions & 0 deletions generate_sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func main() {
generateBucketSample()
generateProviderConfigSample()
generateSecretSample()
generateUserSample()
}

func generateBucketSample() {
Expand Down Expand Up @@ -110,6 +111,32 @@ func newSecretSample() *corev1.Secret {
}
}

func generateUserSample() {
spec := newUserSample()
serialize(spec, true)
}

func newUserSample() *miniov1.User {
return &miniov1.User{
TypeMeta: metav1.TypeMeta{
APIVersion: miniov1.UserGroupVersionKind.GroupVersion().String(),
Kind: miniov1.UserKind,
},
ObjectMeta: metav1.ObjectMeta{
Name: "devuser",
},
Spec: miniov1.UserSpec{
ResourceSpec: xpv1.ResourceSpec{
ProviderConfigReference: &xpv1.Reference{Name: "provider-config"},
WriteConnectionSecretToReference: &xpv1.SecretReference{
Name: "devuser",
Namespace: "default",
},
},
},
}
}

func failIfError(err error) {
if err != nil {
log.Fatal(err)
Expand Down
Loading

0 comments on commit a359e98

Please sign in to comment.