Skip to content
This repository has been archived by the owner on Nov 15, 2018. It is now read-only.

[WIP] Create shared service plan when keycloak is provisioned #14

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 26 additions & 6 deletions pkg/apis/aerogear/v1alpha1/shared.go
Expand Up @@ -88,10 +88,28 @@ type SharedServicePlan struct {
}

type SharedServicePlanSpec struct {
ServiceType string `json:"serviceType"`
InstanceParams *runtime.RawExtension `json:"instanceParams"`
BindParams *runtime.RawExtension `json:"bindParams"`
ServiceType string `json:"serviceType"`
Name string `json:"name"`
ID string `json:"id"`
Description string `json:"description"`
Free bool `json:"free"`
BindParams SharedServicePlanSpecParams `json:"bindParams"`
ProvisionParams SharedServicePlanSpecParams `json:"provisionParams"`
}

type SharedServicePlanSpecParams struct {
Schema string `json:"$schema"`
Type string `json:"type"`
Properties map[string]SharedServicePlanSpecParamsProperty `json:"properties"`
}

type SharedServicePlanSpecParamsProperty struct {
Type string `json:"type"`
Required bool `json:"required"`
Description string `json:"description"`
Title string `json:"title"`
}

type SharedServicePlanStatus struct {
CommonStatus
}
Expand Down Expand Up @@ -139,7 +157,9 @@ type StatusSharedConfig struct {
type SharedServiceStatusPhase string

const (
SSPhaseNone = ""
SSPhaseAccepted SharedServiceStatusPhase = "accepted"
SSPhaseComplete SharedServiceStatusPhase = "complete"
SSPhaseNone = ""
SSPhaseAccepted SharedServiceStatusPhase = "accepted"
SSPhaseComplete SharedServiceStatusPhase = "complete"
SSPhaseProvisioning SharedServiceStatusPhase = "provisioning"
SSPhaseProvisioned SharedServiceStatusPhase = "provisioned"
)
1 change: 1 addition & 0 deletions pkg/apis/aerogear/v1alpha1/types.go
Expand Up @@ -89,6 +89,7 @@ var (
PhaseFailed StatusPhase = "failed"
PhaseModified StatusPhase = "modified"
PhaseProvisioning StatusPhase = "provisioning"
PhaseProvisioned StatusPhase = "provisioned"
PhaseDeprovisioning StatusPhase = "deprovisioning"
PhaseDeprovisioned StatusPhase = "deprovisioned"
PhaseDeprovisionFailed StatusPhase = "deprovisionFailed"
Expand Down
51 changes: 41 additions & 10 deletions pkg/apis/aerogear/v1alpha1/zz_generated.deepcopy.go

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

42 changes: 41 additions & 1 deletion pkg/keycloak/keycloak.go
Expand Up @@ -171,11 +171,14 @@ func (h *Handler) Handle(ctx context.Context, event sdk.Event) error {

siCondition := si.Status.Conditions[0]
if siCondition.Type == "Ready" && siCondition.Status == "True" {
kcCopy.Status.Phase = v1alpha1.PhaseComplete
kcCopy.Status.Phase = v1alpha1.PhaseProvisioned
kcCopy.Status.Ready = true
}
}

case v1alpha1.PhaseProvisioned:
return h.createSharedServicePlan(kcCopy, namespace)

case v1alpha1.PhaseComplete:
return h.reconcileResources(kcCopy)

Expand Down Expand Up @@ -366,6 +369,43 @@ func (sh *Handler) finalizeKeycloak(kc *v1alpha1.Keycloak) error {
return nil
}

func (h *Handler) createSharedServicePlan(kc *v1alpha1.Keycloak, namespace string) error {
sharedServiceList := v1alpha1.SharedServiceList{
TypeMeta: metav1.TypeMeta{
Kind: "SharedService",
APIVersion: "aerogear.org/v1alpha1",
},
}

err := sdk.List(namespace, &sharedServiceList, sdk.WithListOptions(&metav1.ListOptions{}))
if err != nil {
logrus.Errorf("Failed to list shared services: %v\n", err)
return err
}

for _, sharedService := range sharedServiceList.Items {
if sharedService.Spec.ServiceType == KEYCLOAK_SERVICE_NAME && sharedService.Status.Phase == v1alpha1.SSPhaseProvisioning {
ssCopy := sharedService.DeepCopy()
ssCopy.Status.Phase = v1alpha1.SSPhaseProvisioned
if err := sdk.Update(ssCopy); err != nil {
logrus.Errorf("Failed to update the shared service resource: %v\n", err)
return err
}
}
}

kc.Status.Phase = v1alpha1.PhaseComplete
return h.updateKeycloakResource(kc)
}

func (h *Handler) updateKeycloakResource(kc *v1alpha1.Keycloak) error {
if err := sdk.Update(kc); err != nil {
logrus.Errorf("Failed to update the keycloak resource: %v\n", err)
return err
}
return nil
}

func (h *Handler) GVK() schema.GroupVersionKind {
return schema.GroupVersionKind{
Version: v1alpha1.Version,
Expand Down
101 changes: 99 additions & 2 deletions pkg/shared/service.go
Expand Up @@ -43,6 +43,8 @@ func (sh *ServiceHandler) Handle(ctx context.Context, event sdk.Event) error {
sh.initSharedService(sharedServiceCopy)
case v1alpha1.SSPhaseAccepted:
sh.createKeycloaks(sharedServiceCopy)
case v1alpha1.SSPhaseProvisioned:
sh.createSharedServicePlan(sharedServiceCopy)
}

return nil
Expand Down Expand Up @@ -78,8 +80,7 @@ func (sh *ServiceHandler) createKeycloaks(sharedService *v1alpha1.SharedService)
return err
}
} else {
sharedService.Status.Ready = true
sharedService.Status.Phase = v1alpha1.SSPhaseComplete
sharedService.Status.Phase = v1alpha1.SSPhaseProvisioning
err := sdk.Update(sharedService)
if err != nil {
logrus.Errorf("error updating resource status: %v", err)
Expand Down Expand Up @@ -156,6 +157,102 @@ func (sh *ServiceHandler) finalizeSharedService(sharedService *v1alpha1.SharedSe
return nil
}

func (sh *ServiceHandler) createSharedServicePlan(sharedService *v1alpha1.SharedService) error {
sharedService.Status.Phase = v1alpha1.SSPhaseComplete
sharedService.Status.Ready = true

sharedServicePlanList := v1alpha1.SharedServicePlanList{
TypeMeta: metav1.TypeMeta{
Kind: "SharedServicePlan",
APIVersion: "aerogear.org/v1alpha1",
},
}

err := sdk.List(sharedService.Namespace, &sharedServicePlanList, sdk.WithListOptions(&metav1.ListOptions{}))
if err != nil {
logrus.Errorf("Failed to list shared service plans: %v\n", err)
return err
}

for _, sharedServicePlan := range sharedServicePlanList.Items {
if sharedServicePlan.Spec.ServiceType == sharedService.Spec.ServiceType {
logrus.Infof("Shared service plan for %s already exists.", sharedServicePlan.Spec.ServiceType)
return sh.updateSharedServiceResource(sharedService)
}
}

sharedServicePlan := sh.buildSharedServicePlan(sharedService)
if err := sdk.Create(sharedServicePlan); err != nil {
logrus.Errorf("Failed to create a shared service plan: %v\n", err)
return err
}

return sh.updateSharedServiceResource(sharedService)
}

func (sh *ServiceHandler) buildSharedServicePlan(sharedService *v1alpha1.SharedService) *v1alpha1.SharedServicePlan {
serviceName := sharedService.Spec.ServiceType
schema := "http://json-schema.org/draft-04/schema#"
bindParams := &v1alpha1.SharedServicePlanSpecParams{
Schema: schema,
Type: "object",
Properties: map[string]v1alpha1.SharedServicePlanSpecParamsProperty{
"Username": v1alpha1.SharedServicePlanSpecParamsProperty{
Type: "string",
Required: true,
Description: "The Keycloak admin username.",
Title: "Username",
},
"ClientType": v1alpha1.SharedServicePlanSpecParamsProperty{
Type: "string",
Required: false,
Description: "The Keycloak client type.",
Title: "Client Type",
},
},
}
provisionParams := &v1alpha1.SharedServicePlanSpecParams{
Schema: schema,
Type: "object",
Properties: map[string]v1alpha1.SharedServicePlanSpecParamsProperty{
"CUSTOM_REALM_NAME": v1alpha1.SharedServicePlanSpecParamsProperty{
Type: "string",
Required: false,
Description: "The name of the realm to create in Keycloak (defaults to your namespace).",
Title: "Realm Name",
},
},
}

return &v1alpha1.SharedServicePlan{
TypeMeta: metav1.TypeMeta{
APIVersion: "aerogear.org/v1alpha1",
Kind: "SharedServicePlan",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: sharedService.Namespace,
Name: serviceName + "-slice-plan",
},
Spec: v1alpha1.SharedServicePlanSpec{
ServiceType: serviceName,
Name: serviceName + " Slice",
ID: serviceName + "-default-slice",
Description: "Slice of a shared Keycloak Service",
Free: true,
BindParams: *bindParams,
ProvisionParams: *provisionParams,
},
}
}

func (sh *ServiceHandler) updateSharedServiceResource(sharedService *v1alpha1.SharedService) error {
if err := sdk.Update(sharedService); err != nil {
logrus.Errorf("Error updating shared service resource: %v\n", err)
return err
}
return nil
}

func (sh *ServiceHandler) GVK() schema.GroupVersionKind {
return schema.GroupVersionKind{
Kind: v1alpha1.SharedServiceKind,
Expand Down