### Compare import statements Source: https://github.com/cloudfoundry/brokerapi/wiki/Releasing-new-BrokerAPI-major-version Example of the import path change required in Go source files. ```go import ( "github.com/pivotal-cf/brokerapi/v8" ) ``` ```go import ( "github.com/pivotal-cf/brokerapi/v9" ) ``` -------------------------------- ### Configure Multiple User Authentication in Go Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Configure the auth wrapper with multiple allowed credentials for basic authentication. This setup is useful for brokers requiring different user roles. ```go package main import ( "log/slog" "net/http" "os" "code.cloudfoundry.org/brokerapi/v13" "code.cloudfoundry.org/brokerapi/v13/auth" ) func main() { broker := &MyServiceBroker{} logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) // Create auth wrapper with multiple users authWrapper := auth.NewWrapperMultiple(map[string]string{ "admin": "admin-password", "operator": "operator-password", "readonly": "readonly-password", }) handler := brokerapi.NewWithOptions( broker, logger, brokerapi.WithCustomAuth(authWrapper.Wrap), ) http.ListenAndServe(":8080", handler) } ``` -------------------------------- ### Create Service Broker Handler with Custom Options Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Utilize `brokerapi.NewWithOptions()` for advanced configuration, including the ability to add custom middleware. This function allows for more flexible setup beyond basic authentication. ```go package main import ( "log/slog" "net/http" "os" "code.cloudfoundry.org/brokerapi/v13" ) func main() { broker := &MyServiceBroker{} logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) handler := brokerapi.NewWithOptions( broker, logger, brokerapi.WithBrokerCredentials(brokerapi.BrokerCredentials{ Username: "admin", Password: "secret", }), brokerapi.WithAdditionalMiddleware(loggingMiddleware), ) http.ListenAndServe(":8080", handler) } func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { slog.Info("request", "method", r.Method, "path", r.URL.Path) next.ServeHTTP(w, r) }) } ``` -------------------------------- ### Get Binding Details Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Fetches existing service binding details. Returns ErrBindingNotFound if the binding does not exist. ```go func (b *MyServiceBroker) GetBinding(ctx context.Context, instanceID, bindingID string, details domain.FetchBindingDetails) (domain.GetBindingSpec, error) { if _, exists := b.bindings[bindingID]; !exists { return domain.GetBindingSpec{}, apiresponses.ErrBindingNotFound } return domain.GetBindingSpec{ Credentials: map[string]interface{}{ "host": "db.example.com", "port": 5432, "username": "user-" + bindingID[:8], "password": "generated-password", }, }, }, nil } ``` -------------------------------- ### GET /v2/catalog Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Retrieves the service catalog from the broker. ```APIDOC ## GET /v2/catalog ### Description Retrieves the service catalog from the broker. ### Method GET ### Endpoint /v2/catalog ``` -------------------------------- ### GET /v2/catalog Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Retrieves the catalog of services offered by the broker. ```APIDOC ## GET /v2/catalog ### Description Returns the list of services and plans offered by this service broker. ### Method GET ### Endpoint /v2/catalog ### Response #### Success Response (200) - **services** (array) - List of service offerings available. ``` -------------------------------- ### Open Service Broker API v2 Endpoints Reference Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Reference for common Open Service Broker API v2 endpoints using curl. These examples demonstrate how to interact with a service broker for various operations. ```bash # Get service catalog curl -X GET http://localhost:8080/v2/catalog \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` ```bash # Provision a service instance curl -X PUT "http://localhost:8080/v2/service_instances/instance-123?accepts_incomplete=true" \ -H "X-Broker-API-Version: 2.14" \ -H "Content-Type: application/json" \ -u admin:secret \ -d '{ "service_id": "service-guid", "plan_id": "plan-guid", "organization_guid": "org-guid", "space_guid": "space-guid", "parameters": {"region": "us-east-1"} }' ``` ```bash # Get service instance curl -X GET "http://localhost:8080/v2/service_instances/instance-123" \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` ```bash # Update service instance curl -X PATCH "http://localhost:8080/v2/service_instances/instance-123?accepts_incomplete=true" \ -H "X-Broker-API-Version: 2.14" \ -H "Content-Type: application/json" \ -u admin:secret \ -d '{ "service_id": "service-guid", "plan_id": "new-plan-guid" }' ``` ```bash # Poll last operation status curl -X GET "http://localhost:8080/v2/service_instances/instance-123/last_operation?operation=provision-123" \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` ```bash # Deprovision service instance curl -X DELETE "http://localhost:8080/v2/service_instances/instance-123?service_id=service-guid&plan_id=plan-guid&accepts_incomplete=true" \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` ```bash # Create service binding curl -X PUT "http://localhost:8080/v2/service_instances/instance-123/service_bindings/binding-456" \ -H "X-Broker-API-Version: 2.14" \ -H "Content-Type: application/json" \ -u admin:secret \ -d '{ "service_id": "service-guid", "plan_id": "plan-guid", "bind_resource": {"app_guid": "app-guid"} }' ``` ```bash # Get service binding curl -X GET "http://localhost:8080/v2/service_instances/instance-123/service_bindings/binding-456" \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` ```bash # Delete service binding curl -X DELETE "http://localhost:8080/v2/service_instances/instance-123/service_bindings/binding-456?service_id=service-guid&plan_id=plan-guid" \ -H "X-Broker-API-Version: 2.14" \ -u admin:secret ``` -------------------------------- ### Implement Asynchronous Provisioning Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Handles asynchronous service provisioning by returning IsAsync: true and implementing LastOperation for polling. Requires asyncAllowed to be true. ```go func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { if !asyncAllowed { return domain.ProvisionedServiceSpec{}, apiresponses.ErrAsyncRequired } // Start async provisioning in background go b.provisionAsync(instanceID, details) return domain.ProvisionedServiceSpec{ IsAsync: true, OperationData: "provision-" + instanceID, DashboardURL: "https://dashboard.example.com/" + instanceID, }, }, nil } ``` ```go func (b *MyServiceBroker) LastOperation(ctx context.Context, instanceID string, details domain.PollDetails) (domain.LastOperation, error) { // Check operation status based on details.OperationData status := b.getOperationStatus(instanceID, details.OperationData) switch status { case "pending": return domain.LastOperation{ State: domain.InProgress, Description: "Provisioning in progress", }, nil case "completed": return domain.LastOperation{ State: domain.Succeeded, Description: "Provisioning completed", }, nil default: return domain.LastOperation{ State: domain.Failed, Description: "Provisioning failed", }, nil } } ``` -------------------------------- ### Implement ServiceBroker Interface in Go Source: https://context7.com/cloudfoundry/brokerapi/llms.txt A complete implementation of the ServiceBroker interface, including catalog, provisioning, binding, and lifecycle management methods. ```go package main import ( "context" "errors" "code.cloudfoundry.org/brokerapi/v13/domain" "code.cloudfoundry.org/brokerapi/v13/domain/apiresponses" ) type MyServiceBroker struct { instances map[string]domain.ProvisionDetails bindings map[string]domain.BindDetails } func NewBroker() *MyServiceBroker { return &MyServiceBroker{ instances: make(map[string]domain.ProvisionDetails), bindings: make(map[string]domain.BindDetails), } } // Services returns the catalog of services offered by this broker // GET /v2/catalog func (b *MyServiceBroker) Services(ctx context.Context) ([]domain.Service, error) { return []domain.Service{ { ID: "service-guid-here", Name: "my-service", Description: "My custom service", Bindable: true, PlanUpdatable: true, Plans: []domain.ServicePlan{ { ID: "plan-guid-here", Name: "standard", Description: "Standard plan", Free: domain.FreeValue(true), }, }, Metadata: &domain.ServiceMetadata{ DisplayName: "My Service", DocumentationUrl: "https://docs.example.com", }, Tags: []string{"database", "nosql"}, }, }, nil } // Provision creates a new service instance // PUT /v2/service_instances/{instance_id} func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { if _, exists := b.instances[instanceID]; exists { return domain.ProvisionedServiceSpec{}, apiresponses.ErrInstanceAlreadyExists } b.instances[instanceID] = details return domain.ProvisionedServiceSpec{ IsAsync: false, DashboardURL: "https://dashboard.example.com/" + instanceID, }, nil } // Deprovision deletes an existing service instance // DELETE /v2/service_instances/{instance_id} func (b *MyServiceBroker) Deprovision(ctx context.Context, instanceID string, details domain.DeprovisionDetails, asyncAllowed bool) (domain.DeprovisionServiceSpec, error) { if _, exists := b.instances[instanceID]; !exists { return domain.DeprovisionServiceSpec{}, apiresponses.ErrInstanceDoesNotExist } delete(b.instances, instanceID) return domain.DeprovisionServiceSpec{IsAsync: false}, nil } // GetInstance fetches information about a service instance // GET /v2/service_instances/{instance_id} func (b *MyServiceBroker) GetInstance(ctx context.Context, instanceID string, details domain.FetchInstanceDetails) (domain.GetInstanceDetailsSpec, error) { instance, exists := b.instances[instanceID] if !exists { return domain.GetInstanceDetailsSpec{}, apiresponses.ErrInstanceNotFound } return domain.GetInstanceDetailsSpec{ ServiceID: instance.ServiceID, PlanID: instance.PlanID, DashboardURL: "https://dashboard.example.com/" + instanceID, }, nil } // Update modifies an existing service instance // PATCH /v2/service_instances/{instance_id} func (b *MyServiceBroker) Update(ctx context.Context, instanceID string, details domain.UpdateDetails, asyncAllowed bool) (domain.UpdateServiceSpec, error) { if _, exists := b.instances[instanceID]; !exists { return domain.UpdateServiceSpec{}, apiresponses.ErrInstanceDoesNotExist } return domain.UpdateServiceSpec{ IsAsync: false, DashboardURL: "https://dashboard.example.com/" + instanceID, }, nil } // LastOperation fetches last operation state for a service instance // GET /v2/service_instances/{instance_id}/last_operation func (b *MyServiceBroker) LastOperation(ctx context.Context, instanceID string, details domain.PollDetails) (domain.LastOperation, error) { return domain.LastOperation{ State: domain.Succeeded, Description: "Operation completed successfully", }, nil } // Bind creates a new service binding // PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id} func (b *MyServiceBroker) Bind(ctx context.Context, instanceID, bindingID string, details domain.BindDetails, asyncAllowed bool) (domain.Binding, error) { if _, exists := b.instances[instanceID]; !exists { return domain.Binding{}, apiresponses.ErrInstanceDoesNotExist } b.bindings[bindingID] = details return domain.Binding{ Credentials: map[string]interface{}{ "host": "db.example.com", "port": 5432, "username": "user-" + bindingID[:8], "password": "generated-password", "uri": "postgres://user:pass@db.example.com:5432/mydb", }, }, nil } // Unbind deletes an existing service binding // DELETE /v2/service_instances/{instance_id}/service_bindings/{binding_id} func (b *MyServiceBroker) Unbind(ctx context.Context, instanceID, bindingID string, details domain.UnbindDetails, asyncAllowed bool) (domain.UnbindSpec, error) { if _, exists := b.bindings[bindingID]; !exists { return domain.UnbindSpec{}, apiresponses.ErrBindingDoesNotExist } ``` -------------------------------- ### PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Creates a new service binding. ```APIDOC ## PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Description Creates a binding between an application and a service instance. ### Method PUT ### Endpoint /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The unique identifier for the service instance. - **binding_id** (string) - Required - The unique identifier for the service binding. ### Response #### Success Response (200) - **credentials** (object) - The credentials required to access the service instance. ``` -------------------------------- ### Git workflow for contributions Source: https://github.com/cloudfoundry/brokerapi/blob/main/CONTRIBUTING.md Standard commands for setting up a remote, creating a feature branch, and pushing changes to a fork. ```shell git remote add upstream https://github.com/vmware/@(project).git git checkout -b my-new-feature main git commit -a git push origin my-new-feature ``` -------------------------------- ### PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Creates a service binding for a service instance. ```APIDOC ## PUT /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Description Creates a service binding. ### Method PUT ### Endpoint /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance. - **binding_id** (string) - Required - The ID of the binding. #### Request Body - **service_id** (string) - Required - The ID of the service. - **plan_id** (string) - Required - The ID of the plan. - **bind_resource** (object) - Required - Resource information for the binding. ``` -------------------------------- ### Create Service Broker Handler with Basic Auth Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Use `brokerapi.New()` to create an http.Handler for your ServiceBroker implementation with basic authentication. Ensure the provided credentials match the expected username and password. ```go package main import ( "context" "log/slog" "net/http" "os" "code.cloudfoundry.org/brokerapi/v13" "code.cloudfoundry.org/brokerapi/v13/domain" ) type MyServiceBroker struct{} func main() { broker := &MyServiceBroker{} logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) credentials := brokerapi.BrokerCredentials{ Username: "admin", Password: "secret", } handler := brokerapi.New(broker, logger, credentials) http.ListenAndServe(":8080", handler) } ``` -------------------------------- ### PUT /v2/service_instances/{instance_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Creates a new service instance. ```APIDOC ## PUT /v2/service_instances/{instance_id} ### Description Provisions a new service instance for the specified instance ID. ### Method PUT ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The unique identifier for the service instance. ### Response #### Success Response (200) - **is_async** (boolean) - Indicates if the operation is asynchronous. - **dashboard_url** (string) - URL for the service dashboard. ``` -------------------------------- ### Retrieve Service from Context in Go Source: https://github.com/cloudfoundry/brokerapi/blob/main/README.md Demonstrates how to retrieve service details from the request context within a ServiceBroker implementation. Ensure the service ID and plan ID are validated and attached to the context. ```go func (sb *ServiceBrokerImplementation) Provision(ctx context.Context, instanceID string, details brokerapi.ProvisionDetails, asyncAllowed bool) { service := brokerapi.RetrieveServiceFromContext(ctx) if service == nil { // Lookup service } // [..] } ``` -------------------------------- ### Define Service Catalog with Schemas in Go Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Defines a service catalog including detailed JSON schemas for instance and binding parameters. Use this to validate user inputs during service provisioning and binding. ```go package main import ( "context" "code.cloudfoundry.org/brokerapi/v13/domain" ) func (b *MyServiceBroker) Services(ctx context.Context) ([]domain.Service, error) { return []domain.Service{ { ID: "database-service-id", Name: "my-database", Description: "Managed database service", Bindable: true, InstancesRetrievable: true, BindingsRetrievable: true, PlanUpdatable: true, AllowContextUpdates: true, Plans: []domain.ServicePlan{ { ID: "standard-plan-id", Name: "standard", Description: "Standard database plan", Free: domain.FreeValue(false), Bindable: domain.BindableValue(true), Metadata: &domain.ServicePlanMetadata{ DisplayName: "Standard", Bullets: []string{"5GB Storage", "100 connections"}, Costs: []domain.ServicePlanCost{ { Amount: map[string]float64{"usd": 99.0}, Unit: "MONTHLY", }, }, }, Schemas: &domain.ServiceSchemas{ Instance: domain.ServiceInstanceSchema{ Create: domain.Schema{ Parameters: map[string]any{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": map[string]any{ "region": map[string]any{ "type": "string", "description": "Cloud region for deployment", "enum": []string{"us-east-1", "eu-west-1", "ap-south-1"}, }, "storage_gb": map[string]any{ "type": "integer", "description": "Storage size in GB", "minimum": 5, "maximum": 100, }, }, "required": []string{"region"}, }, }, Update: domain.Schema{ Parameters: map[string]any{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": map[string]any{ "storage_gb": map[string]any{ "type": "integer", "minimum": 5, "maximum": 500, }, }, }, }, }, Binding: domain.ServiceBindingSchema{ Create: domain.Schema{ Parameters: map[string]any{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": map[string]any{ "role": map[string]any{ "type": "string", "enum": []string{"read", "write", "admin"}, }, }, }, }, }, }, MaintenanceInfo: &domain.MaintenanceInfo{ Version: "1.2.0", Description: "Database engine update", }, }, }, Requires: []domain.RequiredPermission{ domain.PermissionSyslogDrain, }, Metadata: &domain.ServiceMetadata{ DisplayName: "My Database", ImageUrl: "https://example.com/icon.png", LongDescription: "A fully managed database service with automatic backups and high availability.", ProviderDisplayName: "My Company", DocumentationUrl: "https://docs.example.com/database", SupportUrl: "https://support.example.com", }, DashboardClient: &domain.ServiceDashboardClient{ ID: "dashboard-client-id", Secret: "dashboard-secret", RedirectURI: "https://dashboard.example.com/oauth/callback", }, Tags: []string{"database", "postgresql", "managed"}, }, }, nil } ``` -------------------------------- ### Create Service Broker Handler with Custom Authentication Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Implement custom authentication logic using `brokerapi.NewWithCustomAuth()` or the `WithCustomAuth` option. This is useful for integrating with token-based or other non-standard authentication schemes. ```go package main import ( "log/slog" "net/http" "os" "code.cloudfoundry.org/brokerapi/v13" ) func main() { broker := &MyServiceBroker{} logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) handler := brokerapi.NewWithCustomAuth(broker, logger, tokenAuthMiddleware) http.ListenAndServe(":8080", handler) } func tokenAuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") if token != "Bearer my-secret-token" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } next.ServeHTTP(w, r) }) } ``` -------------------------------- ### PUT /v2/service_instances/{instance_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Provisions a new service instance. ```APIDOC ## PUT /v2/service_instances/{instance_id} ### Description Provisions a service instance. ### Method PUT ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance to provision. #### Query Parameters - **accepts_incomplete** (boolean) - Optional - Allows asynchronous provisioning. #### Request Body - **service_id** (string) - Required - The ID of the service. - **plan_id** (string) - Required - The ID of the plan. - **organization_guid** (string) - Required - The GUID of the organization. - **space_guid** (string) - Required - The GUID of the space. - **parameters** (object) - Optional - Service-specific parameters. ``` -------------------------------- ### Return Binding with Volume Mounts in Go Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Returns binding information including volume mount details for services that provide shared storage. This is used when a service instance needs to expose persistent storage to an application. ```go package main import ( "context" "code.cloudfoundry.org/brokerapi/v13/domain" ) func (b *MyServiceBroker) Bind(ctx context.Context, instanceID, bindingID string, details domain.BindDetails, asyncAllowed bool) (domain.Binding, error) { return domain.Binding{ Credentials: map[string]interface{}{ "mount_path": "/var/data", }, VolumeMounts: []domain.VolumeMount{ { Driver: "nfs", ContainerDir: "/var/data", Mode: "rw", DeviceType: "shared", Device: domain.SharedDevice{ VolumeId: "volume-" + instanceID, MountConfig: map[string]any{ "source": "nfs://storage.example.com/exports/" + instanceID, "options": "vers=4.1", }, }, }, }, }, nil } ``` -------------------------------- ### Retrieve Service and Plan from Request Context Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Utilize context utility functions to access validated service and plan information during provisioning. The BrokerAPI validates service and plan IDs and attaches them to the context for easy retrieval. ```go package main import ( "context" "code.cloudfoundry.org/brokerapi/v13" "code.cloudfoundry.org/brokerapi/v13/domain" ) func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { // BrokerAPI validates service_id and plan_id and attaches them to context service := brokerapi.RetrieveServiceFromContext(ctx) if service != nil { // Access validated service information serviceName := service.Name isBindable := service.Bindable _ = serviceName _ = isBindable } plan := brokerapi.RetrieveServicePlanFromContext(ctx) if plan != nil { // Access validated plan information planName := plan.Name isFree := plan.Free _ = planName _ = isFree } return domain.ProvisionedServiceSpec{}, nil } ``` -------------------------------- ### Upgrade imports using mod tool Source: https://github.com/cloudfoundry/brokerapi/wiki/Releasing-new-BrokerAPI-major-version Use the mod tool to automatically update import paths from v8 to v9. ```bash mod upgrade --mod-name=github.com/pivotal-cf/brokerapi/v8 ``` -------------------------------- ### Access Raw Parameters and Context in BrokerAPI Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Access raw JSON parameters and context from incoming requests using the provided domain types. This allows for parsing custom parameters and Cloud Foundry context information directly from the request details. ```go package main import ( "context" "encoding/json" "code.cloudfoundry.org/brokerapi/v13/domain" ) type ProvisionParams struct { Region string `json:"region"` Size string `json:"size"` Replicas int `json:"replicas"` } type CloudFoundryContext struct { OrganizationGUID string `json:"organization_guid"` SpaceGUID string `json:"space_guid"` OrganizationName string `json:"organization_name"` SpaceName string `json:"space_name"` } func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { // Parse custom parameters from RawParameters var params ProvisionParams if len(details.RawParameters) > 0 { if err := json.Unmarshal(details.RawParameters, ¶ms); err != nil { return domain.ProvisionedServiceSpec{}, err } } // Parse Cloud Foundry context from RawContext var cfContext CloudFoundryContext if len(details.RawContext) > 0 { if err := json.Unmarshal(details.RawContext, &cfContext); err != nil { return domain.ProvisionedServiceSpec{}, err } } // Use organization_guid and space_guid directly from details orgGUID := details.OrganizationGUID spaceGUID := details.SpaceGUID _ = params _ = cfContext _ = orgGUID _ = spaceGUID return domain.ProvisionedServiceSpec{}, nil } ``` -------------------------------- ### Update dependencies in consuming repositories Source: https://github.com/cloudfoundry/brokerapi/wiki/Releasing-new-BrokerAPI-major-version Commands to update the BrokerAPI version and clean up dependencies in dependent projects. ```bash ## This will add the new version to `go.mod` > go get github.com/pivotal-cf/brokerapi/v9@v9.0.0 ## If needed > go mod vendor ## This will update all import statement to refer to v9 rather than v8 > mod upgrade --mod-name=github.com/pivotal-cf/brokerapi/v8 ## This should remove the previous version from `go.mod` > go mod tidy ``` -------------------------------- ### Update go.mod module version Source: https://github.com/cloudfoundry/brokerapi/wiki/Releasing-new-BrokerAPI-major-version Update the module path in go.mod to reflect the new major version. ```go module github.com/pivotal-cf/brokerapi/v9 ``` -------------------------------- ### DELETE /v2/service_instances/{instance_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Deletes an existing service instance. ```APIDOC ## DELETE /v2/service_instances/{instance_id} ### Description Deprovisions and removes an existing service instance. ### Method DELETE ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The unique identifier for the service instance. ``` -------------------------------- ### Custom Error Responses Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Implementing custom HTTP error responses for provisioning operations. ```APIDOC ## POST /v2/service_instances/{instance_id} ### Description Provisions a service instance and returns custom error responses for specific conditions. ### Method POST ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance to provision. #### Request Body - **service_id** (string) - Required - The ID of the service offering. - **plan_id** (string) - Required - The ID of the plan for the service. - **parameters** (object) - Optional - Arbitrary parameters for provisioning. ### Response #### Error Responses - **400 Bad Request** - Returned for invalid parameters, e.g., invalid region. Includes an error message and an error key. - **403 Forbidden** - Returned when a quota is exceeded. Includes an error message, an error key, and a specific error key in the response body. - **503 Service Unavailable** - Returned when the service is in maintenance mode. Includes an error message and an error key, with an empty response body. #### Response Example (400 Bad Request) ```json { "description": "invalid region specified", "error_code": "invalid-region" } ``` #### Response Example (403 Forbidden) ```json { "description": "quota exceeded for this plan", "error_code": "quota-exceeded", "error_key": "QuotaExceeded" } ``` #### Response Example (503 Service Unavailable) ```json { "description": "service is in maintenance mode", "error_code": "maintenance-mode" } ``` ``` -------------------------------- ### PATCH /v2/service_instances/{instance_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Updates an existing service instance. ```APIDOC ## PATCH /v2/service_instances/{instance_id} ### Description Updates an existing service instance. ### Method PATCH ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance to update. #### Query Parameters - **accepts_incomplete** (boolean) - Optional - Allows asynchronous updates. #### Request Body - **service_id** (string) - Required - The ID of the service. - **plan_id** (string) - Required - The ID of the new plan. ``` -------------------------------- ### Asynchronous Operations Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Implementing asynchronous operations for provisioning and handling polling for operation status. ```APIDOC ## POST /v2/service_instances/{instance_id} ### Description Provisions a new service instance asynchronously. ### Method POST ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance to provision. #### Request Body - **service_id** (string) - Required - The ID of the service offering. - **plan_id** (string) - Required - The ID of the plan for the service. - **organization_guid** (string) - Required - The GUID of the organization. - **space_guid** (string) - Required - The GUID of the space. ### Response #### Success Response (200 or 202) - **IsAsync** (bool) - Indicates if the operation is asynchronous. - **OperationData** (string) - Data to be passed to the LastOperation endpoint. - **DashboardURL** (string) - URL for the service dashboard. #### Response Example ```json { "is_async": true, "operation_data": "provision-instance-123", "dashboard_url": "https://dashboard.example.com/instance-123" } ``` ``` ```APIDOC ## GET /v2/service_instances/{instance_id}/last_operation ### Description Fetches the status of the last operation for a service instance. ### Method GET ### Endpoint /v2/service_instances/{instance_id}/last_operation ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance. #### Query Parameters - **operation** (string) - Optional - The operation data returned from the Provision endpoint. ### Response #### Success Response (200) - **State** (domain.LastOperationState) - The state of the operation (e.g., Succeeded, Failed, InProgress). - **Description** (string) - A description of the operation's status. #### Response Example ```json { "state": "in progress", "description": "Provisioning in progress" } ``` ``` -------------------------------- ### DELETE /v2/service_instances/{instance_id} Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Deprovisions a service instance. ```APIDOC ## DELETE /v2/service_instances/{instance_id} ### Description Deprovisions a service instance. ### Method DELETE ### Endpoint /v2/service_instances/{instance_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance to deprovision. #### Query Parameters - **service_id** (string) - Required - The ID of the service. - **plan_id** (string) - Required - The ID of the plan. - **accepts_incomplete** (boolean) - Optional - Allows asynchronous deprovisioning. ``` -------------------------------- ### Handle Pre-defined Errors in BrokerAPI Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Use pre-defined error types from the apiresponses package to return appropriate HTTP status codes as per the OSB specification. These errors handle common scenarios like instance or binding conflicts, non-existence, or limit issues. ```go package main import ( "context" "code.cloudfoundry.org/brokerapi/v13/domain" "code.cloudfoundry.org/brokerapi/v13/domain/apiresponses" ) func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { // Instance already exists - returns 409 Conflict return domain.ProvisionedServiceSpec{}, apiresponses.ErrInstanceAlreadyExists } func (b *MyServiceBroker) Deprovision(ctx context.Context, instanceID string, details domain.DeprovisionDetails, asyncAllowed bool) (domain.DeprovisionServiceSpec, error) { // Instance does not exist - returns 410 Gone return domain.DeprovisionServiceSpec{}, apiresponses.ErrInstanceDoesNotExist } func (b *MyServiceBroker) GetInstance(ctx context.Context, instanceID string, details domain.FetchInstanceDetails) (domain.GetInstanceDetailsSpec, error) { // Instance not found - returns 404 Not Found return domain.GetInstanceDetailsSpec{}, apiresponses.ErrInstanceNotFound } func (b *MyServiceBroker) Bind(ctx context.Context, instanceID, bindingID string, details domain.BindDetails, asyncAllowed bool) (domain.Binding, error) { // Binding already exists - returns 409 Conflict return domain.Binding{}, apiresponses.ErrBindingAlreadyExists } func (b *MyServiceBroker) Unbind(ctx context.Context, instanceID, bindingID string, details domain.UnbindDetails, asyncAllowed bool) (domain.UnbindSpec, error) { // Binding does not exist - returns 410 Gone return domain.UnbindSpec{}, apiresponses.ErrBindingDoesNotExist } // Other pre-defined errors: // apiresponses.ErrInstanceLimitMet - 500 Internal Server Error // apiresponses.ErrAsyncRequired - 422 Unprocessable Entity (AsyncRequired) // apiresponses.ErrPlanChangeNotSupported - 422 Unprocessable Entity (PlanChangeNotSupported) // apiresponses.ErrConcurrentInstanceAccess - 422 Unprocessable Entity (ConcurrencyError) // apiresponses.ErrMaintenanceInfoConflict - 422 Unprocessable Entity (MaintenanceInfoConflict) ``` -------------------------------- ### Last Binding Operation Status Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Fetches the last operation state for a service binding. Assumes the operation has already completed successfully. ```go func (b *MyServiceBroker) LastBindingOperation(ctx context.Context, instanceID, bindingID string, details domain.PollDetails) (domain.LastOperation, error) { return domain.LastOperation{ State: domain.Succeeded, Description: "Binding operation completed", }, nil } ``` -------------------------------- ### Custom Error Responses with Status Code Source: https://context7.com/cloudfoundry/brokerapi/llms.txt Provides a simple custom error response with a specific HTTP status code and an error key. Use when a specific error condition needs to be communicated. ```go package main import ( "context" "errors" "net/http" "code.cloudfoundry.org/brokerapi/v13/domain" "code.cloudfoundry.org/brokerapi/v13/domain/apiresponses" ) func (b *MyServiceBroker) Provision(ctx context.Context, instanceID string, details domain.ProvisionDetails, asyncAllowed bool) (domain.ProvisionedServiceSpec, error) { // Simple custom error with status code if !isValidRegion(details) { return domain.ProvisionedServiceSpec{}, apiresponses.NewFailureResponse( errors.New("invalid region specified"), http.StatusBadRequest, "invalid-region", ) } // Custom error with error key in response body if !hasQuota(details) { return domain.ProvisionedServiceSpec{}, apiresponses.NewFailureResponseBuilder( errors.New("quota exceeded for this plan"), http.StatusForbidden, "quota-exceeded", ).WithErrorKey("QuotaExceeded").Build() } // Custom error with empty response body if isMaintenanceMode() { return domain.ProvisionedServiceSpec{}, apiresponses.NewFailureResponseBuilder( errors.New("service is in maintenance mode"), http.StatusServiceUnavailable, "maintenance-mode", ).WithEmptyResponse().Build() } return domain.ProvisionedServiceSpec{}, nil } ``` -------------------------------- ### Service Binding Operations Source: https://context7.com/cloudfoundry/brokerapi/llms.txt API endpoints for managing service bindings, including fetching binding details and checking the last operation status. ```APIDOC ## GET /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Description Fetches an existing service binding. ### Method GET ### Endpoint /v2/service_instances/{instance_id}/service_bindings/{binding_id} ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance. - **binding_id** (string) - Required - The ID of the service binding. ### Response #### Success Response (200) - **Credentials** (map[string]interface{}) - The credentials for the service binding. #### Response Example ```json { "credentials": { "host": "db.example.com", "port": 5432, "username": "user-abcdefgh", "password": "generated-password" } } ``` ``` ```APIDOC ## GET /v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation ### Description Fetches the last operation state for a service binding. ### Method GET ### Endpoint /v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation ### Parameters #### Path Parameters - **instance_id** (string) - Required - The ID of the service instance. - **binding_id** (string) - Required - The ID of the service binding. ### Response #### Success Response (200) - **State** (domain.LastOperationState) - The state of the last operation (e.g., Succeeded, Failed, InProgress). - **Description** (string) - A description of the last operation. #### Response Example ```json { "state": "succeeded", "description": "Binding operation completed" } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.