3535 AccountAPI = "https://account.scaleway.com/"
3636 MetadataAPI = "http://169.254.42.42/"
3737 MarketplaceAPI = "https://api-marketplace.scaleway.com"
38- URLPublicDNS = ".pub.cloud.scaleway.com"
39- URLPrivateDNS = ".priv.cloud.scaleway.com"
38+ ComputeAPIPar1 = "https://cp-par1.scaleway.com/"
39+ ComputeAPIAms1 = "https://cp-ams1.scaleway.com"
40+
41+ URLPublicDNS = ".pub.cloud.scaleway.com"
42+ URLPrivateDNS = ".priv.cloud.scaleway.com"
4043)
4144
4245func init () {
@@ -74,6 +77,8 @@ type ScalewayAPI struct {
7477 client * http.Client
7578 verbose bool
7679 computeAPI string
80+
81+ Region string
7782 //
7883 Logger
7984}
@@ -885,10 +890,13 @@ func NewScalewayAPI(organization, token, userAgent, region string, options ...fu
885890 }
886891 switch region {
887892 case "par1" , "" :
888- s .computeAPI = "https://api.scaleway.com/"
893+ s .computeAPI = ComputeAPIPar1
894+ case "ams1" :
895+ s .computeAPI = ComputeAPIAms1
889896 default :
890897 return nil , fmt .Errorf ("%s isn't a valid region" , region )
891898 }
899+ s .Region = region
892900 if url := os .Getenv ("SCW_COMPUTE_API" ); url != "" {
893901 s .computeAPI = url
894902 }
@@ -1098,6 +1106,30 @@ func (s *ScalewayAPI) handleHTTPError(goodStatusCode []int, resp *http.Response)
10981106 return body , nil
10991107}
11001108
1109+ func (s * ScalewayAPI ) fetchServers (api string , query url.Values , out chan <- ScalewayServers ) func () error {
1110+ return func () error {
1111+ resp , err := s .GetResponsePaginate (api , "servers" , query )
1112+ if resp != nil {
1113+ defer resp .Body .Close ()
1114+ }
1115+ if err != nil {
1116+ return err
1117+ }
1118+
1119+ body , err := s .handleHTTPError ([]int {http .StatusOK }, resp )
1120+ if err != nil {
1121+ return err
1122+ }
1123+ var servers ScalewayServers
1124+
1125+ if err = json .Unmarshal (body , & servers ); err != nil {
1126+ return err
1127+ }
1128+ out <- servers
1129+ return nil
1130+ }
1131+ }
1132+
11011133// GetServers gets the list of servers from the ScalewayAPI
11021134func (s * ScalewayAPI ) GetServers (all bool , limit int ) (* []ScalewayServer , error ) {
11031135 query := url.Values {}
@@ -1112,32 +1144,34 @@ func (s *ScalewayAPI) GetServers(all bool, limit int) (*[]ScalewayServer, error)
11121144 if all && limit == 0 {
11131145 s .Cache .ClearServers ()
11141146 }
1115- resp , err := s .GetResponsePaginate (s .computeAPI , "servers" , query )
1116- if resp != nil {
1117- defer resp .Body .Close ()
1118- }
1119- if err != nil {
1120- return nil , err
1147+ var (
1148+ g errgroup.Group
1149+ apis = []string {
1150+ ComputeAPIPar1 ,
1151+ ComputeAPIAms1 ,
1152+ }
1153+ )
1154+
1155+ serverChan := make (chan ScalewayServers , 2 )
1156+ for _ , api := range apis {
1157+ g .Go (s .fetchServers (api , query , serverChan ))
11211158 }
11221159
1123- body , err := s .handleHTTPError ([]int {http .StatusOK }, resp )
1124- if err != nil {
1160+ if err := g .Wait (); err != nil {
11251161 return nil , err
11261162 }
1163+ close (serverChan )
11271164 var servers ScalewayServers
1128- if err = json .Unmarshal (body , & servers ); err != nil {
1129- return nil , err
1165+
1166+ for server := range serverChan {
1167+ servers .Servers = append (servers .Servers , server .Servers ... )
11301168 }
1169+
11311170 for i , server := range servers .Servers {
1132- // FIXME arch, owner, title
11331171 servers .Servers [i ].DNSPublic = server .Identifier + URLPublicDNS
11341172 servers .Servers [i ].DNSPrivate = server .Identifier + URLPrivateDNS
11351173 s .Cache .InsertServer (server .Identifier , server .Location .ZoneID , server .Arch , server .Organization , server .Name )
11361174 }
1137- // FIXME: when API limit is ready, remove the following code
1138- if limit > 0 && limit < len (servers .Servers ) {
1139- servers .Servers = servers .Servers [0 :limit ]
1140- }
11411175 return & servers .Servers , nil
11421176}
11431177
@@ -2081,11 +2115,12 @@ func showResolverResults(needle string, results ScalewayResolverResults) error {
20812115 w := tabwriter .NewWriter (os .Stderr , 20 , 1 , 3 , ' ' , 0 )
20822116 defer w .Flush ()
20832117 sort .Sort (results )
2118+ fmt .Fprintf (w , " IMAGEID\t FROM\t NAME\t ZONE\t ARCH\n " )
20842119 for _ , result := range results {
20852120 if result .Arch == "" {
20862121 result .Arch = "n/a"
20872122 }
2088- fmt .Fprintf (w , "- %s\t %s\t %s\t %s\n " , result .TruncIdentifier (), result .CodeName (), result .Name , result .Arch )
2123+ fmt .Fprintf (w , "- %s\t %s\t %s\t %s\t %s \ n " , result .TruncIdentifier (), result .CodeName (), result .Name , result . Region , result .Arch )
20892124 }
20902125 return fmt .Errorf ("Too many candidates for %s (%d)" , needle , len (results ))
20912126}
@@ -2139,6 +2174,19 @@ func FilterImagesByArch(res ScalewayResolverResults, arch string) (ret ScalewayR
21392174 return
21402175}
21412176
2177+ // FilterImagesByRegion removes entry that doesn't match with region
2178+ func FilterImagesByRegion (res ScalewayResolverResults , region string ) (ret ScalewayResolverResults ) {
2179+ if region == "*" {
2180+ return res
2181+ }
2182+ for _ , result := range res {
2183+ if result .Region == region {
2184+ ret = append (ret , result )
2185+ }
2186+ }
2187+ return
2188+ }
2189+
21422190// GetImageID returns exactly one image matching
21432191func (s * ScalewayAPI ) GetImageID (needle , arch string ) (* ScalewayImageIdentifier , error ) {
21442192 // Parses optional type prefix, i.e: "image:name" -> "name"
@@ -2149,17 +2197,18 @@ func (s *ScalewayAPI) GetImageID(needle, arch string) (*ScalewayImageIdentifier,
21492197 return nil , fmt .Errorf ("Unable to resolve image %s: %s" , needle , err )
21502198 }
21512199 images = FilterImagesByArch (images , arch )
2200+ images = FilterImagesByRegion (images , s .Region )
21522201 if len (images ) == 1 {
21532202 return & ScalewayImageIdentifier {
21542203 Identifier : images [0 ].Identifier ,
21552204 Arch : images [0 ].Arch ,
21562205 // FIXME region, owner hardcoded
2157- Region : "" ,
2206+ Region : images [ 0 ]. Region ,
21582207 Owner : "" ,
21592208 }, nil
21602209 }
21612210 if len (images ) == 0 {
2162- return nil , fmt .Errorf ("No such image: %s" , needle )
2211+ return nil , fmt .Errorf ("No such image (zone %s, arch %s) : %s" , s . Region , arch , needle )
21632212 }
21642213 return nil , showResolverResults (needle , images )
21652214}
@@ -2817,3 +2866,14 @@ func (s *ScalewayAPI) DeleteMarketPlaceLocalImage(uuidImage, uuidVersion, uuidLo
28172866 _ , err = s .handleHTTPError ([]int {http .StatusNoContent }, resp )
28182867 return err
28192868}
2869+
2870+ // ResolveTTYUrl return an URL to get a tty
2871+ func (s * ScalewayAPI ) ResolveTTYUrl () string {
2872+ switch s .Region {
2873+ case "par1" , "" :
2874+ return "https://tty-par1.scaleway.com/v2/"
2875+ case "ams1" :
2876+ return "https://tty-ams1.scaleway.com"
2877+ }
2878+ return ""
2879+ }
0 commit comments