github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/api/endpoints.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
     9  	"github.com/cloudfoundry/cli/cf/errors"
    10  	"github.com/cloudfoundry/cli/cf/net"
    11  )
    12  
    13  type EndpointRepository interface {
    14  	UpdateEndpoint(endpoint string) (finalEndpoint string, apiErr error)
    15  }
    16  
    17  type RemoteEndpointRepository struct {
    18  	config  core_config.ReadWriter
    19  	gateway net.Gateway
    20  }
    21  
    22  type endpointResource struct {
    23  	ApiVersion               string `json:"api_version"`
    24  	AuthorizationEndpoint    string `json:"authorization_endpoint"`
    25  	LoggregatorEndpoint      string `json:"logging_endpoint"`
    26  	MinCliVersion            string `json:"min_cli_version"`
    27  	MinRecommendedCliVersion string `json:"min_recommended_cli_version"`
    28  }
    29  
    30  func NewEndpointRepository(config core_config.ReadWriter, gateway net.Gateway) EndpointRepository {
    31  	r := &RemoteEndpointRepository{
    32  		config:  config,
    33  		gateway: gateway,
    34  	}
    35  	return r
    36  }
    37  
    38  func (repo RemoteEndpointRepository) UpdateEndpoint(endpoint string) (finalEndpoint string, apiErr error) {
    39  	defer func() {
    40  		if apiErr != nil {
    41  			repo.config.SetApiEndpoint("")
    42  		}
    43  	}()
    44  
    45  	endpointMissingScheme := !strings.HasPrefix(endpoint, "https://") && !strings.HasPrefix(endpoint, "http://")
    46  
    47  	if endpointMissingScheme {
    48  		finalEndpoint := "https://" + endpoint
    49  		apiErr := repo.attemptUpdate(finalEndpoint)
    50  
    51  		switch apiErr.(type) {
    52  		case nil:
    53  		case *errors.InvalidSSLCert:
    54  			return endpoint, apiErr
    55  		default:
    56  			finalEndpoint = "http://" + endpoint
    57  			apiErr = repo.attemptUpdate(finalEndpoint)
    58  		}
    59  
    60  		return finalEndpoint, apiErr
    61  	} else {
    62  		apiErr := repo.attemptUpdate(endpoint)
    63  		return endpoint, apiErr
    64  	}
    65  }
    66  
    67  func (repo RemoteEndpointRepository) attemptUpdate(endpoint string) error {
    68  	serverResponse := new(endpointResource)
    69  	err := repo.gateway.GetResource(endpoint+"/v2/info", &serverResponse)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	if endpoint != repo.config.ApiEndpoint() {
    75  		repo.config.ClearSession()
    76  	}
    77  
    78  	repo.config.SetApiEndpoint(endpoint)
    79  	repo.config.SetApiVersion(serverResponse.ApiVersion)
    80  	repo.config.SetAuthenticationEndpoint(serverResponse.AuthorizationEndpoint)
    81  	repo.config.SetMinCliVersion(serverResponse.MinCliVersion)
    82  	repo.config.SetMinRecommendedCliVersion(serverResponse.MinRecommendedCliVersion)
    83  
    84  	if serverResponse.LoggregatorEndpoint == "" {
    85  		repo.config.SetLoggregatorEndpoint(defaultLoggregatorEndpoint(endpoint))
    86  	} else {
    87  		repo.config.SetLoggregatorEndpoint(serverResponse.LoggregatorEndpoint)
    88  	}
    89  
    90  	//* 3/5/15: loggregator endpoint will be renamed to doppler eventually,
    91  	//          we just have to use the loggregator endpoint as doppler for now
    92  	repo.config.SetDopplerEndpoint(strings.Replace(repo.config.LoggregatorEndpoint(), "loggregator", "doppler", 1))
    93  
    94  	return nil
    95  }
    96  
    97  // FIXME: needs semantic versioning
    98  func defaultLoggregatorEndpoint(apiEndpoint string) string {
    99  	matches := endpointDomainRegex.FindStringSubmatch(apiEndpoint)
   100  	url := fmt.Sprintf("ws%s://loggregator.%s", matches[1], matches[2])
   101  	if url[0:3] == "wss" {
   102  		return url + ":443"
   103  	} else {
   104  		return url + ":80"
   105  	}
   106  }
   107  
   108  var endpointDomainRegex = regexp.MustCompile(`^http(s?)://[^\.]+\.([^:]+)`)