func (svc *ServiceDefinition) GetPlanById(planId string) (*ServicePlan, error) {
	catalogEntry, err := svc.CatalogEntry()
	if err != nil {
		return nil, err
	}
	for _, plan := range catalogEntry.Plans {
		if plan.ID == planId {
			return &plan, nil
		}
	}
	return nil, fmt.Errorf("Plan ID %q could not be found", planId)
}
GetPlanById finds a plan in this service by its UUID.
package broker
import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"code.cloudfoundry.org/lager"
	"github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models"
	"github.com/GoogleCloudPlatform/gcp-service-broker/pkg/toggles"
	"github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation"
	"github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext"
	"github.com/GoogleCloudPlatform/gcp-service-broker/utils"
	"github.com/pivotal-cf/brokerapi"
	"github.com/spf13/viper"
	"golang.org/x/oauth2/jwt"
)
var enableCatalogSchemas = toggles.Features.Toggle("enable-catalog-schemas", false, `Enable generating JSONSchema for the service catalog.`)
type ServiceDefinition struct {
	Id               string
	Name             string
	Description      string
	DisplayName      string
	ImageUrl         string
	DocumentationUrl string
	SupportUrl       string
	Tags             []string
	Bindable         bool
	PlanUpdateable   bool
	Plans            []ServicePlan
	ProvisionInputVariables    []BrokerVariable
	ProvisionComputedVariables []varcontext.DefaultVariable
	BindInputVariables         []BrokerVariable
	BindOutputVariables        []BrokerVariable
	BindComputedVariables      []varcontext.DefaultVariable
	PlanVariables              []BrokerVariable
	Examples                   []ServiceExample
	DefaultRoleWhitelist       []string
	ProviderBuilder func(projectId string, auth *jwt.Config, logger lager.Logger) ServiceProvider
	IsBuiltin bool
}
var _ validation.Validatable = (*ServiceDefinition)(nil)
func (sd *ServiceDefinition) Validate() (errs *validation.FieldError) {
	errs = errs.Also(
		validation.ErrIfNotUUID(sd.Id, "Id"),
		validation.ErrIfNotOSBName(sd.Name, "Name"),
	)
	if sd.ImageUrl != "" {
		errs = errs.Also(validation.ErrIfNotURL(sd.ImageUrl, "ImageUrl"))
	}
	if sd.DocumentationUrl != "" {
		errs = errs.Also(validation.ErrIfNotURL(sd.DocumentationUrl, "DocumentationUrl"))
	}
	if sd.SupportUrl != "" {
		errs = errs.Also(validation.ErrIfNotURL(sd.SupportUrl, "SupportUrl"))
	}
	for i, v := range sd.ProvisionInputVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("ProvisionInputVariables", i))
	}
	for i, v := range sd.ProvisionComputedVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("ProvisionComputedVariables", i))
	}
	for i, v := range sd.BindInputVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("BindInputVariables", i))
	}
	for i, v := range sd.BindOutputVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("BindOutputVariables", i))
	}
	for i, v := range sd.BindComputedVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("BindComputedVariables", i))
	}
	for i, v := range sd.PlanVariables {
		errs = errs.Also(v.Validate().ViaFieldIndex("PlanVariables", i))
	}
	return errs
}
func (svc *ServiceDefinition) UserDefinedPlansProperty() string {
	return fmt.Sprintf("service.%s.plans", svc.Name)
}
func (svc *ServiceDefinition) ProvisionDefaultOverrideProperty() string {
	return fmt.Sprintf("service.%s.provision.defaults", svc.Name)
}
func (svc *ServiceDefinition) ProvisionDefaultOverrides() map[string]interface{} {
	return viper.GetStringMap(svc.ProvisionDefaultOverrideProperty())
}
func (svc *ServiceDefinition) IsRoleWhitelistEnabled() bool {
	return len(svc.DefaultRoleWhitelist) > 0
}
func (svc *ServiceDefinition) BindDefaultOverrideProperty() string {
	return fmt.Sprintf("service.%s.bind.defaults", svc.Name)
}
func (svc *ServiceDefinition) BindDefaultOverrides() map[string]interface{} {
	return viper.GetStringMap(svc.BindDefaultOverrideProperty())
}
func (svc *ServiceDefinition) TileUserDefinedPlansVariable() string {
	v := utils.PropertyToEnvUnprefixed(svc.Name)
	v = strings.TrimPrefix(v, "GOOGLE_")
	return v + "_CUSTOM_PLANS"
}
func (svc *ServiceDefinition) CatalogEntry() (*Service, error) {
	userPlans, err := svc.UserDefinedPlans()
	if err != nil {
		return nil, err
	}
	sd := &Service{
		Service: brokerapi.Service{
			ID:          svc.Id,
			Name:        svc.Name,
			Description: svc.Description,
			Metadata: &brokerapi.ServiceMetadata{
				DisplayName:     svc.DisplayName,
				LongDescription: svc.Description,
				DocumentationUrl: svc.DocumentationUrl,
				ImageUrl:         svc.ImageUrl,
				SupportUrl:       svc.SupportUrl,
			},
			Tags:          svc.Tags,
			Bindable:      svc.Bindable,
			PlanUpdatable: svc.PlanUpdateable,
		},
		Plans: append(svc.Plans, userPlans...),
	}
	if enableCatalogSchemas.IsActive() {
		for i, _ := range sd.Plans {
			sd.Plans[i].Schemas = svc.createSchemas()
		}
	}
	return sd, nil
}
func (svc *ServiceDefinition) createSchemas() *brokerapi.ServiceSchemas {
	return &brokerapi.ServiceSchemas{
		Instance: brokerapi.ServiceInstanceSchema{
			Create: brokerapi.Schema{
				Parameters: CreateJsonSchema(svc.ProvisionInputVariables),
			},
		},
		Binding: brokerapi.ServiceBindingSchema{
			Create: brokerapi.Schema{
				Parameters: CreateJsonSchema(svc.BindInputVariables),
			},
		},
	}
}