github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/api/cloudcontroller/ccv2/route.go (about)

     1  package ccv2
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"net/url"
     9  
    10  	"github.com/liamawhite/cli-with-i18n/api/cloudcontroller"
    11  	"github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccerror"
    12  	"github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccv2/internal"
    13  	"github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccversion"
    14  	"github.com/liamawhite/cli-with-i18n/types"
    15  )
    16  
    17  // Route represents a Cloud Controller Route.
    18  type Route struct {
    19  	GUID       string        `json:"-"`
    20  	Host       string        `json:"host,omitempty"`
    21  	Path       string        `json:"path,omitempty"`
    22  	Port       types.NullInt `json:"port,omitempty"`
    23  	DomainGUID string        `json:"domain_guid"`
    24  	SpaceGUID  string        `json:"space_guid"`
    25  }
    26  
    27  // UnmarshalJSON helps unmarshal a Cloud Controller Route response.
    28  func (route *Route) UnmarshalJSON(data []byte) error {
    29  	var ccRoute struct {
    30  		Metadata internal.Metadata `json:"metadata"`
    31  		Entity   struct {
    32  			Host       string        `json:"host"`
    33  			Path       string        `json:"path"`
    34  			Port       types.NullInt `json:"port"`
    35  			DomainGUID string        `json:"domain_guid"`
    36  			SpaceGUID  string        `json:"space_guid"`
    37  		} `json:"entity"`
    38  	}
    39  	if err := json.Unmarshal(data, &ccRoute); err != nil {
    40  		return err
    41  	}
    42  
    43  	route.GUID = ccRoute.Metadata.GUID
    44  	route.Host = ccRoute.Entity.Host
    45  	route.Path = ccRoute.Entity.Path
    46  	route.Port = ccRoute.Entity.Port
    47  	route.DomainGUID = ccRoute.Entity.DomainGUID
    48  	route.SpaceGUID = ccRoute.Entity.SpaceGUID
    49  	return nil
    50  }
    51  
    52  // BindRouteToApplication binds the given route to the given application.
    53  func (client *Client) BindRouteToApplication(routeGUID string, appGUID string) (Route, Warnings, error) {
    54  	request, err := client.newHTTPRequest(requestOptions{
    55  		RequestName: internal.PutBindRouteAppRequest,
    56  		URIParams: map[string]string{
    57  			"app_guid":   appGUID,
    58  			"route_guid": routeGUID,
    59  		},
    60  	})
    61  	if err != nil {
    62  		return Route{}, nil, err
    63  	}
    64  
    65  	var route Route
    66  	response := cloudcontroller.Response{
    67  		Result: &route,
    68  	}
    69  	err = client.connection.Make(request, &response)
    70  
    71  	return route, response.Warnings, err
    72  }
    73  
    74  // CreateRoute creates the route with the given properties; SpaceGUID and
    75  // DomainGUID are required. Set generatePort true to generate a random port on
    76  // the cloud controller. generatePort takes precedence over manually specified
    77  // port. Setting the port and generatePort only works with CC API 2.53.0 or
    78  // higher and when TCP router groups are enabled.
    79  func (client *Client) CreateRoute(route Route, generatePort bool) (Route, Warnings, error) {
    80  	body, err := json.Marshal(route)
    81  	if err != nil {
    82  		return Route{}, nil, err
    83  	}
    84  
    85  	request, err := client.newHTTPRequest(requestOptions{
    86  		RequestName: internal.PostRouteRequest,
    87  		Body:        bytes.NewReader(body),
    88  	})
    89  	if err != nil {
    90  		return Route{}, nil, err
    91  	}
    92  
    93  	if generatePort {
    94  		query := url.Values{}
    95  		query.Add("generate_port", "true")
    96  		request.URL.RawQuery = query.Encode()
    97  	}
    98  
    99  	var updatedRoute Route
   100  	response := cloudcontroller.Response{
   101  		Result: &updatedRoute,
   102  	}
   103  
   104  	err = client.connection.Make(request, &response)
   105  	return updatedRoute, response.Warnings, err
   106  }
   107  
   108  // GetApplicationRoutes returns a list of Routes associated with the provided
   109  // Application GUID, and filtered by the provided queries.
   110  func (client *Client) GetApplicationRoutes(appGUID string, queryParams ...Query) ([]Route, Warnings, error) {
   111  	request, err := client.newHTTPRequest(requestOptions{
   112  		RequestName: internal.GetAppRoutesRequest,
   113  		URIParams:   map[string]string{"app_guid": appGUID},
   114  		Query:       FormatQueryParameters(queryParams),
   115  	})
   116  	if err != nil {
   117  		return nil, nil, err
   118  	}
   119  
   120  	var fullRoutesList []Route
   121  	warnings, err := client.paginate(request, Route{}, func(item interface{}) error {
   122  		if route, ok := item.(Route); ok {
   123  			fullRoutesList = append(fullRoutesList, route)
   124  		} else {
   125  			return ccerror.UnknownObjectInListError{
   126  				Expected:   Route{},
   127  				Unexpected: item,
   128  			}
   129  		}
   130  		return nil
   131  	})
   132  
   133  	return fullRoutesList, warnings, err
   134  }
   135  
   136  // GetSpaceRoutes returns a list of Routes associated with the provided Space
   137  // GUID, and filtered by the provided queries.
   138  func (client *Client) GetSpaceRoutes(spaceGUID string, queryParams ...Query) ([]Route, Warnings, error) {
   139  	request, err := client.newHTTPRequest(requestOptions{
   140  		RequestName: internal.GetSpaceRoutesRequest,
   141  		URIParams:   map[string]string{"space_guid": spaceGUID},
   142  		Query:       FormatQueryParameters(queryParams),
   143  	})
   144  	if err != nil {
   145  		return nil, nil, err
   146  	}
   147  
   148  	var fullRoutesList []Route
   149  	warnings, err := client.paginate(request, Route{}, func(item interface{}) error {
   150  		if route, ok := item.(Route); ok {
   151  			fullRoutesList = append(fullRoutesList, route)
   152  		} else {
   153  			return ccerror.UnknownObjectInListError{
   154  				Expected:   Route{},
   155  				Unexpected: item,
   156  			}
   157  		}
   158  		return nil
   159  	})
   160  
   161  	return fullRoutesList, warnings, err
   162  }
   163  
   164  // GetRoutes returns a list of Routes based off of the provided queries.
   165  func (client *Client) GetRoutes(queryParams ...Query) ([]Route, Warnings, error) {
   166  	request, err := client.newHTTPRequest(requestOptions{
   167  		RequestName: internal.GetRoutesRequest,
   168  		Query:       FormatQueryParameters(queryParams),
   169  	})
   170  	if err != nil {
   171  		return nil, nil, err
   172  	}
   173  
   174  	var fullRoutesList []Route
   175  	warnings, err := client.paginate(request, Route{}, func(item interface{}) error {
   176  		if route, ok := item.(Route); ok {
   177  			fullRoutesList = append(fullRoutesList, route)
   178  		} else {
   179  			return ccerror.UnknownObjectInListError{
   180  				Expected:   Route{},
   181  				Unexpected: item,
   182  			}
   183  		}
   184  		return nil
   185  	})
   186  
   187  	return fullRoutesList, warnings, err
   188  }
   189  
   190  // DeleteRoute deletes the Route associated with the provided Route GUID.
   191  func (client *Client) DeleteRoute(routeGUID string) (Warnings, error) {
   192  	request, err := client.newHTTPRequest(requestOptions{
   193  		RequestName: internal.DeleteRouteRequest,
   194  		URIParams:   map[string]string{"route_guid": routeGUID},
   195  	})
   196  	if err != nil {
   197  		return nil, err
   198  	}
   199  
   200  	var response cloudcontroller.Response
   201  	err = client.connection.Make(request, &response)
   202  	return response.Warnings, err
   203  }
   204  
   205  // CheckRoute returns true if the route exists in the CF instance. DomainGUID
   206  // is required for check. This call will only work for CC API 2.55 or higher.
   207  func (client *Client) CheckRoute(route Route) (bool, Warnings, error) {
   208  	currentVersion := client.APIVersion()
   209  	switch {
   210  	case cloudcontroller.MinimumAPIVersionCheck(currentVersion, ccversion.MinVersionNoHostInReservedRouteEndpoint) == nil:
   211  		return client.checkRoute(route)
   212  	case cloudcontroller.MinimumAPIVersionCheck(currentVersion, ccversion.MinVersionHTTPRoutePath) == nil:
   213  		return client.checkRouteDeprecated(route.DomainGUID, route.Host, route.Path)
   214  	default:
   215  		return client.checkRouteDeprecated(route.DomainGUID, route.Host, "")
   216  	}
   217  }
   218  
   219  func (client *Client) checkRoute(route Route) (bool, Warnings, error) {
   220  	request, err := client.newHTTPRequest(requestOptions{
   221  		RequestName: internal.GetRouteReservedRequest,
   222  		URIParams:   map[string]string{"domain_guid": route.DomainGUID},
   223  	})
   224  	if err != nil {
   225  		return false, nil, err
   226  	}
   227  
   228  	queryParams := url.Values{}
   229  	if route.Host != "" {
   230  		queryParams.Add("host", route.Host)
   231  	}
   232  	if route.Path != "" {
   233  		queryParams.Add("path", route.Path)
   234  	}
   235  	if route.Port.IsSet {
   236  		queryParams.Add("port", fmt.Sprint(route.Port.Value))
   237  	}
   238  	request.URL.RawQuery = queryParams.Encode()
   239  
   240  	var response cloudcontroller.Response
   241  	err = client.connection.Make(request, &response)
   242  	if _, ok := err.(ccerror.ResourceNotFoundError); ok {
   243  		return false, response.Warnings, nil
   244  	}
   245  
   246  	return response.HTTPResponse.StatusCode == http.StatusNoContent, response.Warnings, err
   247  }
   248  
   249  func (client *Client) checkRouteDeprecated(domainGUID string, host string, path string) (bool, Warnings, error) {
   250  	request, err := client.newHTTPRequest(requestOptions{
   251  		RequestName: internal.GetRouteReservedDeprecatedRequest,
   252  		URIParams:   map[string]string{"domain_guid": domainGUID, "host": host},
   253  	})
   254  	if err != nil {
   255  		return false, nil, err
   256  	}
   257  
   258  	queryParams := url.Values{}
   259  	if path != "" {
   260  		queryParams.Add("path", path)
   261  	}
   262  	request.URL.RawQuery = queryParams.Encode()
   263  
   264  	var response cloudcontroller.Response
   265  	err = client.connection.Make(request, &response)
   266  	if _, ok := err.(ccerror.ResourceNotFoundError); ok {
   267  		return false, response.Warnings, nil
   268  	}
   269  
   270  	return response.HTTPResponse.StatusCode == http.StatusNoContent, response.Warnings, err
   271  }