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?)://[^\.]+\.([^:]+)`)