Skip to content

Commit

Permalink
Merge pull request #99 from aerogear/AEROGEAR-2375-remove-need-for-la…
Browse files Browse the repository at this point in the history
…belling-service-instance

Aerogear 2375 remove need for labelling service instance
  • Loading branch information
maleck13 authored Apr 13, 2018
2 parents 80813ba + 2220733 commit 8b6de4c
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 51 deletions.
83 changes: 49 additions & 34 deletions pkg/cmd/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/aerogear/mobile-cli/pkg/cmd/output"
"github.com/olekukonko/tablewriter"
"github.com/pkg/errors"
"github.com/satori/go.uuid"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -102,6 +101,27 @@ func podPreset(objectName, secretName, providerSvcName, consumerSvcName string)
return &podPreset
}

func (bc *IntegrationCmd) getServiceNameFromServiceInst(si *v1beta1.ServiceInstance) (string, error) {
serviceClass, err := bc.
scClient.
ServicecatalogV1beta1().
ClusterServiceClasses().
Get(si.Spec.ClusterServiceClassRef.Name, metav1.GetOptions{})
if err != nil {
return "", errors.WithStack(err)
}
serviceMeta := map[string]interface{}{}
if err := json.Unmarshal(serviceClass.
Spec.
ExternalMetadata.
Raw, &serviceMeta); err != nil {
return "", errors.WithStack(err)
}
serviceName := serviceMeta["serviceName"].(string)
return serviceName, nil
}

// CreateIntegrationCmd will create a binding from the provider services and setup a pod preset for the consumer service
func (bc *IntegrationCmd) CreateIntegrationCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "integration <consuming_service_instance_id> <providing_service_instance_id>",
Expand Down Expand Up @@ -136,25 +156,30 @@ If both the --no-wait and --auto-redeploy flags are set to true, --auto-redeploy
if err != nil {
return errors.WithStack(err)
}
consumerSvc := getService(namespace, consumerSvcInst.Labels["serviceName"], bc.k8Client) // the consumer service
providerSvc := getService(namespace, providerSvcInst.Labels["serviceName"], bc.k8Client) // the provider service
consumerServiceName, err := bc.getServiceNameFromServiceInst(consumerSvcInst)
if err != nil {
return errors.WithStack(err)
}
providerServiceName, err := bc.getServiceNameFromServiceInst(providerSvcInst)
if err != nil {
return errors.WithStack(err)
}
//TODO review how we build the params
bindParams := buildBindParams(providerSvc, consumerSvc)
bindParams := buildBindParams(providerServiceName, consumerServiceName)
objectName := objectName(consumerSvcInstName, providerSvcInstName)
preset := podPreset(objectName, objectName, providerSvcInst.Labels["serviceName"], consumerSvcInst.Labels["serviceName"])
preset := podPreset(objectName, objectName, providerServiceName, consumerServiceName)
if _, err := bc.k8Client.SettingsV1alpha1().PodPresets(namespace).Create(preset); err != nil {
return errors.Wrap(err, "failed to create pod preset for service ")
}
// prepare and create our binding
binding, err := createBindingObject(consumerSvc.Name, providerSvc.Name, objectName, providerSvcInst.Name, bindParams, objectName)
binding, err := createBindingObject(consumerServiceName, providerServiceName, objectName, providerSvcInstName, bindParams, objectName)
if err != nil {
return errors.WithStack(err)
}
sb, err := bc.scClient.ServicecatalogV1beta1().ServiceBindings(namespace).Create(binding)
if err != nil {
return errors.WithStack(err)
}

// check if a redeploy was asked for
redeploy, err := cmd.PersistentFlags().GetBool("auto-redeploy")
if err != nil {
Expand Down Expand Up @@ -202,11 +227,11 @@ If both the --no-wait and --auto-redeploy flags are set to true, --auto-redeploy
if redeploy {

// update the deployment with an annotation
dep, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Get(consumerSvc.Name, metav1.GetOptions{})
dep, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Get(consumerServiceName, metav1.GetOptions{})
if err != nil {
return errors.Wrap(err, "failed to get deployment for service "+consumerSvcInstName)
}
dep.Spec.Template.Labels[providerSvc.Name] = "enabled"
dep.Spec.Template.Labels[providerServiceName] = "enabled"
if _, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Update(dep); err != nil {
return errors.Wrap(err, "failed to update deployment for service "+consumerSvcInstName)
}
Expand Down Expand Up @@ -246,17 +271,22 @@ oc plugin mobile delete integration <consuming_service_instance_id> <providing_s
}
consumerSvcInstName := args[0]
providerSvcInstName := args[1]

providerSvcInst, err := bc.scClient.ServicecatalogV1beta1().ServiceInstances(namespace).Get(providerSvcInstName, metav1.GetOptions{})
if err != nil {
return errors.WithStack(err)
}
consumerSvcInst, err := bc.scClient.ServicecatalogV1beta1().ServiceInstances(namespace).Get(consumerSvcInstName, metav1.GetOptions{})
if err != nil {
return errors.WithStack(err)
}
providerSvcInst, err := bc.scClient.ServicecatalogV1beta1().ServiceInstances(namespace).Get(providerSvcInstName, metav1.GetOptions{})
consumerServiceName, err := bc.getServiceNameFromServiceInst(consumerSvcInst)
if err != nil {
return errors.WithStack(err)
}
providerServiceName, err := bc.getServiceNameFromServiceInst(providerSvcInst)
if err != nil {
return errors.WithStack(err)
}
consumerSvcName := consumerSvcInst.Labels["serviceName"]
providerSvcName := providerSvcInst.Labels["serviceName"]
objectName := objectName(consumerSvcInstName, providerSvcInstName)
if err := bc.k8Client.SettingsV1alpha1().PodPresets(namespace).Delete(objectName, metav1.NewDeleteOptions(0)); err != nil {
return errors.WithStack(err)
Expand Down Expand Up @@ -314,11 +344,11 @@ oc plugin mobile delete integration <consuming_service_instance_id> <providing_s

if redeploy {
//update the deployment with an annotation
dep, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Get(consumerSvcName, metav1.GetOptions{})
dep, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Get(consumerServiceName, metav1.GetOptions{})
if err != nil {
return errors.Wrap(err, "service "+consumerSvcInstName)
}
delete(dep.Spec.Template.Labels, providerSvcName)
delete(dep.Spec.Template.Labels, providerServiceName)
if _, err := bc.k8Client.AppsV1beta1().Deployments(namespace).Update(dep); err != nil {
return errors.Wrap(err, "failed to update deployment for service "+consumerSvcInstName)
}
Expand Down Expand Up @@ -379,27 +409,12 @@ func (bc *IntegrationCmd) ListIntegrationsCmd() *cobra.Command {
return cmd
}

// TODO remove need for this by retrieving the params from the secret in the APB
func buildBindParams(from *Service, to *Service) map[string]interface{} {
// TODO review how we build params. This is still POC
func buildBindParams(from string, to string) map[string]interface{} {
var p = map[string]interface{}{}
p["credentials"] = map[string]string{
"route": from.Host,
"service_secret": to.ID,
}

for k, v := range from.Params {
p[k] = v
}
if from.Name == ServiceNameThreeScale {
p["apicast_route"] = from.Params["apicast_route"]
p["apicast_token"] = from.Params["token"]
p["apicast_service_id"] = from.Params["service_id"]
p["service_route"] = to.Host
p["service_name"] = to.Name
p["app_key"] = uuid.NewV4().String()
p["service_secret"] = to.ID
} else if from.Name == ServiceNameKeycloak {
p["service"] = to.Name
if from == ServiceNameKeycloak {
p["service"] = to
}
return p
}
121 changes: 115 additions & 6 deletions pkg/cmd/integration_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd_test

import (
"fmt"
"testing"

"bytes"
Expand Down Expand Up @@ -32,6 +33,8 @@ func TestIntegrationCmd_CreateIntegrationCmd(t *testing.T) {
},
}

fmt.Print(defaultServiceBinding)

cases := []struct {
Name string
SvcCatalogClient func() (versioned.Interface, *watch.FakeWatcher, []runtime.Object)
Expand Down Expand Up @@ -86,15 +89,34 @@ func TestIntegrationCmd_CreateIntegrationCmd(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "keycloak",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
return fake, fakeWatch, []runtime.Object{
defaultServiceBinding,
}
Expand Down Expand Up @@ -126,10 +148,21 @@ func TestIntegrationCmd_CreateIntegrationCmd(t *testing.T) {
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
Name: "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
return fake, fakeWatch, []runtime.Object{
defaultServiceBinding,
}
Expand Down Expand Up @@ -173,15 +206,34 @@ func TestIntegrationCmd_CreateIntegrationCmd(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "keycloak",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
return fake, fakeWatch, []runtime.Object{
defaultServiceBinding,
}
Expand Down Expand Up @@ -387,8 +439,13 @@ func TestIntegrationCmd_DeleteIntegrationCmd(t *testing.T) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
Labels: map[string]string{
"serviceName": "keycloak",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "keycloak",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
Expand All @@ -397,12 +454,20 @@ func TestIntegrationCmd_DeleteIntegrationCmd(t *testing.T) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "fh-sync-server",
Labels: map[string]string{
"serviceName": "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
fake.AddReactor("delete", "podpreset", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, nil
})
Expand Down Expand Up @@ -436,12 +501,37 @@ func TestIntegrationCmd_DeleteIntegrationCmd(t *testing.T) {
fakeWatch := watch.NewFake()
fake := &scFake.Clientset{}
fake.AddWatchReactor("servicebindings", ktesting.DefaultWatchReactor(fakeWatch, nil))

fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "keycloak",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
return fake, fakeWatch, []runtime.Object{
Expand Down Expand Up @@ -482,18 +572,37 @@ func TestIntegrationCmd_DeleteIntegrationCmd(t *testing.T) {
fake := &scFake.Clientset{}
fakeWatch := watch.NewFake()
fake.AddWatchReactor("servicebindings", ktesting.DefaultWatchReactor(fakeWatch, nil))
fake.AddReactor("get", "clusterserviceclasses", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ClusterServiceClass{Spec: v1beta1.ClusterServiceClassSpec{ExternalMetadata: &runtime.RawExtension{Raw: []byte(`{"serviceName":"test"}`)}}}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "keycloak",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "keycloak",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
fake.AddReactor("get", "serviceinstances", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
return true, &v1beta1.ServiceInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "fh-sync-server",
},
Spec: v1beta1.ServiceInstanceSpec{
PlanReference: v1beta1.PlanReference{
ClusterServiceClassExternalName: "fh-sync-server",
},
ClusterServiceClassRef: &v1beta1.ClusterObjectReference{
Name: "id",
},
},
}, nil
})
return fake, fakeWatch, []runtime.Object{
Expand Down
Loading

0 comments on commit 8b6de4c

Please sign in to comment.