github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/api/cloudcontroller/ccv3/service_broker.go (about)

     1  package ccv3
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/internal"
    12  )
    13  
    14  // ServiceBroker represents Service Broker data
    15  type ServiceBroker struct {
    16  	// GUID is a unique service broker identifier.
    17  	GUID string
    18  	// Name is the name of the service broker.
    19  	Name string
    20  	// URL is the url of the service broker.
    21  	URL string
    22  	// Status is the state of the service broker.
    23  	Status string
    24  }
    25  
    26  type ServiceBrokerModel struct {
    27  	// Name is the name of the service broker.
    28  	Name string
    29  	// URL is the url of the service broker.
    30  	URL string
    31  	// Username is the Basic Auth username for the service broker.
    32  	Username string
    33  	// Password is the Basic Auth password for the service broker.
    34  	Password string
    35  	// Space GUID for the space that the broker is in. Empty when not a space-scoped service broker.
    36  	SpaceGUID string
    37  }
    38  
    39  // serviceBrokerRequest represents a Cloud Controller V3 Service Broker (when creating and updating).
    40  type serviceBrokerRequest struct {
    41  	// GUID is a unique service broker identifier.
    42  	GUID string `json:"guid,omitempty"`
    43  	// Name is the name of the service broker.
    44  	Name string `json:"name,omitempty"`
    45  	// URL is the url of the service broker.
    46  	URL string `json:"url,omitempty"`
    47  	// Authentication contains the authentication for authenticating with the service broker.
    48  	Authentication *serviceBrokerAuthentication `json:"authentication,omitempty"`
    49  	// This is the relationship for the space GUID
    50  	Relationships *serviceBrokerRelationships `json:"relationships,omitempty"`
    51  }
    52  
    53  // serviceBrokerResponse represents a Cloud Controller V3 Service Broker (when reading).
    54  type serviceBrokerResponse struct {
    55  	// GUID is a unique service broker identifier.
    56  	GUID string `json:"guid,omitempty"`
    57  	// Name is the name of the service broker.
    58  	Name string `json:"name"`
    59  	// URL is the url of the service broker.
    60  	URL string `json:"url"`
    61  	// Status is the state of the service broker.
    62  	Status string `json:"status,omitempty"`
    63  	// Authentication contains the authentication for authenticating with the service broker.
    64  	Authentication serviceBrokerAuthentication `json:"authentication"`
    65  	// This is the relationship for the space GUID
    66  	Relationships *serviceBrokerRelationships `json:"relationships,omitempty"`
    67  }
    68  
    69  // serviceBrokerAuthentication represents a data structure for the Credentials
    70  // of V3 Service Broker.
    71  type serviceBrokerAuthentication struct {
    72  	// Type is the type of authentication for the service broker, e.g. "basic"
    73  	Type constant.ServiceBrokerCredentialsType `json:"type"`
    74  	// Data is the authentication data of the service broker of a particular type.
    75  	Credentials serviceBrokerBasicAuthCredentials `json:"credentials"`
    76  }
    77  
    78  // serviceBrokerBasicAuthCredentials represents a data structure for the Credentials Data
    79  // of V3 Service Broker Credentials.
    80  type serviceBrokerBasicAuthCredentials struct {
    81  	// Username is the Basic Auth username for the service broker.
    82  	Username string `json:"username"`
    83  	// Password is the Basic Auth password for the service broker.
    84  	Password string `json:"password"`
    85  }
    86  
    87  // serviceBrokerRelationships represents a data structure for the relationships data
    88  // of V3 Service Broker Relationships.
    89  type serviceBrokerRelationships struct {
    90  	// Space represents the space that a space-scoped broker is in
    91  	Space serviceBrokerRelationshipsSpace `json:"space"`
    92  }
    93  
    94  // serviceBrokerRelationshipsSpace represents a data structure for the relationships space data
    95  // of V3 Service Broker Relationships.
    96  type serviceBrokerRelationshipsSpace struct {
    97  	// Data holds the space GUID object
    98  	Data serviceBrokerRelationshipsSpaceData `json:"data"`
    99  }
   100  
   101  // serviceBrokerRelationshipsSpaceData represents a data structure for the relationships space GUID data
   102  // of V3 Service Broker Relationships.
   103  type serviceBrokerRelationshipsSpaceData struct {
   104  	// GUID is the space guid associated with a space-scoped broker
   105  	GUID string `json:"guid"`
   106  }
   107  
   108  // CreateServiceBroker registers a new service broker.
   109  func (client *Client) CreateServiceBroker(serviceBroker ServiceBrokerModel) (JobURL, Warnings, error) {
   110  	bodyBytes, err := json.Marshal(newServiceBroker(serviceBroker))
   111  	if err != nil {
   112  		return "", nil, err
   113  	}
   114  
   115  	request, err := client.newHTTPRequest(requestOptions{
   116  		RequestName: internal.PostServiceBrokerRequest,
   117  		Body:        bytes.NewReader(bodyBytes),
   118  	})
   119  	if err != nil {
   120  		return "", nil, err
   121  	}
   122  
   123  	response := cloudcontroller.Response{}
   124  	err = client.connection.Make(request, &response)
   125  	return JobURL(response.ResourceLocationURL), response.Warnings, err
   126  }
   127  
   128  // DeleteServiceBroker deletes a named service broker
   129  func (client *Client) DeleteServiceBroker(serviceBrokerGUID string) (JobURL, Warnings, error) {
   130  	request, err := client.newHTTPRequest(requestOptions{
   131  		RequestName: internal.DeleteServiceBrokerRequest,
   132  		URIParams: map[string]string{
   133  			"service_broker_guid": serviceBrokerGUID,
   134  		},
   135  	})
   136  
   137  	if err != nil {
   138  		return "", nil, err
   139  	}
   140  
   141  	response := cloudcontroller.Response{}
   142  	err = client.connection.Make(request, &response)
   143  	return JobURL(response.ResourceLocationURL), response.Warnings, err
   144  }
   145  
   146  // GetServiceBrokers lists service brokers.
   147  func (client *Client) GetServiceBrokers() ([]ServiceBroker, Warnings, error) {
   148  	request, err := client.newHTTPRequest(requestOptions{
   149  		RequestName: internal.GetServiceBrokersRequest,
   150  	})
   151  	if err != nil {
   152  		return nil, nil, err
   153  	}
   154  
   155  	var fullList []ServiceBroker
   156  	warnings, err := client.paginate(request, serviceBrokerResponse{}, func(item interface{}) error {
   157  		if serviceBroker, ok := item.(serviceBrokerResponse); ok {
   158  			fullList = append(fullList, extractServiceBrokerData(serviceBroker))
   159  		} else {
   160  			return ccerror.UnknownObjectInListError{
   161  				Expected:   serviceBrokerResponse{},
   162  				Unexpected: item,
   163  			}
   164  		}
   165  		return nil
   166  	})
   167  
   168  	return fullList, warnings, err
   169  }
   170  
   171  // UpdateServiceBroker updates an existing service broker.
   172  func (client *Client) UpdateServiceBroker(serviceBrokerGUID string, serviceBroker ServiceBrokerModel) (JobURL, Warnings, error) {
   173  	brokerUpdateRequest, err := newUpdateServiceBroker(serviceBroker)
   174  	if err != nil {
   175  		return "", nil, err
   176  	}
   177  
   178  	bodyBytes, err := json.Marshal(brokerUpdateRequest)
   179  	if err != nil {
   180  		return "", nil, err
   181  	}
   182  
   183  	request, err := client.newHTTPRequest(requestOptions{
   184  		RequestName: internal.PatchServiceBrokerRequest,
   185  		URIParams: map[string]string{
   186  			"service_broker_guid": serviceBrokerGUID,
   187  		},
   188  		Body: bytes.NewReader(bodyBytes),
   189  	})
   190  	if err != nil {
   191  		return "", nil, err
   192  	}
   193  
   194  	response := cloudcontroller.Response{}
   195  	err = client.connection.Make(request, &response)
   196  	return JobURL(response.ResourceLocationURL), response.Warnings, err
   197  }
   198  
   199  func newServiceBroker(serviceBroker ServiceBrokerModel) serviceBrokerRequest {
   200  	serviceBrokerRequest := serviceBrokerRequest{
   201  		Name: serviceBroker.Name,
   202  		URL:  serviceBroker.URL,
   203  		Authentication: &serviceBrokerAuthentication{
   204  			Type: constant.BasicCredentials,
   205  			Credentials: serviceBrokerBasicAuthCredentials{
   206  				Username: serviceBroker.Username,
   207  				Password: serviceBroker.Password,
   208  			},
   209  		},
   210  	}
   211  
   212  	if serviceBroker.SpaceGUID != "" {
   213  		serviceBrokerRequest.Relationships = &serviceBrokerRelationships{
   214  			Space: serviceBrokerRelationshipsSpace{
   215  				Data: serviceBrokerRelationshipsSpaceData{
   216  					GUID: serviceBroker.SpaceGUID,
   217  				},
   218  			},
   219  		}
   220  	}
   221  
   222  	return serviceBrokerRequest
   223  }
   224  
   225  func newUpdateServiceBroker(serviceBroker ServiceBrokerModel) (serviceBrokerRequest, error) {
   226  	name := serviceBroker.Name
   227  	username := serviceBroker.Username
   228  	password := serviceBroker.Password
   229  	brokerURL := serviceBroker.URL
   230  	if (username == "" && password != "") || (username != "" && password == "") {
   231  		return serviceBrokerRequest{}, errors.New("boom!") // TODO: fix this
   232  	}
   233  	request := serviceBrokerRequest{
   234  		Name: name,
   235  		URL:  brokerURL,
   236  	}
   237  
   238  	if username != "" && password != "" {
   239  		request.Authentication = &serviceBrokerAuthentication{
   240  			Type: constant.BasicCredentials,
   241  			Credentials: serviceBrokerBasicAuthCredentials{
   242  				Username: username,
   243  				Password: password,
   244  			},
   245  		}
   246  	}
   247  
   248  	return request, nil
   249  }
   250  
   251  func extractServiceBrokerData(response serviceBrokerResponse) ServiceBroker {
   252  	return ServiceBroker{
   253  		Name:   response.Name,
   254  		URL:    response.URL,
   255  		GUID:   response.GUID,
   256  		Status: response.Status,
   257  	}
   258  }