Skip to content

Commit

Permalink
Application Broker with one service
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmiskiewicz committed May 10, 2019
1 parent e1a20cc commit cbed107
Show file tree
Hide file tree
Showing 20 changed files with 533 additions and 462 deletions.
1 change: 1 addition & 0 deletions components/application-broker/Gopkg.lock

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

1 change: 1 addition & 0 deletions components/application-broker/README.md
Expand Up @@ -30,6 +30,7 @@ Before each commit, use the `before-commit.sh` script or the `make build` comman
|-----|---------|--------|------------|
|**APP_PORT** | NO | `8080` | The port on which the HTTP server listens |
|**APP_BROKER_RELIST_DURATION_WINDOW** | YES | - | Time period after which the AB synchronizes with the Service Catalog if a new Application is added. In case more than one Application is added, synchronization is performed only once. |
| **APP_SERVICE_NAME** | YES | - | The name of the Kubernetes Service, which exposes the broker API |
| **APP_UNIQUE_SELECTOR_LABEL_KEY** | YES | - | Defined label key selector which allows uniquely identify AB pod's |
| **APP_UNIQUE_SELECTOR_LABEL_VALUE** | YES | - | Defined label value selector which allows uniquely identify AB pod's |
| **NAMESPACE** | YES | - | AB working Namespace |
Expand Down
9 changes: 8 additions & 1 deletion components/application-broker/cmd/broker/main.go
Expand Up @@ -96,7 +96,7 @@ func main() {
brokerService, err := broker.NewNsBrokerService()
fatalOnError(err)

nsBrokerFacade := nsbroker.NewFacade(scClientSet.ServicecatalogV1beta1(), k8sClient.CoreV1(), brokerService, nsBrokerSyncer, cfg.Namespace, cfg.UniqueSelectorLabelKey, cfg.UniqueSelectorLabelValue, int32(cfg.Port), log)
nsBrokerFacade := nsbroker.NewFacade(scClientSet.ServicecatalogV1beta1(), k8sClient.CoreV1(), nsBrokerSyncer, cfg.Namespace, cfg.UniqueSelectorLabelKey, cfg.UniqueSelectorLabelValue, cfg.ServiceName, int32(cfg.Port), log)

mappingCtrl := mapping.New(mInformersGroup.ApplicationMappings().Informer(), nsInformer, k8sClient.CoreV1().Namespaces(), sFact.Application(), nsBrokerFacade, nsBrokerSyncer, log)

Expand All @@ -123,6 +123,13 @@ func main() {
mInformerFactory.WaitForCacheSync(stopCh)
cache.WaitForCacheSync(stopCh, nsInformer.HasSynced)

// migration old ServiceBrokers & Services setup
migrationService, err := nsbroker.NewMigrationService(k8sClient.CoreV1(), scClientSet.ServicecatalogV1beta1(), cfg.Namespace, cfg.ServiceName, log)
fatalOnError(err)
// The migration is done synchronously to prevent HTTP 404 when ServiceCatalog is doing a call via a legacy service.
// In such case the broker returns 404 which could mean the service instance does not exists - it could make a problem.
migrationService.Migrate()

// start services & ctrl
go appSyncCtrl.Run(stopCh)
go mappingCtrl.Run(stopCh)
Expand Down

This file was deleted.

Expand Up @@ -16,7 +16,6 @@ func TestBrokerModeGetNsFromURL(t *testing.T) {
// THEN
require.NoError(t, err)
assert.Equal(t, "stage", actNs)

}

func TestBrokerModeErrorOnGetNsFromURL(t *testing.T) {
Expand Down
Expand Up @@ -5,7 +5,7 @@ func NewConverter() appToServiceConverter {
return appToServiceConverter{}
}

func NewCatalogService(finder applicationFinder, appEnabledChecker appEnabledChecker, conv converter) *catalogService{
func NewCatalogService(finder applicationFinder, appEnabledChecker appEnabledChecker, conv converter) *catalogService {
return &catalogService{
finder: finder,
appEnabledChecker: appEnabledChecker,
Expand Down
27 changes: 3 additions & 24 deletions components/application-broker/internal/broker/middleware.go
Expand Up @@ -3,38 +3,17 @@ package broker
import (
"net/http"

"github.com/gorilla/mux"
osb "github.com/pmorie/go-open-service-broker-client/v2"
"github.com/sirupsen/logrus"
)

// OSBContextMiddleware implements Handler interface
// OSBContextMiddleware implements Handler interface, creates an osbContext instance from HTTP data and stores in the request context.
type OSBContextMiddleware struct {
brokerService brokerService
log logrus.FieldLogger
}

//go:generate mockery -name=brokerService -output=automock -outpkg=automock -case=underscore
type brokerService interface {
GetNsFromBrokerURL(url string) (string, error)
}

// NewOsbContextMiddleware created OsbContext middleware
func NewOsbContextMiddleware(brokerService brokerService, log logrus.FieldLogger) *OSBContextMiddleware {
return &OSBContextMiddleware{
brokerService: brokerService,
log: log.WithField("service", "OSBContextMiddleware"),
}
}

// ServeHTTP adds content of Open Service Broker Api headers to the requests
func (m *OSBContextMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
brokerNamespace, err := m.brokerService.GetNsFromBrokerURL(r.Host)
if err != nil {
errMsg := "misconfiguration, broker is running as a namespace-scoped, but cannot extract namespace from request"
m.log.Error(errMsg, err)
writeErrorResponse(rw, http.StatusInternalServerError, "OSBContextMiddlewareError", errMsg)
return
}
brokerNamespace := mux.Vars(r)["namespace"]

osbCtx := osbContext{
APIVersion: r.Header.Get(osb.APIVersionHeader),
Expand Down
37 changes: 4 additions & 33 deletions components/application-broker/internal/broker/middleware_test.go
@@ -1,28 +1,21 @@
package broker

import (
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/kyma-project/kyma/components/application-broker/internal/broker/automock"
"github.com/kyma-project/kyma/components/application-broker/platform/logger/spy"
"github.com/sirupsen/logrus"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

func TestOSBContextForNsScopedBroker(t *testing.T) {
// GIVEN
mockBrokerService := &automock.BrokerService{}
defer mockBrokerService.AssertExpectations(t)
url := "http://ab-ns-for-stage.kyma-system.svc.cluster.local/v2/catalog"
url := "http://ab-ns-for-stage.kyma-system.svc.cluster.local/stage/v2/catalog"

mockBrokerService.On("GetNsFromBrokerURL", "ab-ns-for-stage.kyma-system.svc.cluster.local").Return("stage", nil)

sut := NewOsbContextMiddleware(mockBrokerService, spy.NewLogDummy())
sut := &OSBContextMiddleware{}
req := httptest.NewRequest(http.MethodGet, url, nil)
req = mux.SetURLVars(req, map[string]string{"namespace": "stage"})
rw := httptest.NewRecorder()
nextCalled := false

Expand All @@ -38,25 +31,3 @@ func TestOSBContextForNsScopedBroker(t *testing.T) {
assert.True(t, nextCalled)

}

func TestOsbContextReturnsErrorWhenCannotExtractNamespace(t *testing.T) {
// GIVEN
mockBrokerService := &automock.BrokerService{}
defer mockBrokerService.AssertExpectations(t)

mockBrokerService.On("GetNsFromBrokerURL", mock.Anything).Return("", errors.New("some error"))
logSink := spy.NewLogSink()
sut := NewOsbContextMiddleware(mockBrokerService, logSink.Logger)
req := httptest.NewRequest(http.MethodGet, "https://core-ab.kyma-system.svc.cluster.local/v2/catalog", nil)
rw := httptest.NewRecorder()
nextCalled := false
// WHEN
sut.ServeHTTP(rw, req, func(nextRw http.ResponseWriter, nextReq *http.Request) {
// THEN
nextCalled = true
})
// THEN
assert.False(t, nextCalled)
assert.Equal(t, http.StatusInternalServerError, rw.Result().StatusCode)
logSink.AssertLogged(t, logrus.ErrorLevel, "misconfiguration, broker is running as a namespace-scoped, but cannot extract namespace from request")
}
18 changes: 10 additions & 8 deletions components/application-broker/internal/broker/server.go
Expand Up @@ -123,25 +123,27 @@ func (srv *Server) createHandler() http.Handler {
fmt.Fprint(w, "OK")
}).Methods("GET")

osbContextMiddleware := NewOsbContextMiddleware(srv.brokerService, srv.logger)
catalogRtr := rtr.PathPrefix("/{namespace}").Subrouter()

osbContextMiddleware := &OSBContextMiddleware{}
reqAsyncMiddleware := &RequireAsyncMiddleware{}
// sync operations

rtr.Path("/v2/catalog").Methods(http.MethodGet).Handler(
// sync operations
catalogRtr.Path("/v2/catalog").Methods(http.MethodGet).Handler(
negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.catalogAction)))

rtr.Path("/v2/service_instances/{instance_id}/last_operation").Methods(http.MethodGet).Handler(
catalogRtr.Path("/v2/service_instances/{instance_id}/last_operation").Methods(http.MethodGet).Handler(
negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.getServiceInstanceLastOperationAction)))

rtr.Path("/v2/service_instances/{instance_id}/service_bindings/{binding_id}").Methods(http.MethodPut).Handler(negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.bindAction)))
catalogRtr.Path("/v2/service_instances/{instance_id}/service_bindings/{binding_id}").Methods(http.MethodPut).Handler(negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.bindAction)))

rtr.Path("/v2/service_instances/{instance_id}/service_bindings/{binding_id}").Methods(http.MethodDelete).Handler(negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.unBindAction)))
catalogRtr.Path("/v2/service_instances/{instance_id}/service_bindings/{binding_id}").Methods(http.MethodDelete).Handler(negroni.New(osbContextMiddleware, negroni.WrapFunc(srv.unBindAction)))

// async operations
rtr.Path("/v2/service_instances/{instance_id}").Methods(http.MethodPut).Handler(
catalogRtr.Path("/v2/service_instances/{instance_id}").Methods(http.MethodPut).Handler(
negroni.New(reqAsyncMiddleware, osbContextMiddleware, negroni.WrapFunc(srv.provisionAction)),
)
rtr.Path("/v2/service_instances/{instance_id}").Methods(http.MethodDelete).Handler(
catalogRtr.Path("/v2/service_instances/{instance_id}").Methods(http.MethodDelete).Handler(
negroni.New(reqAsyncMiddleware, osbContextMiddleware, negroni.WrapFunc(srv.deprovisionAction)),
)

Expand Down
1 change: 1 addition & 0 deletions components/application-broker/internal/config/config.go
Expand Up @@ -33,6 +33,7 @@ type Config struct {
UniqueSelectorLabelKey string `valid:"required"`
UniqueSelectorLabelValue string `valid:"required"`
Namespace string `valid:"required"`
ServiceName string `valid:"required"`
}

// Load method has following strategy:
Expand Down
@@ -1,6 +1,6 @@
package mapping

func (c *Controller) WithMappingLister(svc mappingLister) *Controller{
func (c *Controller) WithMappingLister(svc mappingLister) *Controller {
c.mappingSvc = svc
return c
}
}

This file was deleted.

20 changes: 0 additions & 20 deletions components/application-broker/internal/nsbroker/export_test.go

This file was deleted.

0 comments on commit cbed107

Please sign in to comment.