Skip to content

Commit

Permalink
Create new folder for v7 brokerapi files
Browse files Browse the repository at this point in the history
[#169708392]
  • Loading branch information
FelisiaM committed Nov 13, 2019
1 parent 72e24db commit 3d253be
Show file tree
Hide file tree
Showing 35 changed files with 2,311 additions and 0 deletions.
17 changes: 17 additions & 0 deletions create_version_dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

set -e

version="${1:?"Usage: create_version_dir.sh <version>"}"

if [[ ! "$version" =~ ^v ]]; then
version="v$version"
fi

go_files=$(find . ! -path "*/vendor/*" ! -path "*/fakes/*" ! -path "*/tools/*" ! -path "*/v[0-9]*/*" ! -name "*_test.go" -name "*.go")
for f in $go_files ; do
mkdir -p "$version/$(dirname $f)"
cp $f $version/$(dirname $f)
done
cp go.mod "$version/"
go mod edit -module github.com/pivotal-cf/brokerapi/"$version" "$version"/go.mod
65 changes: 65 additions & 0 deletions v7/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (C) 2015-Present Pivotal Software, Inc. All rights reserved.

// This program and the accompanying materials are made available under
// the terms of the under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package brokerapi

import (
"net/http"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/v7/auth"
"github.com/pivotal-cf/brokerapi/v7/handlers"
"github.com/pivotal-cf/brokerapi/v7/middlewares"
)

type BrokerCredentials struct {
Username string
Password string
}

func New(serviceBroker ServiceBroker, logger lager.Logger, brokerCredentials BrokerCredentials) http.Handler {
router := mux.NewRouter()

AttachRoutes(router, serviceBroker, logger)

authMiddleware := auth.NewWrapper(brokerCredentials.Username, brokerCredentials.Password).Wrap
apiVersionMiddleware := middlewares.APIVersionMiddleware{LoggerFactory: logger}

router.Use(middlewares.AddCorrelationIDToContext)
router.Use(authMiddleware)
router.Use(middlewares.AddOriginatingIdentityToContext)
router.Use(apiVersionMiddleware.ValidateAPIVersionHdr)
router.Use(middlewares.AddInfoLocationToContext)

return router
}

func AttachRoutes(router *mux.Router, serviceBroker ServiceBroker, logger lager.Logger) {
apiHandler := handlers.NewApiHandler(serviceBroker, logger)
router.HandleFunc("/v2/catalog", apiHandler.Catalog).Methods("GET")

router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.GetInstance).Methods("GET")
router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Provision).Methods("PUT")
router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Deprovision).Methods("DELETE")
router.HandleFunc("/v2/service_instances/{instance_id}/last_operation", apiHandler.LastOperation).Methods("GET")
router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Update).Methods("PATCH")

router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}", apiHandler.GetBinding).Methods("GET")
router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}", apiHandler.Bind).Methods("PUT")
router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}", apiHandler.Unbind).Methods("DELETE")

router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation", apiHandler.LastBindingOperation).Methods("GET")
}
66 changes: 66 additions & 0 deletions v7/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2015-Present Pivotal Software, Inc. All rights reserved.

// This program and the accompanying materials are made available under
// the terms of the under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package auth

import (
"crypto/sha256"
"crypto/subtle"
"net/http"
)

type Wrapper struct {
username []byte
password []byte
}

func NewWrapper(username, password string) *Wrapper {
u := sha256.Sum256([]byte(username))
p := sha256.Sum256([]byte(password))
return &Wrapper{username: u[:], password: p[:]}
}

const notAuthorized = "Not Authorized"

func (wrapper *Wrapper) Wrap(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !authorized(wrapper, r) {
http.Error(w, notAuthorized, http.StatusUnauthorized)
return
}

handler.ServeHTTP(w, r)
})
}

func (wrapper *Wrapper) WrapFunc(handlerFunc http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !authorized(wrapper, r) {
http.Error(w, notAuthorized, http.StatusUnauthorized)
return
}

handlerFunc(w, r)
})
}

func authorized(wrapper *Wrapper, r *http.Request) bool {
username, password, isOk := r.BasicAuth()
u := sha256.Sum256([]byte(username))
p := sha256.Sum256([]byte(password))
return isOk &&
subtle.ConstantTimeCompare(wrapper.username, u[:]) == 1 &&
subtle.ConstantTimeCompare(wrapper.password, p[:]) == 1
}
77 changes: 77 additions & 0 deletions v7/catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (C) 2015-Present Pivotal Software, Inc. All rights reserved.

// This program and the accompanying materials are made available under
// the terms of the under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package brokerapi

import (
"reflect"

"github.com/pivotal-cf/brokerapi/v7/domain"
)

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type Service = domain.Service

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServiceDashboardClient = domain.ServiceDashboardClient

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServicePlan = domain.ServicePlan

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServiceSchemas = domain.ServiceSchemas

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServiceInstanceSchema = domain.ServiceInstanceSchema

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServiceBindingSchema = domain.ServiceBindingSchema

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type Schema = domain.Schema

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServicePlanMetadata = domain.ServicePlanMetadata

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServicePlanCost = domain.ServicePlanCost

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type ServiceMetadata = domain.ServiceMetadata

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
func FreeValue(v bool) *bool {
return domain.FreeValue(v)
}

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
func BindableValue(v bool) *bool {
return domain.BindableValue(v)
}

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
type RequiredPermission = domain.RequiredPermission

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
const (
PermissionRouteForwarding = domain.PermissionRouteForwarding
PermissionSyslogDrain = domain.PermissionSyslogDrain
PermissionVolumeMount = domain.PermissionVolumeMount
)

//Deprecated: Use github.com/pivotal-cf/brokerapi/domain
func GetJsonNames(s reflect.Value) (res []string) {
return domain.GetJsonNames(s)
}
23 changes: 23 additions & 0 deletions v7/context_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package brokerapi

import (
"context"

"github.com/pivotal-cf/brokerapi/v7/utils"
)

func AddServiceToContext(ctx context.Context, service *Service) context.Context {
return utils.AddServiceToContext(ctx, service)
}

func RetrieveServiceFromContext(ctx context.Context) *Service {
return utils.RetrieveServiceFromContext(ctx)
}

func AddServicePlanToContext(ctx context.Context, plan *ServicePlan) context.Context {
return utils.AddServicePlanToContext(ctx, plan)
}

func RetrieveServicePlanFromContext(ctx context.Context) *ServicePlan {
return utils.RetrieveServicePlanFromContext(ctx)
}
94 changes: 94 additions & 0 deletions v7/domain/apiresponses/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package apiresponses

import (
"errors"
"net/http"
)

const (
instanceExistsMsg = "instance already exists"
instanceDoesntExistMsg = "instance does not exist"
serviceLimitReachedMsg = "instance limit for this service has been reached"
servicePlanQuotaExceededMsg = "The quota for this service plan has been exceeded. Please contact your Operator for help."
serviceQuotaExceededMsg = "The quota for this service has been exceeded. Please contact your Operator for help."
bindingExistsMsg = "binding already exists"
bindingDoesntExistMsg = "binding does not exist"
bindingNotFoundMsg = "binding cannot be fetched"
asyncRequiredMsg = "This service plan requires client support for asynchronous service operations."
planChangeUnsupportedMsg = "The requested plan migration cannot be performed"
rawInvalidParamsMsg = "The format of the parameters is not valid JSON"
appGuidMissingMsg = "app_guid is a required field but was not provided"
concurrentInstanceAccessMsg = "instance is being updated and cannot be retrieved"
maintenanceInfoConflictMsg = "passed maintenance_info does not match the catalog maintenance_info"
maintenanceInfoNilConflictMsg = "maintenance_info was passed, but the broker catalog contains no maintenance_info"

instanceLimitReachedErrorKey = "instance-limit-reached"
instanceAlreadyExistsErrorKey = "instance-already-exists"
bindingAlreadyExistsErrorKey = "binding-already-exists"
instanceMissingErrorKey = "instance-missing"
bindingMissingErrorKey = "binding-missing"
bindingNotFoundErrorKey = "binding-not-found"
asyncRequiredKey = "async-required"
planChangeNotSupportedKey = "plan-change-not-supported"
invalidRawParamsKey = "invalid-raw-params"
appGuidNotProvidedErrorKey = "app-guid-not-provided"
concurrentAccessKey = "get-instance-during-update"
maintenanceInfoConflictKey = "maintenance-info-conflict"
)

var (
ErrInstanceAlreadyExists = NewFailureResponseBuilder(
errors.New(instanceExistsMsg), http.StatusConflict, instanceAlreadyExistsErrorKey,
).WithEmptyResponse().Build()

ErrInstanceDoesNotExist = NewFailureResponseBuilder(
errors.New(instanceDoesntExistMsg), http.StatusGone, instanceMissingErrorKey,
).WithEmptyResponse().Build()

ErrInstanceLimitMet = NewFailureResponse(
errors.New(serviceLimitReachedMsg), http.StatusInternalServerError, instanceLimitReachedErrorKey,
)

ErrBindingAlreadyExists = NewFailureResponse(
errors.New(bindingExistsMsg), http.StatusConflict, bindingAlreadyExistsErrorKey,
)

ErrBindingDoesNotExist = NewFailureResponseBuilder(
errors.New(bindingDoesntExistMsg), http.StatusGone, bindingMissingErrorKey,
).WithEmptyResponse().Build()

ErrBindingNotFound = NewFailureResponseBuilder(
errors.New(bindingNotFoundMsg), http.StatusNotFound, bindingNotFoundErrorKey,
).WithEmptyResponse().Build()

ErrAsyncRequired = NewFailureResponseBuilder(
errors.New(asyncRequiredMsg), http.StatusUnprocessableEntity, asyncRequiredKey,
).WithErrorKey("AsyncRequired").Build()

ErrPlanChangeNotSupported = NewFailureResponseBuilder(
errors.New(planChangeUnsupportedMsg), http.StatusUnprocessableEntity, planChangeNotSupportedKey,
).WithErrorKey("PlanChangeNotSupported").Build()

ErrRawParamsInvalid = NewFailureResponse(
errors.New(rawInvalidParamsMsg), http.StatusUnprocessableEntity, invalidRawParamsKey,
)

ErrAppGuidNotProvided = NewFailureResponse(
errors.New(appGuidMissingMsg), http.StatusUnprocessableEntity, appGuidNotProvidedErrorKey,
)

ErrPlanQuotaExceeded = errors.New(servicePlanQuotaExceededMsg)
ErrServiceQuotaExceeded = errors.New(serviceQuotaExceededMsg)

ErrConcurrentInstanceAccess = NewFailureResponseBuilder(
errors.New(concurrentInstanceAccessMsg), http.StatusUnprocessableEntity, concurrentAccessKey,
).WithErrorKey("ConcurrencyError").Build()

ErrMaintenanceInfoConflict = NewFailureResponseBuilder(
errors.New(maintenanceInfoConflictMsg), http.StatusUnprocessableEntity, maintenanceInfoConflictKey,
).WithErrorKey("MaintenanceInfoConflict").Build()

ErrMaintenanceInfoNilConflict = NewFailureResponseBuilder(
errors.New(maintenanceInfoNilConflictMsg), http.StatusUnprocessableEntity, maintenanceInfoConflictKey,
).WithErrorKey("MaintenanceInfoConflict").Build()
)
Loading

0 comments on commit 3d253be

Please sign in to comment.