diff --git a/src/cmd/linuxkit/scaleway.go b/src/cmd/linuxkit/scaleway.go index f3604d0b4..d00b7a32b 100644 --- a/src/cmd/linuxkit/scaleway.go +++ b/src/cmd/linuxkit/scaleway.go @@ -18,8 +18,6 @@ import ( "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/api/marketplace/v1" "github.com/scaleway/scaleway-sdk-go/scw" - "github.com/scaleway/scaleway-sdk-go/scwconfig" - "github.com/scaleway/scaleway-sdk-go/utils" log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/terminal" @@ -29,7 +27,9 @@ var ( defaultScalewayCommercialType = "DEV1-S" defaultScalewayImageName = "Ubuntu Bionic" defaultScalewayImageArch = "x86_64" - defaultVolumeSize = uint64(10000000000) + defaultVolumeSize = scw.GB * 10 + scalewayDynamicIPRequired = true + scalewayBootType = instance.BootTypeLocal ) // ScalewayClient contains state required for communication with Scaleway as well as the instance @@ -43,23 +43,28 @@ type ScalewayClient struct { } // NewScalewayClient creates a new scaleway client -func NewScalewayClient(secretKey, zone, projectID string) (*ScalewayClient, error) { +func NewScalewayClient(secretKey, zone, organizationID string) (*ScalewayClient, error) { var scwClient *scw.Client log.Debugf("Connecting to Scaleway") if secretKey == "" { - config, err := scwconfig.Load() + config, err := scw.LoadConfig() + if err != nil { + return nil, err + } + profile, err := config.GetActiveProfile() if err != nil { return nil, err } scwClient, err = scw.NewClient( - scw.WithConfig(config), + scw.WithProfile(profile), + scw.WithEnv(), ) if err != nil { return nil, err } } else { - scwZone, err := utils.ParseZone(zone) + scwZone, err := scw.ParseZone(zone) if err != nil { return nil, err } @@ -67,7 +72,7 @@ func NewScalewayClient(secretKey, zone, projectID string) (*ScalewayClient, erro scwClient, err = scw.NewClient( scw.WithAuth("", secretKey), scw.WithDefaultZone(scwZone), - scw.WithDefaultProjectID(projectID), + scw.WithDefaultOrganizationID(organizationID), ) if err != nil { return nil, err @@ -140,10 +145,10 @@ func (s *ScalewayClient) CreateInstance() (string, error) { createServerRequest := &instance.CreateServerRequest{ Name: "linuxkit-builder", CommercialType: defaultScalewayCommercialType, - DynamicIPRequired: true, + DynamicIPRequired: &scalewayDynamicIPRequired, Image: imageID, EnableIPv6: false, - BootType: instance.ServerBootTypeLocal, + BootType: &scalewayBootType, Volumes: volumeMap, } @@ -548,10 +553,10 @@ func (s *ScalewayClient) CreateLinuxkitInstance(instanceName, imageName, instanc log.Debugf("Creating server %s on Scaleway", instanceName) serverResp, err := s.instanceAPI.CreateServer(&instance.CreateServerRequest{ Name: instanceName, - DynamicIPRequired: true, + DynamicIPRequired: &scalewayDynamicIPRequired, CommercialType: instanceType, Image: imageID, - BootType: instance.ServerBootTypeLocal, + BootType: &scalewayBootType, }) if err != nil { return "", err diff --git a/src/cmd/linuxkit/vendor.conf b/src/cmd/linuxkit/vendor.conf index e1dea1533..55665cb07 100644 --- a/src/cmd/linuxkit/vendor.conf +++ b/src/cmd/linuxkit/vendor.conf @@ -67,7 +67,7 @@ github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 github.com/radu-matei/azure-sdk-for-go 3b12823551999669c9a325a32472508e0af7978e github.com/radu-matei/azure-vhd-utils e52754d5569d2a643a7775f72ff2a6cf524f4c25 github.com/rn/iso9660wrap baf8d62ad3155152b488d5ff9d4f2b9bb0d6986a -github.com/scaleway/scaleway-sdk-go 20b731586975c078d9c2d7dd0002127e9e9cdef2 +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6 github.com/sirupsen/logrus v1.0.3 github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.1 diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/README.md b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/README.md index aee6ab579..f12062126 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/README.md +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/README.md @@ -1,4 +1,4 @@ -

+

GoDoc @@ -12,8 +12,7 @@ **:warning: This is an early release, keep in mind that the API can break** -Scaleway is a simple way to build, deploy and scale your infrastructure in the cloud. -We help thousands of developers and businesses to run their infrastructures without any issue. +Scaleway is a single way to create, deploy and scale your infrastructure in the cloud. We help thousands of businesses to run their infrastructures easily. ## Documentation @@ -44,7 +43,7 @@ func main() { // Create a Scaleway client client, err := scw.NewClient( // Get your credentials at https://console.scaleway.com/account/credentials - scw.WithDefaultProjectID("ORGANISATION_ID"), + scw.WithDefaultOrganizationID("ORGANISATION_ID"), scw.WithAuth("ACCESS_KEY", "SECRET_KEY"), ) if err != nil { @@ -56,7 +55,7 @@ func main() { // Call the ListServers method on the Instance SDK response, err := instanceApi.ListServers(&instance.ListServersRequest{ - Zone: utils.ZoneFrPar1, + Zone: scw.ZoneFrPar1, }) if err != nil { panic(err) @@ -70,6 +69,10 @@ func main() { } ``` +## Examples + +You can find additional examples in the [GoDoc](https://godoc.org/github.com/scaleway/scaleway-sdk-go). + ## Development This repository is at its early stage and is still in active development. diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_metadata_sdk.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_metadata_sdk.go index 5fc5f79ff..07d16f5f9 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_metadata_sdk.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_metadata_sdk.go @@ -117,8 +117,8 @@ type Metadata struct { } } -// ListUserdata returns the metadata available from the server -func (*MetadataAPI) ListUserdata() (res *Userdata, err error) { +// ListUserData returns the metadata available from the server +func (*MetadataAPI) ListUserData() (res *UserData, err error) { retries := 0 for retries <= metadataRetryBindPort { port := rand.Intn(1024) @@ -144,20 +144,20 @@ func (*MetadataAPI) ListUserdata() (res *Userdata, err error) { } defer resp.Body.Close() - userdata := &Userdata{} + userdata := &UserData{} err = json.NewDecoder(resp.Body).Decode(userdata) if err != nil { return nil, errors.Wrap(err, "error decoding userdata") } return userdata, nil } - return nil, errors.New("too many bind port retries for ListUserdata") + return nil, errors.New("too many bind port retries for ListUserData") } -// GetUserdata returns the value for the given metadata key -func (*MetadataAPI) GetUserdata(key string) ([]byte, error) { +// GetUserData returns the value for the given metadata key +func (*MetadataAPI) GetUserData(key string) ([]byte, error) { if key == "" { - return make([]byte, 0), errors.New("key must not be empty in GetUserdata") + return make([]byte, 0), errors.New("key must not be empty in GetUserData") } retries := 0 @@ -192,13 +192,13 @@ func (*MetadataAPI) GetUserdata(key string) ([]byte, error) { return body, nil } - return make([]byte, 0), errors.New("too may bind port retries for GetUserdata") + return make([]byte, 0), errors.New("too may bind port retries for GetUserData") } -// SetUserdata sets the userdata key with the given value -func (*MetadataAPI) SetUserdata(key string, value []byte) error { +// SetUserData sets the userdata key with the given value +func (*MetadataAPI) SetUserData(key string, value []byte) error { if key == "" { - return errors.New("key must not be empty in SetUserdata") + return errors.New("key must not be empty in SetUserData") } retries := 0 @@ -231,13 +231,13 @@ func (*MetadataAPI) SetUserdata(key string, value []byte) error { return nil } - return errors.New("too may bind port retries for SetUserdata") + return errors.New("too may bind port retries for SetUserData") } -// DeleteUserdata deletes the userdata key and the associated value -func (*MetadataAPI) DeleteUserdata(key string) error { +// DeleteUserData deletes the userdata key and the associated value +func (*MetadataAPI) DeleteUserData(key string) error { if key == "" { - return errors.New("key must not be empty in DeleteUserdata") + return errors.New("key must not be empty in DeleteUserData") } retries := 0 @@ -269,10 +269,10 @@ func (*MetadataAPI) DeleteUserdata(key string) error { return nil } - return errors.New("too may bind port retries for DeleteUserdata") + return errors.New("too may bind port retries for DeleteUserData") } -// Userdata represents the user data -type Userdata struct { +// UserData represents the user data +type UserData struct { UserData []string `json:"user_data,omitempty"` } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_sdk.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_sdk.go index 0a99b8265..824b39470 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_sdk.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_sdk.go @@ -1,6 +1,7 @@ // This file was automatically generated. DO NOT EDIT. // If you have any remark or suggestion do not hesitate to open an issue. +// Package instance provides methods and message types of the instance v1 API. package instance import ( @@ -15,8 +16,8 @@ import ( "github.com/scaleway/scaleway-sdk-go/internal/errors" "github.com/scaleway/scaleway-sdk-go/internal/marshaler" "github.com/scaleway/scaleway-sdk-go/internal/parameter" + "github.com/scaleway/scaleway-sdk-go/namegenerator" "github.com/scaleway/scaleway-sdk-go/scw" - "github.com/scaleway/scaleway-sdk-go/utils" ) // always import dependencies @@ -31,8 +32,9 @@ var ( _ scw.ScalewayRequest _ marshaler.Duration - _ utils.File + _ scw.File _ = parameter.AddToQuery + _ = namegenerator.GetRandomName ) // API instance API @@ -64,25 +66,55 @@ func (enum Arch) String() string { return string(enum) } -type GetServerTypesAvailabilityResponseAvailability string +func (enum Arch) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *Arch) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = Arch(Arch(tmp).String()) + return nil +} + +type BootType string const ( - // GetServerTypesAvailabilityResponseAvailabilityAvailable is [insert doc]. - GetServerTypesAvailabilityResponseAvailabilityAvailable = GetServerTypesAvailabilityResponseAvailability("available") - // GetServerTypesAvailabilityResponseAvailabilityScarce is [insert doc]. - GetServerTypesAvailabilityResponseAvailabilityScarce = GetServerTypesAvailabilityResponseAvailability("scarce") - // GetServerTypesAvailabilityResponseAvailabilityShortage is [insert doc]. - GetServerTypesAvailabilityResponseAvailabilityShortage = GetServerTypesAvailabilityResponseAvailability("shortage") + // BootTypeLocal is [insert doc]. + BootTypeLocal = BootType("local") + // BootTypeBootscript is [insert doc]. + BootTypeBootscript = BootType("bootscript") + // BootTypeRescue is [insert doc]. + BootTypeRescue = BootType("rescue") ) -func (enum GetServerTypesAvailabilityResponseAvailability) String() string { +func (enum BootType) String() string { if enum == "" { // return default value if empty - return "available" + return "local" } return string(enum) } +func (enum BootType) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *BootType) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = BootType(BootType(tmp).String()) + return nil +} + type ImageState string const ( @@ -102,6 +134,85 @@ func (enum ImageState) String() string { return string(enum) } +func (enum ImageState) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *ImageState) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = ImageState(ImageState(tmp).String()) + return nil +} + +type PlacementGroupPolicyMode string + +const ( + // PlacementGroupPolicyModeOptional is [insert doc]. + PlacementGroupPolicyModeOptional = PlacementGroupPolicyMode("optional") + // PlacementGroupPolicyModeEnforced is [insert doc]. + PlacementGroupPolicyModeEnforced = PlacementGroupPolicyMode("enforced") +) + +func (enum PlacementGroupPolicyMode) String() string { + if enum == "" { + // return default value if empty + return "optional" + } + return string(enum) +} + +func (enum PlacementGroupPolicyMode) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *PlacementGroupPolicyMode) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = PlacementGroupPolicyMode(PlacementGroupPolicyMode(tmp).String()) + return nil +} + +type PlacementGroupPolicyType string + +const ( + // PlacementGroupPolicyTypeMaxAvailability is [insert doc]. + PlacementGroupPolicyTypeMaxAvailability = PlacementGroupPolicyType("max_availability") + // PlacementGroupPolicyTypeLowLatency is [insert doc]. + PlacementGroupPolicyTypeLowLatency = PlacementGroupPolicyType("low_latency") +) + +func (enum PlacementGroupPolicyType) String() string { + if enum == "" { + // return default value if empty + return "max_availability" + } + return string(enum) +} + +func (enum PlacementGroupPolicyType) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *PlacementGroupPolicyType) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = PlacementGroupPolicyType(PlacementGroupPolicyType(tmp).String()) + return nil +} + type SecurityGroupPolicy string const ( @@ -119,16 +230,31 @@ func (enum SecurityGroupPolicy) String() string { return string(enum) } -type SecurityRuleAction string +func (enum SecurityGroupPolicy) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *SecurityGroupPolicy) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = SecurityGroupPolicy(SecurityGroupPolicy(tmp).String()) + return nil +} + +type SecurityGroupRuleAction string const ( - // SecurityRuleActionAccept is [insert doc]. - SecurityRuleActionAccept = SecurityRuleAction("accept") - // SecurityRuleActionDrop is [insert doc]. - SecurityRuleActionDrop = SecurityRuleAction("drop") + // SecurityGroupRuleActionAccept is [insert doc]. + SecurityGroupRuleActionAccept = SecurityGroupRuleAction("accept") + // SecurityGroupRuleActionDrop is [insert doc]. + SecurityGroupRuleActionDrop = SecurityGroupRuleAction("drop") ) -func (enum SecurityRuleAction) String() string { +func (enum SecurityGroupRuleAction) String() string { if enum == "" { // return default value if empty return "accept" @@ -136,16 +262,31 @@ func (enum SecurityRuleAction) String() string { return string(enum) } -type SecurityRuleDirection string +func (enum SecurityGroupRuleAction) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *SecurityGroupRuleAction) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = SecurityGroupRuleAction(SecurityGroupRuleAction(tmp).String()) + return nil +} + +type SecurityGroupRuleDirection string const ( - // SecurityRuleDirectionInbound is [insert doc]. - SecurityRuleDirectionInbound = SecurityRuleDirection("inbound") - // SecurityRuleDirectionOutbound is [insert doc]. - SecurityRuleDirectionOutbound = SecurityRuleDirection("outbound") + // SecurityGroupRuleDirectionInbound is [insert doc]. + SecurityGroupRuleDirectionInbound = SecurityGroupRuleDirection("inbound") + // SecurityGroupRuleDirectionOutbound is [insert doc]. + SecurityGroupRuleDirectionOutbound = SecurityGroupRuleDirection("outbound") ) -func (enum SecurityRuleDirection) String() string { +func (enum SecurityGroupRuleDirection) String() string { if enum == "" { // return default value if empty return "inbound" @@ -153,25 +294,57 @@ func (enum SecurityRuleDirection) String() string { return string(enum) } -type SecurityRuleProtocol string +func (enum SecurityGroupRuleDirection) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *SecurityGroupRuleDirection) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = SecurityGroupRuleDirection(SecurityGroupRuleDirection(tmp).String()) + return nil +} + +type SecurityGroupRuleProtocol string const ( - // SecurityRuleProtocolTCP is [insert doc]. - SecurityRuleProtocolTCP = SecurityRuleProtocol("tcp") - // SecurityRuleProtocolUDP is [insert doc]. - SecurityRuleProtocolUDP = SecurityRuleProtocol("udp") - // SecurityRuleProtocolIcmp is [insert doc]. - SecurityRuleProtocolIcmp = SecurityRuleProtocol("icmp") + // SecurityGroupRuleProtocolTCP is [insert doc]. + SecurityGroupRuleProtocolTCP = SecurityGroupRuleProtocol("TCP") + // SecurityGroupRuleProtocolUDP is [insert doc]. + SecurityGroupRuleProtocolUDP = SecurityGroupRuleProtocol("UDP") + // SecurityGroupRuleProtocolICMP is [insert doc]. + SecurityGroupRuleProtocolICMP = SecurityGroupRuleProtocol("ICMP") + // SecurityGroupRuleProtocolANY is [insert doc]. + SecurityGroupRuleProtocolANY = SecurityGroupRuleProtocol("ANY") ) -func (enum SecurityRuleProtocol) String() string { +func (enum SecurityGroupRuleProtocol) String() string { if enum == "" { // return default value if empty - return "tcp" + return "TCP" } return string(enum) } +func (enum SecurityGroupRuleProtocol) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *SecurityGroupRuleProtocol) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = SecurityGroupRuleProtocol(SecurityGroupRuleProtocol(tmp).String()) + return nil +} + type ServerAction string const ( @@ -197,19 +370,19 @@ func (enum ServerAction) String() string { return string(enum) } -type ServerBootType string +func (enum ServerAction) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} -const ( - // ServerBootTypeLocal is [insert doc]. - ServerBootTypeLocal = ServerBootType("local") -) +func (enum *ServerAction) UnmarshalJSON(data []byte) error { + tmp := "" -func (enum ServerBootType) String() string { - if enum == "" { - // return default value if empty - return "local" + if err := json.Unmarshal(data, &tmp); err != nil { + return err } - return string(enum) + + *enum = ServerAction(ServerAction(tmp).String()) + return nil } type ServerState string @@ -237,6 +410,55 @@ func (enum ServerState) String() string { return string(enum) } +func (enum ServerState) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *ServerState) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = ServerState(ServerState(tmp).String()) + return nil +} + +type ServerTypesAvailability string + +const ( + // ServerTypesAvailabilityAvailable is [insert doc]. + ServerTypesAvailabilityAvailable = ServerTypesAvailability("available") + // ServerTypesAvailabilityScarce is [insert doc]. + ServerTypesAvailabilityScarce = ServerTypesAvailability("scarce") + // ServerTypesAvailabilityShortage is [insert doc]. + ServerTypesAvailabilityShortage = ServerTypesAvailability("shortage") +) + +func (enum ServerTypesAvailability) String() string { + if enum == "" { + // return default value if empty + return "available" + } + return string(enum) +} + +func (enum ServerTypesAvailability) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *ServerTypesAvailability) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = ServerTypesAvailability(ServerTypesAvailability(tmp).String()) + return nil +} + type SnapshotState string const ( @@ -256,6 +478,21 @@ func (enum SnapshotState) String() string { return string(enum) } +func (enum SnapshotState) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *SnapshotState) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = SnapshotState(SnapshotState(tmp).String()) + return nil +} + type TaskStatus string const ( @@ -279,6 +516,21 @@ func (enum TaskStatus) String() string { return string(enum) } +func (enum TaskStatus) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *TaskStatus) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = TaskStatus(TaskStatus(tmp).String()) + return nil +} + type VolumeState string const ( @@ -298,15 +550,28 @@ func (enum VolumeState) String() string { return string(enum) } +func (enum VolumeState) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *VolumeState) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = VolumeState(VolumeState(tmp).String()) + return nil +} + type VolumeType string const ( - // VolumeTypeLSsd is [insert doc]. - VolumeTypeLSsd = VolumeType("l_ssd") - // VolumeTypeLHdd is [insert doc]. - VolumeTypeLHdd = VolumeType("l_hdd") - // VolumeTypeRSsd is [insert doc]. - VolumeTypeRSsd = VolumeType("r_ssd") + // VolumeTypeLSSD is [insert doc]. + VolumeTypeLSSD = VolumeType("l_ssd") + // VolumeTypeBSSD is [insert doc]. + VolumeTypeBSSD = VolumeType("b_ssd") ) func (enum VolumeType) String() string { @@ -317,592 +582,721 @@ func (enum VolumeType) String() string { return string(enum) } +func (enum VolumeType) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, enum)), nil +} + +func (enum *VolumeType) UnmarshalJSON(data []byte) error { + tmp := "" + + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + *enum = VolumeType(VolumeType(tmp).String()) + return nil +} + +// Bootscript bootscript type Bootscript struct { - // Arch display the bootscripts arch + // Bootcmdargs the bootscript arguments + Bootcmdargs string `json:"bootcmdargs"` + // Default dispmay if the bootscript is the default bootscript if no other boot option is configured + Default bool `json:"default"` + // Dtb provide information regarding a Device Tree Binary (dtb) for use with C1 servers + Dtb string `json:"dtb"` + // ID the bootscript ID + ID string `json:"id"` + // Initrd the initrd (initial ramdisk) configuration + Initrd string `json:"initrd"` + // Kernel the server kernel version + Kernel string `json:"kernel"` + // Organization the bootscript organization + Organization string `json:"organization"` + // Public provide information if the bootscript is public + Public bool `json:"public"` + // Title the bootscript title + Title string `json:"title"` + // Arch the bootscript arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` - // Bootcmdargs display the bootscript parameters - Bootcmdargs string `json:"bootcmdargs,omitempty"` - // Default dispmay if the bootscript is the default bootscript if no other boot option is configured - Default bool `json:"default,omitempty"` - // Dtb provide information regarding a Device Tree Binary (dtb) for use with C1 servers - Dtb string `json:"dtb,omitempty"` - // ID display the bootscripts ID - ID string `json:"id,omitempty"` - // Initrd display the initrd (initial ramdisk) configuration - Initrd string `json:"initrd,omitempty"` - // Kernel display the server kernel version - Kernel string `json:"kernel,omitempty"` - // Organization display the bootscripts organization - Organization string `json:"organization,omitempty"` - // Public provide information if the bootscript is public - Public bool `json:"public,omitempty"` - // Title display the bootscripts title - Title string `json:"title,omitempty"` + Arch Arch `json:"arch"` + // Zone the zone in which is the bootscript + Zone scw.Zone `json:"zone"` } type CreateIPResponse struct { - IP *IP `json:"ip,omitempty"` + IP *IP `json:"ip"` - Location string `json:"Location,omitempty"` + Location string `json:"Location"` } type CreateImageResponse struct { - Image *Image `json:"image,omitempty"` + Image *Image `json:"image"` - Location string `json:"Location,omitempty"` + Location string `json:"Location"` +} + +type CreatePlacementGroupResponse struct { + PlacementGroup *PlacementGroup `json:"placement_group"` } type CreateSecurityGroupResponse struct { - SecurityGroup *SecurityGroup `json:"security_group,omitempty"` + SecurityGroup *SecurityGroup `json:"security_group"` } type CreateSecurityGroupRuleResponse struct { - SecurityRule *SecurityRule `json:"security_rule,omitempty"` + Rule *SecurityGroupRule `json:"rule"` } type CreateServerResponse struct { - Server *Server `json:"server,omitempty"` + Server *Server `json:"server"` } type CreateSnapshotResponse struct { - Snapshot *Snapshot `json:"snapshot,omitempty"` + Snapshot *Snapshot `json:"snapshot"` } type CreateVolumeResponse struct { - Volume *Volume `json:"volume,omitempty"` + Volume *Volume `json:"volume"` - Location string `json:"Location,omitempty"` + Location string `json:"Location"` } type Dashboard struct { - VolumesCount uint32 `json:"volumes_count,omitempty"` + VolumesCount uint32 `json:"volumes_count"` - RunningServersCount uint32 `json:"running_servers_count,omitempty"` + RunningServersCount uint32 `json:"running_servers_count"` - ServersByTypes map[string]uint32 `json:"servers_by_types,omitempty"` + ServersByTypes map[string]uint32 `json:"servers_by_types"` - ImagesCount uint32 `json:"images_count,omitempty"` + ImagesCount uint32 `json:"images_count"` - SnapshotsCount uint32 `json:"snapshots_count,omitempty"` + SnapshotsCount uint32 `json:"snapshots_count"` - ServersCount uint32 `json:"servers_count,omitempty"` + ServersCount uint32 `json:"servers_count"` - IpsCount uint32 `json:"ips_count,omitempty"` + IPsCount uint32 `json:"ips_count"` - SecurityGroupsCount uint32 `json:"security_groups_count,omitempty"` + SecurityGroupsCount uint32 `json:"security_groups_count"` - IpsUnused uint32 `json:"ips_unused,omitempty"` + IPsUnused uint32 `json:"ips_unused"` } type GetBootscriptResponse struct { - Bootscript *Bootscript `json:"bootscript,omitempty"` + Bootscript *Bootscript `json:"bootscript"` } type GetDashboardResponse struct { - Dashboard *Dashboard `json:"dashboard,omitempty"` + Dashboard *Dashboard `json:"dashboard"` } type GetIPResponse struct { - IP *IP `json:"ip,omitempty"` + IP *IP `json:"ip"` } type GetImageResponse struct { - Image *Image `json:"image,omitempty"` + Image *Image `json:"image"` +} + +type GetPlacementGroupResponse struct { + PlacementGroup *PlacementGroup `json:"placement_group"` +} + +type GetPlacementGroupServersResponse struct { + Servers []*PlacementGroupServer `json:"servers"` } type GetSecurityGroupResponse struct { - SecurityGroup *SecurityGroup `json:"security_group,omitempty"` + SecurityGroup *SecurityGroup `json:"security_group"` } type GetSecurityGroupRuleResponse struct { - SecurityRule *SecurityRule `json:"security_rule,omitempty"` + Rule *SecurityGroupRule `json:"rule"` } type GetServerResponse struct { - Server *Server `json:"server,omitempty"` + Server *Server `json:"server"` } type GetServerTypesAvailabilityResponse struct { - Servers map[string]GetServerTypesAvailabilityResponseAvailability `json:"servers,omitempty"` -} - -type GetServiceInfoResponse struct { - API string `json:"api,omitempty"` - - Description string `json:"description,omitempty"` - - Version string `json:"version,omitempty"` + Servers map[string]ServerTypesAvailability `json:"servers"` } type GetSnapshotResponse struct { - Snapshot *Snapshot `json:"snapshot,omitempty"` + Snapshot *Snapshot `json:"snapshot"` } type GetVolumeResponse struct { - Volume *Volume `json:"volume,omitempty"` + Volume *Volume `json:"volume"` } type IP struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Address net.IP `json:"address,omitempty"` + Address net.IP `json:"address"` - Reverse *string `json:"reverse,omitempty"` + Reverse *string `json:"reverse"` - Server *ServerSummary `json:"server,omitempty"` + Server *ServerSummary `json:"server"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` + + Zone scw.Zone `json:"zone"` } type Image struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Name string `json:"name,omitempty"` + Name string `json:"name"` // Arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` + Arch Arch `json:"arch"` - CreationDate time.Time `json:"creation_date,omitempty"` + CreationDate time.Time `json:"creation_date"` - ModificationDate time.Time `json:"modification_date,omitempty"` + ModificationDate time.Time `json:"modification_date"` - DefaultBootscript *Bootscript `json:"default_bootscript,omitempty"` + DefaultBootscript *Bootscript `json:"default_bootscript"` - ExtraVolumes map[string]*Volume `json:"extra_volumes,omitempty"` + ExtraVolumes map[string]*Volume `json:"extra_volumes"` - FromServer *ServerSummary `json:"from_server,omitempty"` + FromServer string `json:"from_server"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` - Public bool `json:"public,omitempty"` + Public bool `json:"public"` - RootVolume *VolumeTemplate `json:"root_volume,omitempty"` + RootVolume *VolumeSummary `json:"root_volume"` // State // // Default value: available - State ImageState `json:"state,omitempty"` + State ImageState `json:"state"` + + Zone scw.Zone `json:"zone"` } type ListBootscriptsResponse struct { - Bootscripts []*Bootscript `json:"bootscripts,omitempty"` + Bootscripts []*Bootscript `json:"bootscripts"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` +} + +type ListIPsResponse struct { + IPs []*IP `json:"ips"` + + TotalCount uint32 `json:"total_count"` } type ListImagesResponse struct { - Images []*Image `json:"images,omitempty"` + Images []*Image `json:"images"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } -type ListIpsResponse struct { - Ips []*IP `json:"ips,omitempty"` +type ListPlacementGroupsResponse struct { + PlacementGroups []*PlacementGroup `json:"placement_groups"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListSecurityGroupRulesResponse struct { - SecurityRules []*SecurityRule `json:"security_rules,omitempty"` + Rules []*SecurityGroupRule `json:"rules"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListSecurityGroupsResponse struct { - SecurityGroups []*SecurityGroup `json:"security_groups,omitempty"` + SecurityGroups []*SecurityGroup `json:"security_groups"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListServerActionsResponse struct { - Actions []ServerAction `json:"actions,omitempty"` + Actions []ServerAction `json:"actions"` } type ListServerUserDataResponse struct { - UserData []string `json:"user_data,omitempty"` + UserData []string `json:"user_data"` } type ListServersResponse struct { - Servers []*Server `json:"servers,omitempty"` + Servers []*Server `json:"servers"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListServersTypesResponse struct { - Servers map[string]*ServerTypeDefinition `json:"servers,omitempty"` + Servers map[string]*ServerType `json:"servers"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListSnapshotsResponse struct { - Snapshots []*Snapshot `json:"snapshots,omitempty"` + Snapshots []*Snapshot `json:"snapshots"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } type ListVolumesResponse struct { - Volumes []*Volume `json:"volumes,omitempty"` + Volumes []*Volume `json:"volumes"` - TotalCount uint32 `json:"total_count,omitempty"` + TotalCount uint32 `json:"total_count"` } +type NullableStringValue struct { + Null bool `json:"null,omitempty"` + + Value string `json:"value,omitempty"` +} + +// PlacementGroup placement group +type PlacementGroup struct { + // ID the placement group unique ID + ID string `json:"id"` + // Name the placement group name + Name string `json:"name"` + // Organization the placement group organization + Organization string `json:"organization"` + // PolicyMode select the failling mode when the placement cannot be respected, either optional or enforced + // + // Default value: optional + PolicyMode PlacementGroupPolicyMode `json:"policy_mode"` + // PolicyType select the behavior of the placement group, either low_latency (group) or max_availability (spread) + // + // Default value: max_availability + PolicyType PlacementGroupPolicyType `json:"policy_type"` + // PolicyRespected returns true if the policy is respected, false otherwise + PolicyRespected bool `json:"policy_respected"` + // Zone the zone in which is the placement group + Zone scw.Zone `json:"zone"` +} + +type PlacementGroupServer struct { + ID string `json:"id"` + + Name string `json:"name"` + + PolicyRespected bool `json:"policy_respected"` +} + +// SecurityGroup security group type SecurityGroup struct { - // ID display the security groups' unique ID - ID string `json:"id,omitempty"` - // Name display the security groups name - Name string `json:"name,omitempty"` - // CreationDate display the security group creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // ModificationDate display the security group modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // Description display the security groups description - Description string `json:"description,omitempty"` - // EnableDefaultSecurity display if the security group is set as default - EnableDefaultSecurity bool `json:"enable_default_security,omitempty"` - // InboundDefaultPolicy display the default inbound policy + // ID the security groups' unique ID + ID string `json:"id"` + // Name the security groups name + Name string `json:"name"` + // Description the security groups description + Description string `json:"description"` + // EnableDefaultSecurity true if SMTP is blocked on IPv4 and IPv6 + EnableDefaultSecurity bool `json:"enable_default_security"` + // InboundDefaultPolicy the default inbound policy // // Default value: accept - InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy,omitempty"` - // Organization display the security groups organization ID - Organization string `json:"organization,omitempty"` - // OrganizationDefault display if the security group is set as organization default - OrganizationDefault bool `json:"organization_default,omitempty"` - // OutboundDefaultPolicy display the default outbound policy + InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy"` + // OutboundDefaultPolicy the default outbound policy // // Default value: accept - OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy,omitempty"` + OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy"` + // Organization the security groups organization ID + Organization string `json:"organization"` + // OrganizationDefault true if it is your default security group for this organization + OrganizationDefault bool `json:"organization_default"` + // CreationDate the security group creation date + CreationDate time.Time `json:"creation_date"` + // ModificationDate the security group modification date + ModificationDate time.Time `json:"modification_date"` // Servers list of servers attached to this security group - Servers []*ServerSummary `json:"servers,omitempty"` + Servers []*ServerSummary `json:"servers"` // Stateful true if the security group is stateful - Stateful bool `json:"stateful,omitempty"` + Stateful bool `json:"stateful"` + // Zone the zone in which is the security group + Zone scw.Zone `json:"zone"` } -type SecurityGroupSummary struct { - ID string `json:"id,omitempty"` - - Name string `json:"name,omitempty"` -} - -type SecurityRule struct { - ID string `json:"id,omitempty"` +type SecurityGroupRule struct { + ID string `json:"id"` // Protocol // - // Default value: tcp - Protocol SecurityRuleProtocol `json:"protocol,omitempty"` + // Default value: TCP + Protocol SecurityGroupRuleProtocol `json:"protocol"` // Direction // // Default value: inbound - Direction SecurityRuleDirection `json:"direction,omitempty"` + Direction SecurityGroupRuleDirection `json:"direction"` // Action // // Default value: accept - Action SecurityRuleAction `json:"action,omitempty"` + Action SecurityGroupRuleAction `json:"action"` - IPRange string `json:"ip_range,omitempty"` + IPRange scw.IPNet `json:"ip_range"` - DestPortFrom uint32 `json:"dest_port_from,omitempty"` + DestPortFrom *uint32 `json:"dest_port_from"` - DestPortTo uint32 `json:"dest_port_to,omitempty"` + DestPortTo *uint32 `json:"dest_port_to"` - Position uint32 `json:"position,omitempty"` + Position uint32 `json:"position"` - Editable bool `json:"editable,omitempty"` + Editable bool `json:"editable"` + + Zone scw.Zone `json:"zone"` } -type Server struct { - // ID display the server unique ID +type SecurityGroupSummary struct { + ID string `json:"id"` + + Name string `json:"name"` +} + +type SecurityGroupTemplate struct { ID string `json:"id,omitempty"` - // Image provide information on the server image - Image *Image `json:"image,omitempty"` - // Name display the server name + Name string `json:"name,omitempty"` - // Organization display the server organization - Organization string `json:"organization,omitempty"` - // PrivateIP display the server private IP address - PrivateIP *string `json:"private_ip,omitempty"` - // PublicIP display the server public IP address - PublicIP *ServerIP `json:"public_ip,omitempty"` - // State display the server state +} + +// Server server +type Server struct { + // ID the server unique ID + ID string `json:"id"` + // Name the server name + Name string `json:"name"` + // Organization the server organization + Organization string `json:"organization"` + // AllowedActions provide as list of allowed actions on the server + AllowedActions []ServerAction `json:"allowed_actions"` + // Tags the server associated tags + Tags []string `json:"tags"` + // CommercialType the server commercial type (eg. GP1-M) + CommercialType string `json:"commercial_type"` + // CreationDate the server creation date + CreationDate time.Time `json:"creation_date"` + // DynamicIPRequired true if a dynamic IP is required + DynamicIPRequired bool `json:"dynamic_ip_required"` + // EnableIPv6 true if IPv6 is enabled + EnableIPv6 bool `json:"enable_ipv6"` + // Hostname the server host name + Hostname string `json:"hostname"` + // Image provide information on the server image + Image *Image `json:"image"` + // Protected the server protection option is activated + Protected bool `json:"protected"` + // PrivateIP the server private IP address + PrivateIP *string `json:"private_ip"` + // PublicIP information about the public IP + PublicIP *ServerIP `json:"public_ip"` + // ModificationDate the server modification date + ModificationDate time.Time `json:"modification_date"` + // State the server state // // Default value: running - State ServerState `json:"state,omitempty"` - // BootType display the server boot type + State ServerState `json:"state"` + // Location the server location + Location *ServerLocation `json:"location"` + // IPv6 the server IPv6 address + IPv6 *ServerIPv6 `json:"ipv6"` + // Bootscript the server bootscript + Bootscript *Bootscript `json:"bootscript"` + // BootType the server boot type // // Default value: local - BootType ServerBootType `json:"boot_type,omitempty"` - // Tags display the server associated tags - Tags []string `json:"tags,omitempty"` - // Volumes display the server volumes - Volumes map[string]*Volume `json:"volumes,omitempty"` - // Bootscript display the server bootscript - Bootscript *Bootscript `json:"bootscript,omitempty"` - // DynamicPublicIP display the server dynamic public IP - DynamicPublicIP bool `json:"dynamic_public_ip,omitempty"` - // CommercialType display the server commercial type (e.g. GP1-M) - CommercialType string `json:"commercial_type,omitempty"` - // CreationDate display the server creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // DynamicIPRequired display if a dynamic IP is required - DynamicIPRequired bool `json:"dynamic_ip_required,omitempty"` - // EnableIPv6 display if IPv6 is enabled - EnableIPv6 bool `json:"enable_ipv6,omitempty"` - // ExtraNetworks display information about additional network interfaces - ExtraNetworks []string `json:"extra_networks,omitempty"` - // Hostname display the server host name - Hostname string `json:"hostname,omitempty"` - // AllowedActions provide as list of allowed actions on the server - AllowedActions []ServerAction `json:"allowed_actions,omitempty"` - // Arch display the server arch + BootType BootType `json:"boot_type"` + // Volumes the server volumes + Volumes map[string]*Volume `json:"volumes"` + // SecurityGroup the server security group + SecurityGroup *SecurityGroupSummary `json:"security_group"` + // Maintenances the server planned maintenances + Maintenances []*ServerMaintenance `json:"maintenances"` + // StateDetail the server state_detail + StateDetail string `json:"state_detail"` + // Arch the server arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` - // IPv6 display the server IPv6 address - IPv6 *ServerIPv6 `json:"ipv6,omitempty"` - // Location display the server location - Location *ServerLocation `json:"location,omitempty"` - // Maintenances display the server planned maintenances - Maintenances []*ServerMaintenance `json:"maintenances,omitempty"` - // ModificationDate display the server modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // Protected display the server protection option is activated - Protected bool `json:"protected,omitempty"` - // SecurityGroup display the server security group - SecurityGroup *SecurityGroupSummary `json:"security_group,omitempty"` - // StateDetail display the server state_detail - StateDetail string `json:"state_detail,omitempty"` + Arch Arch `json:"arch"` + // PlacementGroup the server placement group + PlacementGroup *PlacementGroup `json:"placement_group"` + // Zone the zone in which is the server + Zone scw.Zone `json:"zone"` } type ServerActionResponse struct { - Task *Task `json:"task,omitempty"` + Task *Task `json:"task"` } +// ServerIP server. ip type ServerIP struct { - // ID display the unique ID of the IP address - ID string `json:"id,omitempty"` - // Address display the server public IPv4 IP-Address - Address net.IP `json:"address,omitempty"` - // Dynamic display information if the IP address will be considered as dynamic - Dynamic bool `json:"dynamic,omitempty"` + // ID the unique ID of the IP address + ID string `json:"id"` + // Address the server public IPv4 IP-Address + Address net.IP `json:"address"` + // Dynamic true if the IP address is dynamic + Dynamic bool `json:"dynamic"` } +// ServerIPv6 server. ipv6 type ServerIPv6 struct { - // Address display the server IPv6 IP-Address - Address net.IP `json:"address,omitempty"` - // Gateway display the IPv6 IP-addresses gateway - Gateway string `json:"gateway,omitempty"` - // Netmask display the IPv6 IP-addresses CIDR netmask - Netmask string `json:"netmask,omitempty"` + // Address the server IPv6 IP-Address + Address net.IP `json:"address"` + // Gateway the IPv6 IP-addresses gateway + Gateway net.IP `json:"gateway"` + // Netmask the IPv6 IP-addresses CIDR netmask + Netmask string `json:"netmask"` } type ServerLocation struct { - ClusterID string `json:"cluster_id,omitempty"` + ClusterID string `json:"cluster_id"` - HypervisorID string `json:"hypervisor_id,omitempty"` + HypervisorID string `json:"hypervisor_id"` - NodeID string `json:"node_id,omitempty"` + NodeID string `json:"node_id"` - PlatformID string `json:"platform_id,omitempty"` + PlatformID string `json:"platform_id"` - ZoneID string `json:"zone_id,omitempty"` + ZoneID string `json:"zone_id"` } type ServerMaintenance struct { } type ServerSummary struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Name string `json:"name,omitempty"` + Name string `json:"name"` } -type ServerTypeDefinition struct { - MonthlyPrice float32 `json:"monthly_price,omitempty"` +type ServerType struct { + MonthlyPrice float32 `json:"monthly_price"` - HourlyPrice float32 `json:"hourly_price,omitempty"` + HourlyPrice float32 `json:"hourly_price"` - AltNames map[uint32]string `json:"alt_names,omitempty"` + AltNames []string `json:"alt_names"` - PerVolumeConstraint map[string]*ServerTypeDefinitionVolumeConstraintSizes `json:"per_volume_constraint,omitempty"` + PerVolumeConstraint *ServerTypeVolumeConstraintsByType `json:"per_volume_constraint"` - VolumesConstraint *ServerTypeDefinitionVolumeConstraintSizes `json:"volumes_constraint,omitempty"` + VolumesConstraint *ServerTypeVolumeConstraintSizes `json:"volumes_constraint"` - Ncpus uint32 `json:"ncpus,omitempty"` + Ncpus uint32 `json:"ncpus"` - Gpu *uint64 `json:"gpu,omitempty"` + Gpu *uint64 `json:"gpu"` - RAM uint64 `json:"ram,omitempty"` + RAM uint64 `json:"ram"` // Arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` + Arch Arch `json:"arch"` - Baremetal bool `json:"baremetal,omitempty"` + Baremetal bool `json:"baremetal"` - Network *ServerTypeDefinitionNetwork `json:"network,omitempty"` + Network *ServerTypeNetwork `json:"network"` } -type ServerTypeDefinitionNetwork struct { - Interfaces []*ServerTypeDefinitionNetworkInterface `json:"interfaces,omitempty"` +type ServerTypeNetwork struct { + Interfaces []*ServerTypeNetworkInterface `json:"interfaces"` - SumInternalBandwidth *uint64 `json:"sum_internal_bandwidth,omitempty"` + SumInternalBandwidth *uint64 `json:"sum_internal_bandwidth"` - SumInternetBandwidth *uint64 `json:"sum_internet_bandwidth,omitempty"` + SumInternetBandwidth *uint64 `json:"sum_internet_bandwidth"` - IPv6Support bool `json:"ipv6_support,omitempty"` + IPv6Support bool `json:"ipv6_support"` } -type ServerTypeDefinitionNetworkInterface struct { - InternalBandwidth *uint64 `json:"internal_bandwidth,omitempty"` +type ServerTypeNetworkInterface struct { + InternalBandwidth *uint64 `json:"internal_bandwidth"` - InternetBandwidth *uint64 `json:"internet_bandwidth,omitempty"` + InternetBandwidth *uint64 `json:"internet_bandwidth"` } -type ServerTypeDefinitionVolumeConstraintSizes struct { - MinSize uint64 `json:"min_size,omitempty"` +type ServerTypeVolumeConstraintSizes struct { + MinSize scw.Size `json:"min_size"` - MaxSize uint64 `json:"max_size,omitempty"` + MaxSize scw.Size `json:"max_size"` } -type SetIPResponse struct { - IP *IP `json:"ip,omitempty"` +type ServerTypeVolumeConstraintsByType struct { + LSSD *ServerTypeVolumeConstraintSizes `json:"l_ssd"` } -type SetImageResponse struct { - Image *Image `json:"image,omitempty"` +type SetPlacementGroupResponse struct { + PlacementGroup *PlacementGroup `json:"placement_group"` } -type SetServerResponse struct { - Server *Server `json:"server,omitempty"` -} - -type SetSnapshotResponse struct { - Snapshot *Snapshot `json:"snapshot,omitempty"` -} - -type SetVolumeResponse struct { - Volume *Volume `json:"volume,omitempty"` +type SetPlacementGroupServersResponse struct { + Servers []*PlacementGroupServer `json:"servers"` } type Snapshot struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Name string `json:"name,omitempty"` + Name string `json:"name"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` // VolumeType // // Default value: l_ssd - VolumeType VolumeType `json:"volume_type,omitempty"` + VolumeType VolumeType `json:"volume_type"` - Size uint64 `json:"size,omitempty"` + Size scw.Size `json:"size"` // State // // Default value: available - State SnapshotState `json:"state,omitempty"` + State SnapshotState `json:"state"` - BaseVolume *SnapshotBaseVolume `json:"base_volume,omitempty"` + BaseVolume *SnapshotBaseVolume `json:"base_volume"` - CreationDate time.Time `json:"creation_date,omitempty"` + CreationDate time.Time `json:"creation_date"` - ModificationDate time.Time `json:"modification_date,omitempty"` + ModificationDate time.Time `json:"modification_date"` + + Zone scw.Zone `json:"zone"` } type SnapshotBaseVolume struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Name string `json:"name,omitempty"` + Name string `json:"name"` } +// Task task type Task struct { // ID the unique ID of the task - ID string `json:"id,omitempty"` + ID string `json:"id"` // Description the description of the task - Description string `json:"description,omitempty"` - - HrefFrom string `json:"href_from,omitempty"` - - HrefResult string `json:"href_result,omitempty"` - // Progress show the progress of the task in percent - Progress int32 `json:"progress,omitempty"` - // StartedAt display the task start date - StartedAt time.Time `json:"started_at,omitempty"` - // Status display the task status + Description string `json:"description"` + // Progress the progress of the task in percent + Progress int32 `json:"progress"` + // StartedAt the task start date + StartedAt time.Time `json:"started_at"` + // TerminatedAt the task end date + TerminatedAt time.Time `json:"terminated_at"` + // Status the task status // // Default value: pending - Status TaskStatus `json:"status,omitempty"` - // TerminatedAt display the task end date - TerminatedAt time.Time `json:"terminated_at,omitempty"` + Status TaskStatus `json:"status"` + + HrefFrom string `json:"href_from"` + + HrefResult string `json:"href_result"` + // Zone the zone in which is the task + Zone scw.Zone `json:"zone"` } type UpdateIPResponse struct { - IP *IP `json:"ip,omitempty"` + IP *IP `json:"ip"` } -type UpdateSecurityGroupResponse struct { - SecurityGroup *SecurityGroup `json:"security_group,omitempty"` +type UpdatePlacementGroupResponse struct { + PlacementGroup *PlacementGroup `json:"placement_group"` +} + +type UpdatePlacementGroupServersResponse struct { + Servers []*PlacementGroupServer `json:"servers"` } type UpdateServerResponse struct { - Server *Server `json:"server,omitempty"` + Server *Server `json:"server"` } +// Volume volume type Volume struct { - // ID display the volumes unique ID - ID string `json:"id,omitempty"` - // Name display the volumes names - Name string `json:"name,omitempty"` + // ID the volumes unique ID + ID string `json:"id"` + // Name the volumes names + Name string `json:"name"` // ExportURI show the volumes NBD export URI - ExportURI string `json:"export_uri,omitempty"` - // Organization display the volumes organization - Organization string `json:"organization,omitempty"` - // Server display information about the server attached to the volume - Server *ServerSummary `json:"server,omitempty"` - // Size display the volumes disk size - Size uint64 `json:"size,omitempty"` - // VolumeType display the volumes type + ExportURI string `json:"export_uri"` + // Size the volumes disk size + Size scw.Size `json:"size"` + // VolumeType the volumes type // // Default value: l_ssd - VolumeType VolumeType `json:"volume_type,omitempty"` - // CreationDate display the volumes creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // ModificationDate display the volumes modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // State display the volumes state + VolumeType VolumeType `json:"volume_type"` + // CreationDate the volumes creation date + CreationDate time.Time `json:"creation_date"` + // ModificationDate the volumes modification date + ModificationDate time.Time `json:"modification_date"` + // Organization the volumes organization + Organization string `json:"organization"` + // Server the server attached to the volume + Server *ServerSummary `json:"server"` + // State the volumes state // // Default value: available - State VolumeState `json:"state,omitempty"` + State VolumeState `json:"state"` + // Zone the zone in which is the volume + Zone scw.Zone `json:"zone"` } +type VolumeSummary struct { + ID string `json:"id"` + + Name string `json:"name"` + + Size scw.Size `json:"size"` + // VolumeType + // + // Default value: l_ssd + VolumeType VolumeType `json:"volume_type"` +} + +// VolumeTemplate volume template type VolumeTemplate struct { - // ID display the volumes unique ID + // ID uUID of the volume ID string `json:"id,omitempty"` - // Name display the volumes name + // Name name of the volume Name string `json:"name,omitempty"` - // Size display the volumes disk size - Size uint64 `json:"size,omitempty"` - // VolumeType display the volumes type + // Size disk size of the volume + Size scw.Size `json:"size,omitempty"` + // VolumeType type of the volume // // Default value: l_ssd VolumeType VolumeType `json:"volume_type,omitempty"` - // Organization the organization ID + // Organization organization ID of the volume Organization string `json:"organization,omitempty"` } +// setIPResponse set ip response +type setIPResponse struct { + IP *IP `json:"ip"` +} + +// setImageResponse set image response +type setImageResponse struct { + Image *Image `json:"image"` +} + +// setSecurityGroupResponse set security group response +type setSecurityGroupResponse struct { + SecurityGroup *SecurityGroup `json:"security_group"` +} + +// setSecurityGroupRuleResponse set security group rule response +type setSecurityGroupRuleResponse struct { + Rule *SecurityGroupRule `json:"rule"` +} + +// setServerResponse set server response +type setServerResponse struct { + Server *Server `json:"server"` +} + +// setSnapshotResponse set snapshot response +type setSnapshotResponse struct { + Snapshot *Snapshot `json:"snapshot"` +} + // Service API type GetServerTypesAvailabilityRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` - PerPage *int32 `json:"-"` + PerPage *uint32 `json:"-"` Page *int32 `json:"-"` } // GetServerTypesAvailability get availability // -// Get availibility for all server types +// Get availibility for all server types. func (s *API) GetServerTypesAvailability(req *GetServerTypesAvailabilityRequest, opts ...scw.RequestOption) (*GetServerTypesAvailabilityResponse, error) { var err error @@ -941,16 +1335,16 @@ func (s *API) GetServerTypesAvailability(req *GetServerTypesAvailabilityRequest, } type ListServersTypesRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` - PerPage *int32 `json:"-"` + PerPage *uint32 `json:"-"` Page *int32 `json:"-"` } // ListServersTypes list server types // -// Get server types technical details +// Get server types technical details. func (s *API) ListServersTypes(req *ListServersTypesRequest, opts ...scw.RequestOption) (*ListServersTypesResponse, error) { var err error @@ -989,26 +1383,33 @@ func (s *API) ListServersTypes(req *ListServersTypesRequest, opts ...scw.Request } type ListServersRequest struct { - Zone utils.Zone `json:"-"` - - Organization *string `json:"-"` - - PerPage *int32 `json:"-"` - + Zone scw.Zone `json:"-"` + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return Page *int32 `json:"-"` - + // Organization list only servers of this organization + Organization *string `json:"-"` + // Name filter servers by name (for eg. "server1" will return "server100" and "server1" but not "foo") Name *string `json:"-"` + // PrivateIP list servers by private_ip + PrivateIP *net.IP `json:"-"` + // WithoutIP list servers that are not attached to a public IP + WithoutIP *bool `json:"-"` + // CommercialType list servers of this commercial type + CommercialType *string `json:"-"` + // State list servers in this state + // + // Default value: running + State *ServerState `json:"-"` } // ListServers list servers func (s *API) ListServers(req *ListServersRequest, opts ...scw.RequestOption) (*ListServersResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -1020,10 +1421,14 @@ func (s *API) ListServers(req *ListServersRequest, opts ...scw.RequestOption) (* } query := url.Values{} - parameter.AddToQuery(query, "organization", req.Organization) parameter.AddToQuery(query, "per_page", req.PerPage) parameter.AddToQuery(query, "page", req.Page) + parameter.AddToQuery(query, "organization", req.Organization) parameter.AddToQuery(query, "name", req.Name) + parameter.AddToQuery(query, "private_ip", req.PrivateIP) + parameter.AddToQuery(query, "without_ip", req.WithoutIP) + parameter.AddToQuery(query, "commercial_type", req.CommercialType) + parameter.AddToQuery(query, "state", req.State) if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") @@ -1047,13 +1452,13 @@ func (s *API) ListServers(req *ListServersRequest, opts ...scw.RequestOption) (* // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListServersResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListServersResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListServersResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListServersResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListServersResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -1061,43 +1466,47 @@ func (r *ListServersResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) r.Servers = append(r.Servers, results.Servers...) r.TotalCount += uint32(len(results.Servers)) - return len(results.Servers), nil + return uint32(len(results.Servers)), nil } type CreateServerRequest struct { - Zone utils.Zone `json:"-"` - // Name display the server name + Zone scw.Zone `json:"-"` + // Name the server name Name string `json:"name,omitempty"` // DynamicIPRequired define if a dynamic IP is required for the instance - DynamicIPRequired bool `json:"dynamic_ip_required,omitempty"` + DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"` // CommercialType define the server commercial type (i.e. GP1-S) CommercialType string `json:"commercial_type,omitempty"` - // Image define the server image id + // Image the server image ID or label Image string `json:"image,omitempty"` - // Volumes define the volumes attached to the server + // Volumes the volumes attached to the server Volumes map[string]*VolumeTemplate `json:"volumes,omitempty"` - // EnableIPv6 define if IPv6 is enabled on the server + // EnableIPv6 true if IPv6 is enabled on the server EnableIPv6 bool `json:"enable_ipv6,omitempty"` - // PublicIP define the public IPv4 attached to the server - PublicIP string `json:"public_ip,omitempty"` - // BootType define the boot type you want to use + // PublicIP the ID of the reserved IP to attach to the server + PublicIP *string `json:"public_ip,omitempty"` + // BootType the boot type to use // // Default value: local - BootType ServerBootType `json:"boot_type,omitempty"` - // Organization define the server organization + BootType *BootType `json:"boot_type,omitempty"` + // Bootscript the bootscript ID to use when `boot_type` is set to `bootscript` + Bootscript *string `json:"bootscript,omitempty"` + // Organization the server organization ID Organization string `json:"organization,omitempty"` - // Tags define the server tags + // Tags the server tags Tags []string `json:"tags,omitempty"` - // SecurityGroup define the security group id - SecurityGroup string `json:"security_group,omitempty"` + // SecurityGroup the security group ID + SecurityGroup *string `json:"security_group,omitempty"` + // PlacementGroup placement group ID if server must be part of a placement group + PlacementGroup *string `json:"placement_group,omitempty"` } -// CreateServer create server -func (s *API) CreateServer(req *CreateServerRequest, opts ...scw.RequestOption) (*CreateServerResponse, error) { +// createServer create server +func (s *API) createServer(req *CreateServerRequest, opts ...scw.RequestOption) (*CreateServerResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -1106,6 +1515,10 @@ func (s *API) CreateServer(req *CreateServerRequest, opts ...scw.RequestOption) req.Zone = defaultZone } + if req.Name == "" { + req.Name = namegenerator.GetRandomName("srv") + } + if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") } @@ -1131,14 +1544,14 @@ func (s *API) CreateServer(req *CreateServerRequest, opts ...scw.RequestOption) } type DeleteServerRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ServerID string `json:"-"` } // DeleteServer delete server // -// Delete a server with the given id +// Delete a server with the given ID. func (s *API) DeleteServer(req *DeleteServerRequest, opts ...scw.RequestOption) error { var err error @@ -1169,14 +1582,14 @@ func (s *API) DeleteServer(req *DeleteServerRequest, opts ...scw.RequestOption) } type GetServerRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ServerID string `json:"-"` } // GetServer get server // -// Get the details of a specified Server +// Get the details of a specified Server. func (s *API) GetServer(req *GetServerRequest, opts ...scw.RequestOption) (*GetServerResponse, error) { var err error @@ -1208,75 +1621,73 @@ func (s *API) GetServer(req *GetServerRequest, opts ...scw.RequestOption) (*GetS return &resp, nil } -type SetServerRequest struct { - Zone utils.Zone `json:"-"` - // ID display the server unique ID +type setServerRequest struct { + Zone scw.Zone `json:"-"` + // ID the server unique ID ID string `json:"-"` - // Name display the server name - Name string `json:"name,omitempty"` - // Organization display the server organization - Organization string `json:"organization,omitempty"` + // Name the server name + Name string `json:"name"` + // Organization the server organization + Organization string `json:"organization"` // AllowedActions provide as list of allowed actions on the server - AllowedActions []ServerAction `json:"allowed_actions,omitempty"` - // Tags display the server associated tags - Tags []string `json:"tags,omitempty"` - // CommercialType display the server commercial type (e.g. GP1-M) - CommercialType string `json:"commercial_type,omitempty"` - // CreationDate display the server creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // DynamicIPRequired display if a dynamic IP is required - DynamicIPRequired bool `json:"dynamic_ip_required,omitempty"` - // DynamicPublicIP display the server dynamic public IP - DynamicPublicIP bool `json:"dynamic_public_ip,omitempty"` - // EnableIPv6 display if IPv6 is enabled - EnableIPv6 bool `json:"enable_ipv6,omitempty"` - // ExtraNetworks display information about additional network interfaces - ExtraNetworks []string `json:"extra_networks,omitempty"` - // Hostname display the server host name - Hostname string `json:"hostname,omitempty"` + AllowedActions []ServerAction `json:"allowed_actions"` + // Tags the server associated tags + Tags []string `json:"tags"` + // CommercialType the server commercial type (eg. GP1-M) + CommercialType string `json:"commercial_type"` + // CreationDate the server creation date + CreationDate time.Time `json:"creation_date"` + // DynamicIPRequired true if a dynamic IP is required + DynamicIPRequired bool `json:"dynamic_ip_required"` + // EnableIPv6 true if IPv6 is enabled + EnableIPv6 bool `json:"enable_ipv6"` + // Hostname the server host name + Hostname string `json:"hostname"` // Image provide information on the server image - Image *Image `json:"image,omitempty"` - // Protected display the server protection option is activated - Protected bool `json:"protected,omitempty"` - // PrivateIP display the server private IP address - PrivateIP *string `json:"private_ip,omitempty"` - // PublicIP display the server public IP address - PublicIP *ServerIP `json:"public_ip,omitempty"` - // ModificationDate display the server modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // State display the server state + Image *Image `json:"image"` + // Protected the server protection option is activated + Protected bool `json:"protected"` + // PrivateIP the server private IP address + PrivateIP *string `json:"private_ip"` + // PublicIP information about the public IP + PublicIP *ServerIP `json:"public_ip"` + // ModificationDate the server modification date + ModificationDate time.Time `json:"modification_date"` + // State the server state // // Default value: running - State ServerState `json:"state,omitempty"` - // Location display the server location - Location *ServerLocation `json:"location,omitempty"` - // IPv6 display the server IPv6 address - IPv6 *ServerIPv6 `json:"ipv6,omitempty"` - // Bootscript display the server bootscript - Bootscript *Bootscript `json:"bootscript,omitempty"` - // BootType display the server boot type + State ServerState `json:"state"` + // Location the server location + Location *ServerLocation `json:"location"` + // IPv6 the server IPv6 address + IPv6 *ServerIPv6 `json:"ipv6"` + // Bootscript the server bootscript + Bootscript *Bootscript `json:"bootscript"` + // BootType the server boot type // // Default value: local - BootType ServerBootType `json:"boot_type,omitempty"` - // Volumes display the server volumes - Volumes map[string]*Volume `json:"volumes,omitempty"` - // SecurityGroup display the server security group - SecurityGroup *SecurityGroupSummary `json:"security_group,omitempty"` - // Maintenances display the server planned maintenances - Maintenances []*ServerMaintenance `json:"maintenances,omitempty"` - // StateDetail display the server state_detail - StateDetail string `json:"state_detail,omitempty"` - // Arch display the server arch + BootType BootType `json:"boot_type"` + // Volumes the server volumes + Volumes map[string]*Volume `json:"volumes"` + // SecurityGroup the server security group + SecurityGroup *SecurityGroupSummary `json:"security_group"` + // Maintenances the server planned maintenances + Maintenances []*ServerMaintenance `json:"maintenances"` + // StateDetail the server state_detail + StateDetail string `json:"state_detail"` + // Arch the server arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` + Arch Arch `json:"arch"` + // PlacementGroup the server placement group + PlacementGroup *PlacementGroup `json:"placement_group"` } -func (s *API) SetServer(req *SetServerRequest, opts ...scw.RequestOption) (*SetServerResponse, error) { +func (s *API) setServer(req *setServerRequest, opts ...scw.RequestOption) (*setServerResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -1304,7 +1715,7 @@ func (s *API) SetServer(req *SetServerRequest, opts ...scw.RequestOption) (*SetS return nil, err } - var resp SetServerResponse + var resp setServerResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -1314,35 +1725,35 @@ func (s *API) SetServer(req *SetServerRequest, opts ...scw.RequestOption) (*SetS } type UpdateServerRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // ServerID uUID of the server ServerID string `json:"-"` - + // Name name of the server Name *string `json:"name,omitempty"` // BootType // // Default value: local - BootType ServerBootType `json:"boot_type,omitempty"` - + BootType *BootType `json:"boot_type,omitempty"` + // Tags tags of the server Tags *[]string `json:"tags,omitempty"` Volumes *map[string]*VolumeTemplate `json:"volumes,omitempty"` - Bootscript *Bootscript `json:"bootscript,omitempty"` + Bootscript *string `json:"bootscript,omitempty"` DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"` EnableIPv6 *bool `json:"enable_ipv6,omitempty"` - ExtraNetworks *[]string `json:"extra_networks,omitempty"` - Protected *bool `json:"protected,omitempty"` - SecurityGroup *SecurityGroupSummary `json:"security_group,omitempty"` + SecurityGroup *SecurityGroupTemplate `json:"security_group,omitempty"` + // PlacementGroup placement group ID if server must be part of a placement group + PlacementGroup *NullableStringValue `json:"placement_group,omitempty"` } -// UpdateServer update server -func (s *API) UpdateServer(req *UpdateServerRequest, opts ...scw.RequestOption) (*UpdateServerResponse, error) { +// updateServer update server +func (s *API) updateServer(req *UpdateServerRequest, opts ...scw.RequestOption) (*UpdateServerResponse, error) { var err error if req.Zone == "" { @@ -1379,14 +1790,14 @@ func (s *API) UpdateServer(req *UpdateServerRequest, opts ...scw.RequestOption) } type ListServerActionsRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ServerID string `json:"-"` } // ListServerActions list server actions // -// Liste all actions that can currently be performed on a server +// Liste all actions that can currently be performed on a server. func (s *API) ListServerActions(req *ListServerActionsRequest, opts ...scw.RequestOption) (*ListServerActionsResponse, error) { var err error @@ -1419,18 +1830,18 @@ func (s *API) ListServerActions(req *ListServerActionsRequest, opts ...scw.Reque } type ServerActionRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ServerID string `json:"-"` // Action // // Default value: poweron - Action ServerAction `json:"action,omitempty"` + Action ServerAction `json:"action"` } // ServerAction perform action // -// Perform power related actions on a server +// Perform power related actions on a server. Be wary that when terminating a server, all the attached volumes (local *and* block storage) are deleted. So, if you want to keep your local volumes, you must use the `archive` action instead of `terminate`. And if you want to keep block-storage volumes, **you must** detach it beforehand you issue the `terminate` call. For more information, read the [Volumes](#volumes-7e8a39) documentation. func (s *API) ServerAction(req *ServerActionRequest, opts ...scw.RequestOption) (*ServerActionResponse, error) { var err error @@ -1468,14 +1879,14 @@ func (s *API) ServerAction(req *ServerActionRequest, opts ...scw.RequestOption) } type ListServerUserDataRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // ServerID uUID of the server ServerID string `json:"-"` } // ListServerUserData list user data // -// List all user data keys register on a given server +// List all user data keys registered on a given server. func (s *API) ListServerUserData(req *ListServerUserDataRequest, opts ...scw.RequestOption) (*ListServerUserDataResponse, error) { var err error @@ -1508,16 +1919,16 @@ func (s *API) ListServerUserData(req *ListServerUserDataRequest, opts ...scw.Req } type DeleteServerUserDataRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // ServerID uUID of the server ServerID string `json:"-"` - + // Key key of the user data to delete Key string `json:"-"` } // DeleteServerUserData delete user data // -// Delete the given key from a server user data +// Delete the given key from a server user data. func (s *API) DeleteServerUserData(req *DeleteServerUserDataRequest, opts ...scw.RequestOption) error { var err error @@ -1551,130 +1962,28 @@ func (s *API) DeleteServerUserData(req *DeleteServerUserDataRequest, opts ...scw return nil } -type SetServerUserDataRequest struct { - Zone utils.Zone `json:"-"` - - ServerID string `json:"-"` - - Key string `json:"-"` - - Content *utils.File -} - -// SetServerUserData add/Set user data -// -// Add or update a user data with the given key on a server -func (s *API) SetServerUserData(req *SetServerUserDataRequest, opts ...scw.RequestOption) error { - var err error - - if req.Zone == "" { - defaultZone, _ := s.client.GetDefaultZone() - req.Zone = defaultZone - } - - if fmt.Sprint(req.Zone) == "" { - return errors.New("field Zone cannot be empty in request") - } - - if fmt.Sprint(req.ServerID) == "" { - return errors.New("field ServerID cannot be empty in request") - } - - if fmt.Sprint(req.Key) == "" { - return errors.New("field Key cannot be empty in request") - } - - scwReq := &scw.ScalewayRequest{ - Method: "PATCH", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/servers/" + fmt.Sprint(req.ServerID) + "/user_data/" + fmt.Sprint(req.Key) + "", - Headers: http.Header{}, - } - - err = scwReq.SetBody(req.Content) - if err != nil { - return err - } - - err = s.client.Do(scwReq, nil, opts...) - if err != nil { - return err - } - return nil -} - -type GetServerUserDataRequest struct { - Zone utils.Zone `json:"-"` - - ServerID string `json:"-"` - - Key string `json:"-"` -} - -// GetServerUserData get user data -// -// Get the content of a user data with the given key on a server -func (s *API) GetServerUserData(req *GetServerUserDataRequest, opts ...scw.RequestOption) (*utils.File, error) { - var err error - - if req.Zone == "" { - defaultZone, _ := s.client.GetDefaultZone() - req.Zone = defaultZone - } - - if fmt.Sprint(req.Zone) == "" { - return nil, errors.New("field Zone cannot be empty in request") - } - - if fmt.Sprint(req.ServerID) == "" { - return nil, errors.New("field ServerID cannot be empty in request") - } - - if fmt.Sprint(req.Key) == "" { - return nil, errors.New("field Key cannot be empty in request") - } - - scwReq := &scw.ScalewayRequest{ - Method: "GET", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/servers/" + fmt.Sprint(req.ServerID) + "/user_data/" + fmt.Sprint(req.Key) + "", - Headers: http.Header{}, - } - - var resp utils.File - - err = s.client.Do(scwReq, &resp, opts...) - if err != nil { - return nil, err - } - return &resp, nil -} - type ListImagesRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` Organization *string `json:"-"` - PerPage *int32 `json:"-"` + PerPage *uint32 `json:"-"` Page *int32 `json:"-"` Name *string `json:"-"` - Public bool `json:"-"` + Public *bool `json:"-"` Arch *string `json:"-"` } // ListImages list images // -// List all images available in an account +// List all images available in an account. func (s *API) ListImages(req *ListImagesRequest, opts ...scw.RequestOption) (*ListImagesResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -1715,13 +2024,13 @@ func (s *API) ListImages(req *ListImagesRequest, opts ...scw.RequestOption) (*Li // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListImagesResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListImagesResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListImagesResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListImagesResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListImagesResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -1729,18 +2038,18 @@ func (r *ListImagesResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { r.Images = append(r.Images, results.Images...) r.TotalCount += uint32(len(results.Images)) - return len(results.Images), nil + return uint32(len(results.Images)), nil } type GetImageRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ImageID string `json:"-"` } // GetImage get image // -// Get details of an image with the given id +// Get details of an image with the given ID. func (s *API) GetImage(req *GetImageRequest, opts ...scw.RequestOption) (*GetImageResponse, error) { var err error @@ -1773,22 +2082,22 @@ func (s *API) GetImage(req *GetImageRequest, opts ...scw.RequestOption) (*GetIma } type CreateImageRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // Name name of the image Name string `json:"name,omitempty"` - + // RootVolume uUID of the snapshot RootVolume string `json:"root_volume,omitempty"` - // Arch + // Arch architecture of the image // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` - - DefaultBootscript *Bootscript `json:"default_bootscript,omitempty"` - - ExtraVolumes map[string]*Volume `json:"extra_volumes,omitempty"` - + Arch Arch `json:"arch"` + // DefaultBootscript default bootscript of the image + DefaultBootscript string `json:"default_bootscript,omitempty"` + // ExtraVolumes additional volumes of the image + ExtraVolumes map[string]*VolumeTemplate `json:"extra_volumes,omitempty"` + // Organization organization ID of the image Organization string `json:"organization,omitempty"` - + // Public true to create a public image Public bool `json:"public,omitempty"` } @@ -1797,7 +2106,7 @@ func (s *API) CreateImage(req *CreateImageRequest, opts ...scw.RequestOption) (* var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -1806,6 +2115,10 @@ func (s *API) CreateImage(req *CreateImageRequest, opts ...scw.RequestOption) (* req.Zone = defaultZone } + if req.Name == "" { + req.Name = namegenerator.GetRandomName("img") + } + if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") } @@ -1831,45 +2144,45 @@ func (s *API) CreateImage(req *CreateImageRequest, opts ...scw.RequestOption) (* } type SetImageRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ID string `json:"-"` - Name string `json:"name,omitempty"` + Name string `json:"name"` // Arch // // Default value: x86_64 - Arch Arch `json:"arch,omitempty"` + Arch Arch `json:"arch"` - CreationDate time.Time `json:"creation_date,omitempty"` + CreationDate time.Time `json:"creation_date"` - ModificationDate time.Time `json:"modification_date,omitempty"` + ModificationDate time.Time `json:"modification_date"` - DefaultBootscript *Bootscript `json:"default_bootscript,omitempty"` + DefaultBootscript *Bootscript `json:"default_bootscript"` - ExtraVolumes map[string]*Volume `json:"extra_volumes,omitempty"` + ExtraVolumes map[string]*Volume `json:"extra_volumes"` - FromServer *ServerSummary `json:"from_server,omitempty"` + FromServer string `json:"from_server"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` - Public bool `json:"public,omitempty"` + Public bool `json:"public"` - RootVolume *VolumeTemplate `json:"root_volume,omitempty"` + RootVolume *VolumeSummary `json:"root_volume"` // State // // Default value: available - State ImageState `json:"state,omitempty"` + State ImageState `json:"state"` } -// SetImage update image +// setImage update image // -// Replace all image properties with an image message -func (s *API) SetImage(req *SetImageRequest, opts ...scw.RequestOption) (*SetImageResponse, error) { +// Replace all image properties with an image message. +func (s *API) setImage(req *SetImageRequest, opts ...scw.RequestOption) (*setImageResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -1897,7 +2210,7 @@ func (s *API) SetImage(req *SetImageRequest, opts ...scw.RequestOption) (*SetIma return nil, err } - var resp SetImageResponse + var resp setImageResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -1907,14 +2220,14 @@ func (s *API) SetImage(req *SetImageRequest, opts ...scw.RequestOption) (*SetIma } type DeleteImageRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ImageID string `json:"-"` } // DeleteImage delete image // -// Delete the image with the given id +// Delete the image with the given ID. func (s *API) DeleteImage(req *DeleteImageRequest, opts ...scw.RequestOption) error { var err error @@ -1945,11 +2258,11 @@ func (s *API) DeleteImage(req *DeleteImageRequest, opts ...scw.RequestOption) er } type ListSnapshotsRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` Organization *string `json:"-"` - PerPage *int32 `json:"-"` + PerPage *uint32 `json:"-"` Page *int32 `json:"-"` @@ -1960,11 +2273,6 @@ type ListSnapshotsRequest struct { func (s *API) ListSnapshots(req *ListSnapshotsRequest, opts ...scw.RequestOption) (*ListSnapshotsResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -2003,13 +2311,13 @@ func (s *API) ListSnapshots(req *ListSnapshotsRequest, opts ...scw.RequestOption // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListSnapshotsResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListSnapshotsResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListSnapshotsResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListSnapshotsResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListSnapshotsResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -2017,17 +2325,17 @@ func (r *ListSnapshotsResponse) UnsafeAppend(res interface{}) (int, scw.SdkError r.Snapshots = append(r.Snapshots, results.Snapshots...) r.TotalCount += uint32(len(results.Snapshots)) - return len(results.Snapshots), nil + return uint32(len(results.Snapshots)), nil } type CreateSnapshotRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // Name name of the snapshot + Name string `json:"name,omitempty"` + // VolumeID uUID of the volume VolumeID string `json:"volume_id,omitempty"` Organization string `json:"organization,omitempty"` - - Name string `json:"name,omitempty"` } // CreateSnapshot create snapshot @@ -2035,7 +2343,7 @@ func (s *API) CreateSnapshot(req *CreateSnapshotRequest, opts ...scw.RequestOpti var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -2044,6 +2352,10 @@ func (s *API) CreateSnapshot(req *CreateSnapshotRequest, opts ...scw.RequestOpti req.Zone = defaultZone } + if req.Name == "" { + req.Name = namegenerator.GetRandomName("snp") + } + if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") } @@ -2069,14 +2381,14 @@ func (s *API) CreateSnapshot(req *CreateSnapshotRequest, opts ...scw.RequestOpti } type GetSnapshotRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SnapshotID string `json:"-"` } // GetSnapshot get snapshot // -// Get details of a snapshot with the given id +// Get details of a snapshot with the given ID. func (s *API) GetSnapshot(req *GetSnapshotRequest, opts ...scw.RequestOption) (*GetSnapshotResponse, error) { var err error @@ -2109,39 +2421,39 @@ func (s *API) GetSnapshot(req *GetSnapshotRequest, opts ...scw.RequestOption) (* } type SetSnapshotRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ID string `json:"-"` - Name string `json:"name,omitempty"` + Name string `json:"name"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` // VolumeType // // Default value: l_ssd - VolumeType VolumeType `json:"volume_type,omitempty"` + VolumeType VolumeType `json:"volume_type"` - Size uint64 `json:"size,omitempty"` + Size scw.Size `json:"size"` // State // // Default value: available - State SnapshotState `json:"state,omitempty"` + State SnapshotState `json:"state"` - BaseVolume *SnapshotBaseVolume `json:"base_volume,omitempty"` + BaseVolume *SnapshotBaseVolume `json:"base_volume"` - CreationDate time.Time `json:"creation_date,omitempty"` + CreationDate time.Time `json:"creation_date"` - ModificationDate time.Time `json:"modification_date,omitempty"` + ModificationDate time.Time `json:"modification_date"` } -// SetSnapshot update snapshot +// setSnapshot update snapshot // -// Replace all snapshot properties with a snapshot message -func (s *API) SetSnapshot(req *SetSnapshotRequest, opts ...scw.RequestOption) (*SetSnapshotResponse, error) { +// Replace all snapshot properties with a snapshot message. +func (s *API) setSnapshot(req *SetSnapshotRequest, opts ...scw.RequestOption) (*setSnapshotResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -2169,7 +2481,7 @@ func (s *API) SetSnapshot(req *SetSnapshotRequest, opts ...scw.RequestOption) (* return nil, err } - var resp SetSnapshotResponse + var resp setSnapshotResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -2179,14 +2491,14 @@ func (s *API) SetSnapshot(req *SetSnapshotRequest, opts ...scw.RequestOption) (* } type DeleteSnapshotRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SnapshotID string `json:"-"` } // DeleteSnapshot delete snapshot // -// Delete the snapshot with the given id +// Delete the snapshot with the given ID. func (s *API) DeleteSnapshot(req *DeleteSnapshotRequest, opts ...scw.RequestOption) error { var err error @@ -2217,14 +2529,20 @@ func (s *API) DeleteSnapshot(req *DeleteSnapshotRequest, opts ...scw.RequestOpti } type ListVolumesRequest struct { - Zone utils.Zone `json:"-"` - - Organization *string `json:"-"` - - PerPage *int32 `json:"-"` - + Zone scw.Zone `json:"-"` + // VolumeType filter by volume type + // + // Default value: l_ssd + VolumeType VolumeType `json:"-"` + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return Page *int32 `json:"-"` - + // Organization filter volume by organization + Organization *string `json:"-"` + // Name filter volume by name (for eg. "vol" will return "myvolume" but not "data") Name *string `json:"-"` } @@ -2232,11 +2550,6 @@ type ListVolumesRequest struct { func (s *API) ListVolumes(req *ListVolumesRequest, opts ...scw.RequestOption) (*ListVolumesResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -2248,9 +2561,10 @@ func (s *API) ListVolumes(req *ListVolumesRequest, opts ...scw.RequestOption) (* } query := url.Values{} - parameter.AddToQuery(query, "organization", req.Organization) + parameter.AddToQuery(query, "volume_type", req.VolumeType) parameter.AddToQuery(query, "per_page", req.PerPage) parameter.AddToQuery(query, "page", req.Page) + parameter.AddToQuery(query, "organization", req.Organization) parameter.AddToQuery(query, "name", req.Name) if fmt.Sprint(req.Zone) == "" { @@ -2275,13 +2589,13 @@ func (s *API) ListVolumes(req *ListVolumesRequest, opts ...scw.RequestOption) (* // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListVolumesResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListVolumesResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListVolumesResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListVolumesResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListVolumesResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -2289,11 +2603,11 @@ func (r *ListVolumesResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) r.Volumes = append(r.Volumes, results.Volumes...) r.TotalCount += uint32(len(results.Volumes)) - return len(results.Volumes), nil + return uint32(len(results.Volumes)), nil } type CreateVolumeRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` Name string `json:"name,omitempty"` @@ -2301,10 +2615,10 @@ type CreateVolumeRequest struct { // VolumeType // // Default value: l_ssd - VolumeType VolumeType `json:"volume_type,omitempty"` + VolumeType VolumeType `json:"volume_type"` // Precisely one of BaseSnapshot, BaseVolume, Size must be set. - Size *uint64 `json:"size,omitempty"` + Size *scw.Size `json:"size,omitempty"` // Precisely one of BaseSnapshot, BaseVolume, Size must be set. BaseVolume *string `json:"base_volume,omitempty"` @@ -2313,24 +2627,12 @@ type CreateVolumeRequest struct { BaseSnapshot *string `json:"base_snapshot,omitempty"` } -func (m *CreateVolumeRequest) GetFrom() From { - switch { - case m.Size != nil: - return FromSize{*m.Size} - case m.BaseVolume != nil: - return FromBaseVolume{*m.BaseVolume} - case m.BaseSnapshot != nil: - return FromBaseSnapshot{*m.BaseSnapshot} - } - return nil -} - // CreateVolume create volume func (s *API) CreateVolume(req *CreateVolumeRequest, opts ...scw.RequestOption) (*CreateVolumeResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -2364,14 +2666,14 @@ func (s *API) CreateVolume(req *CreateVolumeRequest, opts ...scw.RequestOption) } type GetVolumeRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` VolumeID string `json:"-"` } // GetVolume get volume // -// Get details of a volume with the given id +// Get details of a volume with the given ID. func (s *API) GetVolume(req *GetVolumeRequest, opts ...scw.RequestOption) (*GetVolumeResponse, error) { var err error @@ -2403,87 +2705,15 @@ func (s *API) GetVolume(req *GetVolumeRequest, opts ...scw.RequestOption) (*GetV return &resp, nil } -type SetVolumeRequest struct { - Zone utils.Zone `json:"-"` - // ID display the volumes unique ID - ID string `json:"-"` - // Name display the volumes names - Name string `json:"name,omitempty"` - // ExportURI show the volumes NBD export URI - ExportURI string `json:"export_uri,omitempty"` - // Size display the volumes disk size - Size uint64 `json:"size,omitempty"` - // VolumeType display the volumes type - // - // Default value: l_ssd - VolumeType VolumeType `json:"volume_type,omitempty"` - // CreationDate display the volumes creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // ModificationDate display the volumes modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // Organization display the volumes organization - Organization string `json:"organization,omitempty"` - // Server display information about the server attached to the volume - Server *ServerSummary `json:"server,omitempty"` - // State display the volumes state - // - // Default value: available - State VolumeState `json:"state,omitempty"` -} - -// SetVolume update volume -// -// Replace all volume properties with a volume message -func (s *API) SetVolume(req *SetVolumeRequest, opts ...scw.RequestOption) (*SetVolumeResponse, error) { - var err error - - if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() - req.Organization = defaultOrganization - } - - if req.Zone == "" { - defaultZone, _ := s.client.GetDefaultZone() - req.Zone = defaultZone - } - - if fmt.Sprint(req.Zone) == "" { - return nil, errors.New("field Zone cannot be empty in request") - } - - if fmt.Sprint(req.ID) == "" { - return nil, errors.New("field ID cannot be empty in request") - } - - scwReq := &scw.ScalewayRequest{ - Method: "PUT", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/volumes/" + fmt.Sprint(req.ID) + "", - Headers: http.Header{}, - } - - err = scwReq.SetBody(req) - if err != nil { - return nil, err - } - - var resp SetVolumeResponse - - err = s.client.Do(scwReq, &resp, opts...) - if err != nil { - return nil, err - } - return &resp, nil -} - type DeleteVolumeRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` VolumeID string `json:"-"` } // DeleteVolume delete volume // -// Delete the volume with the given id +// Delete the volume with the given ID. func (s *API) DeleteVolume(req *DeleteVolumeRequest, opts ...scw.RequestOption) error { var err error @@ -2514,28 +2744,25 @@ func (s *API) DeleteVolume(req *DeleteVolumeRequest, opts ...scw.RequestOption) } type ListSecurityGroupsRequest struct { - Zone utils.Zone `json:"-"` - - Organization *string `json:"-"` - - PerPage *int32 `json:"-"` - - Page *int32 `json:"-"` - + Zone scw.Zone `json:"-"` + // Name name of the security group Name *string `json:"-"` + // Organization the security group organization ID + Organization *string `json:"-"` + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return + Page *int32 `json:"-"` } // ListSecurityGroups list security groups // -// List all security groups available in an account +// List all security groups available in an account. func (s *API) ListSecurityGroups(req *ListSecurityGroupsRequest, opts ...scw.RequestOption) (*ListSecurityGroupsResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -2547,10 +2774,10 @@ func (s *API) ListSecurityGroups(req *ListSecurityGroupsRequest, opts ...scw.Req } query := url.Values{} + parameter.AddToQuery(query, "name", req.Name) parameter.AddToQuery(query, "organization", req.Organization) parameter.AddToQuery(query, "per_page", req.PerPage) parameter.AddToQuery(query, "page", req.Page) - parameter.AddToQuery(query, "name", req.Name) if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") @@ -2574,13 +2801,13 @@ func (s *API) ListSecurityGroups(req *ListSecurityGroupsRequest, opts ...scw.Req // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListSecurityGroupsResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListSecurityGroupsResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListSecurityGroupsResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListSecurityGroupsResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListSecurityGroupsResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -2588,38 +2815,53 @@ func (r *ListSecurityGroupsResponse) UnsafeAppend(res interface{}) (int, scw.Sdk r.SecurityGroups = append(r.SecurityGroups, results.SecurityGroups...) r.TotalCount += uint32(len(results.SecurityGroups)) - return len(results.SecurityGroups), nil + return uint32(len(results.SecurityGroups)), nil } type CreateSecurityGroupRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // Name name of the security group Name string `json:"name,omitempty"` - - OrganizationKey string `json:"organization_key,omitempty"` - + // Description description of the security group + Description string `json:"description,omitempty"` + // Organization organization the security group belongs to + Organization string `json:"organization,omitempty"` + // OrganizationDefault whether this security group becomes the default security group for new instances + // + // Default value: false OrganizationDefault bool `json:"organization_default,omitempty"` - + // Stateful whether the security group is stateful or not + // + // Default value: false Stateful bool `json:"stateful,omitempty"` - // InboundDefaultPolicy + // InboundDefaultPolicy default policy for inbound rules // // Default value: accept - InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy,omitempty"` - // OutboundDefaultPolicy + InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy"` + // OutboundDefaultPolicy default policy for outbound rules // // Default value: accept - OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy,omitempty"` + OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy"` } // CreateSecurityGroup create security group func (s *API) CreateSecurityGroup(req *CreateSecurityGroupRequest, opts ...scw.RequestOption) (*CreateSecurityGroupResponse, error) { var err error + if req.Organization == "" { + defaultOrganization, _ := s.client.GetDefaultOrganizationID() + req.Organization = defaultOrganization + } + if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone } + if req.Name == "" { + req.Name = namegenerator.GetRandomName("sg") + } + if fmt.Sprint(req.Zone) == "" { return nil, errors.New("field Zone cannot be empty in request") } @@ -2645,14 +2887,14 @@ func (s *API) CreateSecurityGroup(req *CreateSecurityGroupRequest, opts ...scw.R } type GetSecurityGroupRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SecurityGroupID string `json:"-"` } // GetSecurityGroup get security group // -// Get the details of a Security Group with the given id +// Get the details of a Security Group with the given ID. func (s *API) GetSecurityGroup(req *GetSecurityGroupRequest, opts ...scw.RequestOption) (*GetSecurityGroupResponse, error) { var err error @@ -2685,7 +2927,7 @@ func (s *API) GetSecurityGroup(req *GetSecurityGroupRequest, opts ...scw.Request } type DeleteSecurityGroupRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SecurityGroupID string `json:"-"` } @@ -2720,46 +2962,46 @@ func (s *API) DeleteSecurityGroup(req *DeleteSecurityGroupRequest, opts ...scw.R return nil } -type SetSecurityGroupRequest struct { - Zone utils.Zone `json:"-"` - // ID display the security groups' unique ID +type setSecurityGroupRequest struct { + Zone scw.Zone `json:"-"` + ID string `json:"-"` - // Name display the security groups name - Name string `json:"name,omitempty"` - // Description display the security groups description - Description string `json:"description,omitempty"` - // EnableDefaultSecurity display if the security group is set as default - EnableDefaultSecurity bool `json:"enable_default_security,omitempty"` - // InboundDefaultPolicy display the default inbound policy + + Name string `json:"name"` + + CreationDate time.Time `json:"creation_date"` + + ModificationDate time.Time `json:"modification_date"` + + Description string `json:"description"` + + EnableDefaultSecurity bool `json:"enable_default_security"` + // InboundDefaultPolicy // // Default value: accept - InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy,omitempty"` - // OutboundDefaultPolicy display the default outbound policy + InboundDefaultPolicy SecurityGroupPolicy `json:"inbound_default_policy"` + + Organization string `json:"organization"` + + OrganizationDefault bool `json:"organization_default"` + // OutboundDefaultPolicy // // Default value: accept - OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy,omitempty"` - // Organization display the security groups organization ID - Organization string `json:"organization,omitempty"` - // OrganizationDefault display if the security group is set as organization default - OrganizationDefault bool `json:"organization_default,omitempty"` - // CreationDate display the security group creation date - CreationDate time.Time `json:"creation_date,omitempty"` - // ModificationDate display the security group modification date - ModificationDate time.Time `json:"modification_date,omitempty"` - // Servers list of servers attached to this security group - Servers []*ServerSummary `json:"servers,omitempty"` - // Stateful true if the security group is stateful - Stateful bool `json:"stateful,omitempty"` + OutboundDefaultPolicy SecurityGroupPolicy `json:"outbound_default_policy"` + + Servers []*ServerSummary `json:"servers"` + + Stateful bool `json:"stateful"` } -// SetSecurityGroup update security group +// setSecurityGroup update security group // -// Replace all security group properties with a security group message -func (s *API) SetSecurityGroup(req *SetSecurityGroupRequest, opts ...scw.RequestOption) (*UpdateSecurityGroupResponse, error) { +// Replace all security group properties with a security group message. +func (s *API) setSecurityGroup(req *setSecurityGroupRequest, opts ...scw.RequestOption) (*setSecurityGroupResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -2787,7 +3029,7 @@ func (s *API) SetSecurityGroup(req *SetSecurityGroupRequest, opts ...scw.Request return nil, err } - var resp UpdateSecurityGroupResponse + var resp setSecurityGroupResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -2797,12 +3039,14 @@ func (s *API) SetSecurityGroup(req *SetSecurityGroupRequest, opts ...scw.Request } type ListSecurityGroupRulesRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // SecurityGroupID uUID of the security group SecurityGroupID string `json:"-"` - - PerPage *int32 `json:"-"` - + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return Page *int32 `json:"-"` } @@ -2850,45 +3094,45 @@ func (s *API) ListSecurityGroupRules(req *ListSecurityGroupRulesRequest, opts .. // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListSecurityGroupRulesResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListSecurityGroupRulesResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListSecurityGroupRulesResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListSecurityGroupRulesResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListSecurityGroupRulesResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) } - r.SecurityRules = append(r.SecurityRules, results.SecurityRules...) - r.TotalCount += uint32(len(results.SecurityRules)) - return len(results.SecurityRules), nil + r.Rules = append(r.Rules, results.Rules...) + r.TotalCount += uint32(len(results.Rules)) + return uint32(len(results.Rules)), nil } type CreateSecurityGroupRuleRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // SecurityGroupID uUID of the security group SecurityGroupID string `json:"-"` // Protocol // - // Default value: tcp - Protocol SecurityRuleProtocol `json:"protocol,omitempty"` + // Default value: TCP + Protocol SecurityGroupRuleProtocol `json:"protocol"` // Direction // // Default value: inbound - Direction SecurityRuleDirection `json:"direction,omitempty"` + Direction SecurityGroupRuleDirection `json:"direction"` // Action // // Default value: accept - Action SecurityRuleAction `json:"action,omitempty"` + Action SecurityGroupRuleAction `json:"action"` - IPRange string `json:"ip_range,omitempty"` + IPRange scw.IPNet `json:"ip_range,omitempty"` - DestPortFrom uint32 `json:"dest_port_from,omitempty"` + DestPortFrom *uint32 `json:"dest_port_from,omitempty"` - DestPortTo uint32 `json:"dest_port_to,omitempty"` + DestPortTo *uint32 `json:"dest_port_to,omitempty"` Position uint32 `json:"position,omitempty"` @@ -2933,16 +3177,16 @@ func (s *API) CreateSecurityGroupRule(req *CreateSecurityGroupRuleRequest, opts } type DeleteSecurityGroupRuleRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SecurityGroupID string `json:"-"` - SecurityRuleID string `json:"-"` + SecurityGroupRuleID string `json:"-"` } // DeleteSecurityGroupRule delete rule // -// Delete a security group rule with the given id +// Delete a security group rule with the given ID. func (s *API) DeleteSecurityGroupRule(req *DeleteSecurityGroupRuleRequest, opts ...scw.RequestOption) error { var err error @@ -2959,13 +3203,13 @@ func (s *API) DeleteSecurityGroupRule(req *DeleteSecurityGroupRuleRequest, opts return errors.New("field SecurityGroupID cannot be empty in request") } - if fmt.Sprint(req.SecurityRuleID) == "" { - return errors.New("field SecurityRuleID cannot be empty in request") + if fmt.Sprint(req.SecurityGroupRuleID) == "" { + return errors.New("field SecurityGroupRuleID cannot be empty in request") } scwReq := &scw.ScalewayRequest{ Method: "DELETE", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/security_groups/" + fmt.Sprint(req.SecurityGroupID) + "/rules/" + fmt.Sprint(req.SecurityRuleID) + "", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/security_groups/" + fmt.Sprint(req.SecurityGroupID) + "/rules/" + fmt.Sprint(req.SecurityGroupRuleID) + "", Headers: http.Header{}, } @@ -2977,16 +3221,16 @@ func (s *API) DeleteSecurityGroupRule(req *DeleteSecurityGroupRuleRequest, opts } type GetSecurityGroupRuleRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` SecurityGroupID string `json:"-"` - SecurityRuleID string `json:"-"` + SecurityGroupRuleID string `json:"-"` } // GetSecurityGroupRule get rule // -// Get details of a security group rule with the given id +// Get details of a security group rule with the given ID. func (s *API) GetSecurityGroupRule(req *GetSecurityGroupRuleRequest, opts ...scw.RequestOption) (*GetSecurityGroupRuleResponse, error) { var err error @@ -3003,13 +3247,13 @@ func (s *API) GetSecurityGroupRule(req *GetSecurityGroupRuleRequest, opts ...scw return nil, errors.New("field SecurityGroupID cannot be empty in request") } - if fmt.Sprint(req.SecurityRuleID) == "" { - return nil, errors.New("field SecurityRuleID cannot be empty in request") + if fmt.Sprint(req.SecurityGroupRuleID) == "" { + return nil, errors.New("field SecurityGroupRuleID cannot be empty in request") } scwReq := &scw.ScalewayRequest{ Method: "GET", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/security_groups/" + fmt.Sprint(req.SecurityGroupID) + "/rules/" + fmt.Sprint(req.SecurityRuleID) + "", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/security_groups/" + fmt.Sprint(req.SecurityGroupID) + "/rules/" + fmt.Sprint(req.SecurityGroupRuleID) + "", Headers: http.Header{}, } @@ -3022,24 +3266,178 @@ func (s *API) GetSecurityGroupRule(req *GetSecurityGroupRuleRequest, opts ...scw return &resp, nil } -type ListIpsRequest struct { - Zone utils.Zone `json:"-"` +type setSecurityGroupRuleRequest struct { + Zone scw.Zone `json:"-"` - Organization string `json:"-"` + SecurityGroupID string `json:"-"` - Name *string `json:"-"` + SecurityGroupRuleID string `json:"-"` - PerPage *int32 `json:"-"` + ID string `json:"id"` + // Protocol + // + // Default value: TCP + Protocol SecurityGroupRuleProtocol `json:"protocol"` + // Direction + // + // Default value: inbound + Direction SecurityGroupRuleDirection `json:"direction"` + // Action + // + // Default value: accept + Action SecurityGroupRuleAction `json:"action"` - Page *int32 `json:"-"` + IPRange scw.IPNet `json:"ip_range"` + + DestPortFrom *uint32 `json:"dest_port_from"` + + DestPortTo *uint32 `json:"dest_port_to"` + + Position uint32 `json:"position"` + + Editable bool `json:"editable"` } -// ListIps list IPs -func (s *API) ListIps(req *ListIpsRequest, opts ...scw.RequestOption) (*ListIpsResponse, error) { +// setSecurityGroupRule update security group rule +func (s *API) setSecurityGroupRule(req *setSecurityGroupRuleRequest, opts ...scw.RequestOption) (*setSecurityGroupRuleResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.SecurityGroupID) == "" { + return nil, errors.New("field SecurityGroupID cannot be empty in request") + } + + if fmt.Sprint(req.SecurityGroupRuleID) == "" { + return nil, errors.New("field SecurityGroupRuleID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PUT", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/security_groups/" + fmt.Sprint(req.SecurityGroupID) + "/rules/" + fmt.Sprint(req.SecurityGroupRuleID) + "", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp setSecurityGroupRuleResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type ListPlacementGroupsRequest struct { + Zone scw.Zone `json:"-"` + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return + Page *int32 `json:"-"` + // Organization list only placement groups of this organization + Organization *string `json:"-"` + // Name filter placement groups by name (for eg. "cluster1" will return "cluster100" and "cluster1" but not "foo") + Name *string `json:"-"` +} + +// ListPlacementGroups list placement groups +// +// List all placement groups. +func (s *API) ListPlacementGroups(req *ListPlacementGroupsRequest, opts ...scw.RequestOption) (*ListPlacementGroupsResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + defaultPerPage, exist := s.client.GetDefaultPageSize() + if (req.PerPage == nil || *req.PerPage == 0) && exist { + req.PerPage = &defaultPerPage + } + + query := url.Values{} + parameter.AddToQuery(query, "per_page", req.PerPage) + parameter.AddToQuery(query, "page", req.Page) + parameter.AddToQuery(query, "organization", req.Organization) + parameter.AddToQuery(query, "name", req.Name) + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "GET", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups", + Query: query, + Headers: http.Header{}, + } + + var resp ListPlacementGroupsResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +// UnsafeGetTotalCount should not be used +// Internal usage only +func (r *ListPlacementGroupsResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount +} + +// UnsafeAppend should not be used +// Internal usage only +func (r *ListPlacementGroupsResponse) UnsafeAppend(res interface{}) (uint32, error) { + results, ok := res.(*ListPlacementGroupsResponse) + if !ok { + return 0, errors.New("%T type cannot be appended to type %T", res, r) + } + + r.PlacementGroups = append(r.PlacementGroups, results.PlacementGroups...) + r.TotalCount += uint32(len(results.PlacementGroups)) + return uint32(len(results.PlacementGroups)), nil +} + +type CreatePlacementGroupRequest struct { + Zone scw.Zone `json:"-"` + // Name name of the placement group + Name string `json:"name,omitempty"` + + Organization string `json:"organization,omitempty"` + // PolicyMode + // + // Default value: optional + PolicyMode PlacementGroupPolicyMode `json:"policy_mode"` + // PolicyType + // + // Default value: max_availability + PolicyType PlacementGroupPolicyType `json:"policy_type"` +} + +// CreatePlacementGroup create placement group +// +// Create a new placement group. +func (s *API) CreatePlacementGroup(req *CreatePlacementGroupRequest, opts ...scw.RequestOption) (*CreatePlacementGroupResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -3048,6 +3446,386 @@ func (s *API) ListIps(req *ListIpsRequest, opts ...scw.RequestOption) (*ListIpsR req.Zone = defaultZone } + if req.Name == "" { + req.Name = namegenerator.GetRandomName("pg") + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "POST", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp CreatePlacementGroupResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type GetPlacementGroupRequest struct { + Zone scw.Zone `json:"-"` + + PlacementGroupID string `json:"-"` +} + +// GetPlacementGroup get placement group +// +// Get the given placement group. +func (s *API) GetPlacementGroup(req *GetPlacementGroupRequest, opts ...scw.RequestOption) (*GetPlacementGroupResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "GET", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "", + Headers: http.Header{}, + } + + var resp GetPlacementGroupResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type SetPlacementGroupRequest struct { + Zone scw.Zone `json:"-"` + + PlacementGroupID string `json:"-"` + + Name string `json:"name"` + + Organization string `json:"organization"` + // PolicyMode + // + // Default value: optional + PolicyMode PlacementGroupPolicyMode `json:"policy_mode"` + // PolicyType + // + // Default value: max_availability + PolicyType PlacementGroupPolicyType `json:"policy_type"` +} + +// SetPlacementGroup set placement group +// +// Set all parameters of the given placement group. +func (s *API) SetPlacementGroup(req *SetPlacementGroupRequest, opts ...scw.RequestOption) (*SetPlacementGroupResponse, error) { + var err error + + if req.Organization == "" { + defaultOrganization, _ := s.client.GetDefaultOrganizationID() + req.Organization = defaultOrganization + } + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PUT", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp SetPlacementGroupResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type UpdatePlacementGroupRequest struct { + Zone scw.Zone `json:"-"` + // PlacementGroupID uUID of the placement group + PlacementGroupID string `json:"-"` + // Name name of the placement group + Name *string `json:"name,omitempty"` + // PolicyMode + // + // Default value: optional + PolicyMode PlacementGroupPolicyMode `json:"policy_mode"` + // PolicyType + // + // Default value: max_availability + PolicyType PlacementGroupPolicyType `json:"policy_type"` +} + +// UpdatePlacementGroup update placement group +// +// Update one or more parameter of the given placement group. +func (s *API) UpdatePlacementGroup(req *UpdatePlacementGroupRequest, opts ...scw.RequestOption) (*UpdatePlacementGroupResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PATCH", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp UpdatePlacementGroupResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type DeletePlacementGroupRequest struct { + Zone scw.Zone `json:"-"` + + PlacementGroupID string `json:"-"` +} + +// DeletePlacementGroup delete the given placement group +// +// Delete the given placement group. +func (s *API) DeletePlacementGroup(req *DeletePlacementGroupRequest, opts ...scw.RequestOption) error { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "DELETE", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "", + Headers: http.Header{}, + } + + err = s.client.Do(scwReq, nil, opts...) + if err != nil { + return err + } + return nil +} + +type GetPlacementGroupServersRequest struct { + Zone scw.Zone `json:"-"` + + PlacementGroupID string `json:"-"` +} + +// GetPlacementGroupServers get placement group servers +// +// Get all servers belonging to the given placement group. +func (s *API) GetPlacementGroupServers(req *GetPlacementGroupServersRequest, opts ...scw.RequestOption) (*GetPlacementGroupServersResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "GET", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "/servers", + Headers: http.Header{}, + } + + var resp GetPlacementGroupServersResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type SetPlacementGroupServersRequest struct { + Zone scw.Zone `json:"-"` + + PlacementGroupID string `json:"-"` + + Servers []string `json:"servers"` +} + +// SetPlacementGroupServers set placement group servers +// +// Set all servers belonging to the given placement group. +func (s *API) SetPlacementGroupServers(req *SetPlacementGroupServersRequest, opts ...scw.RequestOption) (*SetPlacementGroupServersResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PUT", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "/servers", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp SetPlacementGroupServersResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type UpdatePlacementGroupServersRequest struct { + Zone scw.Zone `json:"-"` + // PlacementGroupID uUID of the placement group + PlacementGroupID string `json:"-"` + + Servers []string `json:"servers,omitempty"` +} + +// UpdatePlacementGroupServers update placement group servers +// +// Update all servers belonging to the given placement group. +func (s *API) UpdatePlacementGroupServers(req *UpdatePlacementGroupServersRequest, opts ...scw.RequestOption) (*UpdatePlacementGroupServersResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.PlacementGroupID) == "" { + return nil, errors.New("field PlacementGroupID cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PATCH", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/placement_groups/" + fmt.Sprint(req.PlacementGroupID) + "/servers", + Headers: http.Header{}, + } + + err = scwReq.SetBody(req) + if err != nil { + return nil, err + } + + var resp UpdatePlacementGroupServersResponse + + err = s.client.Do(scwReq, &resp, opts...) + if err != nil { + return nil, err + } + return &resp, nil +} + +type ListIPsRequest struct { + Zone scw.Zone `json:"-"` + // Organization the organization ID the IPs are reserved in + Organization *string `json:"-"` + // Name filter on the IP address (Works as a LIKE operation on the IP address) + Name *string `json:"-"` + // PerPage a positive integer lower or equal to 100 to select the number of items to return + // + // Default value: 50 + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to return + Page *int32 `json:"-"` +} + +// ListIPs list IPs +func (s *API) ListIPs(req *ListIPsRequest, opts ...scw.RequestOption) (*ListIPsResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + defaultPerPage, exist := s.client.GetDefaultPageSize() if (req.PerPage == nil || *req.PerPage == 0) && exist { req.PerPage = &defaultPerPage @@ -3070,7 +3848,7 @@ func (s *API) ListIps(req *ListIpsRequest, opts ...scw.RequestOption) (*ListIpsR Headers: http.Header{}, } - var resp ListIpsResponse + var resp ListIPsResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -3081,37 +3859,37 @@ func (s *API) ListIps(req *ListIpsRequest, opts ...scw.RequestOption) (*ListIpsR // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListIpsResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListIPsResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListIpsResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { - results, ok := res.(*ListIpsResponse) +func (r *ListIPsResponse) UnsafeAppend(res interface{}) (uint32, error) { + results, ok := res.(*ListIPsResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) } - r.Ips = append(r.Ips, results.Ips...) - r.TotalCount += uint32(len(results.Ips)) - return len(results.Ips), nil + r.IPs = append(r.IPs, results.IPs...) + r.TotalCount += uint32(len(results.IPs)) + return uint32(len(results.IPs)), nil } type CreateIPRequest struct { - Zone utils.Zone `json:"-"` - + Zone scw.Zone `json:"-"` + // Organization the organization ID the IP is reserved in Organization string `json:"organization,omitempty"` - + // Server uUID of the server you want to attach the IP to Server *string `json:"server,omitempty"` } -// CreateIP reseve an IP +// CreateIP reserve an IP func (s *API) CreateIP(req *CreateIPRequest, opts ...scw.RequestOption) (*CreateIPResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -3145,14 +3923,14 @@ func (s *API) CreateIP(req *CreateIPRequest, opts ...scw.RequestOption) (*Create } type GetIPRequest struct { - Zone utils.Zone `json:"-"` - - IPID string `json:"-"` + Zone scw.Zone `json:"-"` + // IP the IP ID or address to get + IP string `json:"-"` } // GetIP get IP // -// Get details of an IP with the given id +// Get details of an IP with the given ID or address. func (s *API) GetIP(req *GetIPRequest, opts ...scw.RequestOption) (*GetIPResponse, error) { var err error @@ -3165,13 +3943,13 @@ func (s *API) GetIP(req *GetIPRequest, opts ...scw.RequestOption) (*GetIPRespons return nil, errors.New("field Zone cannot be empty in request") } - if fmt.Sprint(req.IPID) == "" { - return nil, errors.New("field IPID cannot be empty in request") + if fmt.Sprint(req.IP) == "" { + return nil, errors.New("field IP cannot be empty in request") } scwReq := &scw.ScalewayRequest{ Method: "GET", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IPID) + "", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IP) + "", Headers: http.Header{}, } @@ -3185,24 +3963,24 @@ func (s *API) GetIP(req *GetIPRequest, opts ...scw.RequestOption) (*GetIPRespons } type SetIPRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` ID string `json:"-"` - Address net.IP `json:"address,omitempty"` + Address net.IP `json:"address"` - Reverse *string `json:"reverse,omitempty"` + Reverse *string `json:"reverse"` - Server *ServerSummary `json:"server,omitempty"` + Server *ServerSummary `json:"server"` - Organization string `json:"organization,omitempty"` + Organization string `json:"organization"` } -func (s *API) SetIP(req *SetIPRequest, opts ...scw.RequestOption) (*SetIPResponse, error) { +func (s *API) setIP(req *SetIPRequest, opts ...scw.RequestOption) (*setIPResponse, error) { var err error if req.Organization == "" { - defaultOrganization, _ := s.client.GetDefaultProjectID() + defaultOrganization, _ := s.client.GetDefaultOrganizationID() req.Organization = defaultOrganization } @@ -3230,7 +4008,7 @@ func (s *API) SetIP(req *SetIPRequest, opts ...scw.RequestOption) (*SetIPRespons return nil, err } - var resp SetIPResponse + var resp setIPResponse err = s.client.Do(scwReq, &resp, opts...) if err != nil { @@ -3239,18 +4017,18 @@ func (s *API) SetIP(req *SetIPRequest, opts ...scw.RequestOption) (*SetIPRespons return &resp, nil } -type updateIPRequest struct { - Zone utils.Zone `json:"-"` +type UpdateIPRequest struct { + Zone scw.Zone `json:"-"` + // IP iP ID or IP address + IP string `json:"-"` + // Reverse reverse domain name + Reverse *NullableStringValue `json:"reverse,omitempty"` - IPID string `json:"-"` - - Reverse **string `json:"reverse,omitempty"` - - Server **string `json:"server,omitempty"` + Server *NullableStringValue `json:"server,omitempty"` } -// updateIP update IP -func (s *API) updateIP(req *updateIPRequest, opts ...scw.RequestOption) (*UpdateIPResponse, error) { +// UpdateIP update IP +func (s *API) UpdateIP(req *UpdateIPRequest, opts ...scw.RequestOption) (*UpdateIPResponse, error) { var err error if req.Zone == "" { @@ -3262,13 +4040,13 @@ func (s *API) updateIP(req *updateIPRequest, opts ...scw.RequestOption) (*Update return nil, errors.New("field Zone cannot be empty in request") } - if fmt.Sprint(req.IPID) == "" { - return nil, errors.New("field IPID cannot be empty in request") + if fmt.Sprint(req.IP) == "" { + return nil, errors.New("field IP cannot be empty in request") } scwReq := &scw.ScalewayRequest{ Method: "PATCH", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IPID) + "", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IP) + "", Headers: http.Header{}, } @@ -3287,14 +4065,14 @@ func (s *API) updateIP(req *updateIPRequest, opts ...scw.RequestOption) (*Update } type DeleteIPRequest struct { - Zone utils.Zone `json:"-"` - - IPID string `json:"-"` + Zone scw.Zone `json:"-"` + // IP the ID or the address of the IP to delete + IP string `json:"-"` } // DeleteIP delete IP // -// Delete the IP with the given id +// Delete the IP with the given ID. func (s *API) DeleteIP(req *DeleteIPRequest, opts ...scw.RequestOption) error { var err error @@ -3307,13 +4085,13 @@ func (s *API) DeleteIP(req *DeleteIPRequest, opts ...scw.RequestOption) error { return errors.New("field Zone cannot be empty in request") } - if fmt.Sprint(req.IPID) == "" { - return errors.New("field IPID cannot be empty in request") + if fmt.Sprint(req.IP) == "" { + return errors.New("field IP cannot be empty in request") } scwReq := &scw.ScalewayRequest{ Method: "DELETE", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IPID) + "", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/ips/" + fmt.Sprint(req.IP) + "", Headers: http.Header{}, } @@ -3325,7 +4103,7 @@ func (s *API) DeleteIP(req *DeleteIPRequest, opts ...scw.RequestOption) error { } type ListBootscriptsRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` Arch *string `json:"-"` @@ -3335,7 +4113,7 @@ type ListBootscriptsRequest struct { Public *bool `json:"-"` - PerPage *int32 `json:"-"` + PerPage *uint32 `json:"-"` Page *int32 `json:"-"` } @@ -3384,13 +4162,13 @@ func (s *API) ListBootscripts(req *ListBootscriptsRequest, opts ...scw.RequestOp // UnsafeGetTotalCount should not be used // Internal usage only -func (r *ListBootscriptsResponse) UnsafeGetTotalCount() int { - return int(r.TotalCount) +func (r *ListBootscriptsResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount } // UnsafeAppend should not be used // Internal usage only -func (r *ListBootscriptsResponse) UnsafeAppend(res interface{}) (int, scw.SdkError) { +func (r *ListBootscriptsResponse) UnsafeAppend(res interface{}) (uint32, error) { results, ok := res.(*ListBootscriptsResponse) if !ok { return 0, errors.New("%T type cannot be appended to type %T", res, r) @@ -3398,18 +4176,18 @@ func (r *ListBootscriptsResponse) UnsafeAppend(res interface{}) (int, scw.SdkErr r.Bootscripts = append(r.Bootscripts, results.Bootscripts...) r.TotalCount += uint32(len(results.Bootscripts)) - return len(results.Bootscripts), nil + return uint32(len(results.Bootscripts)), nil } type GetBootscriptRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` BootscriptID string `json:"-"` } // GetBootscript get bootscripts // -// Get details of a bootscript with the given id +// Get details of a bootscript with the given ID. func (s *API) GetBootscript(req *GetBootscriptRequest, opts ...scw.RequestOption) (*GetBootscriptResponse, error) { var err error @@ -3441,39 +4219,8 @@ func (s *API) GetBootscript(req *GetBootscriptRequest, opts ...scw.RequestOption return &resp, nil } -type GetServiceInfoRequest struct { - Zone utils.Zone `json:"-"` -} - -func (s *API) GetServiceInfo(req *GetServiceInfoRequest, opts ...scw.RequestOption) (*GetServiceInfoResponse, error) { - var err error - - if req.Zone == "" { - defaultZone, _ := s.client.GetDefaultZone() - req.Zone = defaultZone - } - - if fmt.Sprint(req.Zone) == "" { - return nil, errors.New("field Zone cannot be empty in request") - } - - scwReq := &scw.ScalewayRequest{ - Method: "GET", - Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "", - Headers: http.Header{}, - } - - var resp GetServiceInfoResponse - - err = s.client.Do(scwReq, &resp, opts...) - if err != nil { - return nil, err - } - return &resp, nil -} - type GetDashboardRequest struct { - Zone utils.Zone `json:"-"` + Zone scw.Zone `json:"-"` Organization *string `json:"-"` } @@ -3481,11 +4228,6 @@ type GetDashboardRequest struct { func (s *API) GetDashboard(req *GetDashboardRequest, opts ...scw.RequestOption) (*GetDashboardResponse, error) { var err error - defaultOrganization, exist := s.client.GetDefaultProjectID() - if (req.Organization == nil || *req.Organization == "") && exist { - req.Organization = &defaultOrganization - } - if req.Zone == "" { defaultZone, _ := s.client.GetDefaultZone() req.Zone = defaultZone @@ -3513,28 +4255,3 @@ func (s *API) GetDashboard(req *GetDashboardRequest, opts ...scw.RequestOption) } return &resp, nil } - -type From interface { - isFrom() -} - -type FromSize struct { - Value uint64 -} - -func (FromSize) isFrom() { -} - -type FromBaseVolume struct { - Value string -} - -func (FromBaseVolume) isFrom() { -} - -type FromBaseSnapshot struct { - Value string -} - -func (FromBaseSnapshot) isFrom() { -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_utils.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_utils.go index 946ae4767..5fa431e92 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_utils.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/instance_utils.go @@ -1,31 +1,55 @@ package instance import ( + "encoding/json" "fmt" + "sync" + "github.com/scaleway/scaleway-sdk-go/internal/errors" "github.com/scaleway/scaleway-sdk-go/scw" - "github.com/scaleway/scaleway-sdk-go/utils" ) +var ( + resourceLock sync.Map +) + +// lockResource locks a resource from a specific resourceID +func lockResource(resourceID string) *sync.Mutex { + v, _ := resourceLock.LoadOrStore(resourceID, &sync.Mutex{}) + mutex := v.(*sync.Mutex) + mutex.Lock() + return mutex +} + +// lockServer locks a server from its zone and its ID +func lockServer(zone scw.Zone, serverID string) *sync.Mutex { + return lockResource(fmt.Sprint("server", zone, serverID)) +} + // AttachIPRequest contains the parameters to attach an IP to a server +// +// Deprecated: UpdateIPRequest should be used instead type AttachIPRequest struct { - Zone utils.Zone `json:"-"` - IPID string `json:"-"` - ServerID string `json:"server_id"` + Zone scw.Zone `json:"-"` + IP string `json:"-"` + ServerID string `json:"server_id"` } // AttachIPResponse contains the updated IP after attaching +// +// Deprecated: UpdateIPResponse should be used instead type AttachIPResponse struct { IP *IP } // AttachIP attaches an IP to a server. +// +// Deprecated: UpdateIP() should be used instead func (s *API) AttachIP(req *AttachIPRequest, opts ...scw.RequestOption) (*AttachIPResponse, error) { - var ptrServerID = &req.ServerID - ipResponse, err := s.updateIP(&updateIPRequest{ + ipResponse, err := s.UpdateIP(&UpdateIPRequest{ Zone: req.Zone, - IPID: req.IPID, - Server: &ptrServerID, + IP: req.IP, + Server: &NullableStringValue{Value: req.ServerID}, }) if err != nil { return nil, err @@ -35,23 +59,28 @@ func (s *API) AttachIP(req *AttachIPRequest, opts ...scw.RequestOption) (*Attach } // DetachIPRequest contains the parameters to detach an IP from a server +// +// Deprecated: UpdateIPRequest should be used instead type DetachIPRequest struct { - Zone utils.Zone `json:"-"` - IPID string `json:"-"` + Zone scw.Zone `json:"-"` + IP string `json:"-"` } // DetachIPResponse contains the updated IP after detaching +// +// Deprecated: UpdateIPResponse should be used instead type DetachIPResponse struct { IP *IP } // DetachIP detaches an IP from a server. +// +// Deprecated: UpdateIP() should be used instead func (s *API) DetachIP(req *DetachIPRequest, opts ...scw.RequestOption) (*DetachIPResponse, error) { - var ptrServerID *string - ipResponse, err := s.updateIP(&updateIPRequest{ + ipResponse, err := s.UpdateIP(&UpdateIPRequest{ Zone: req.Zone, - IPID: req.IPID, - Server: &ptrServerID, + IP: req.IP, + Server: &NullableStringValue{Null: true}, }) if err != nil { return nil, err @@ -60,40 +89,11 @@ func (s *API) DetachIP(req *DetachIPRequest, opts ...scw.RequestOption) (*Detach return &DetachIPResponse{IP: ipResponse.IP}, nil } -// UpdateIPRequest contains the parameters to update an IP -// if Reverse is an empty string, the reverse will be removed -type UpdateIPRequest struct { - Zone utils.Zone `json:"-"` - IPID string `json:"-"` - Reverse *string `json:"reverse"` -} - -// UpdateIP updates an IP -func (s *API) UpdateIP(req *UpdateIPRequest, opts ...scw.RequestOption) (*UpdateIPResponse, error) { - var reverse **string - if req.Reverse != nil { - if *req.Reverse == "" { - req.Reverse = nil - } - reverse = &req.Reverse - } - ipResponse, err := s.updateIP(&updateIPRequest{ - Zone: req.Zone, - IPID: req.IPID, - Reverse: reverse, - }) - if err != nil { - return nil, err - } - - return &UpdateIPResponse{IP: ipResponse.IP}, nil -} - // AttachVolumeRequest contains the parameters to attach a volume to a server type AttachVolumeRequest struct { - Zone utils.Zone `json:"-"` - ServerID string `json:"-"` - VolumeID string `json:"-"` + Zone scw.Zone `json:"-"` + ServerID string `json:"-"` + VolumeID string `json:"-"` } // AttachVolumeResponse contains the updated server after attaching a volume @@ -112,7 +112,10 @@ func volumesToVolumeTemplates(volumes map[string]*Volume) map[string]*VolumeTemp } // AttachVolume attaches a volume to a server +// +// Note: Implementation is thread-safe. func (s *API) AttachVolume(req *AttachVolumeRequest, opts ...scw.RequestOption) (*AttachVolumeResponse, error) { + defer lockServer(req.Zone, req.ServerID).Unlock() // get server with volumes getServerResponse, err := s.GetServer(&GetServerRequest{ Zone: req.Zone, @@ -126,15 +129,29 @@ func (s *API) AttachVolume(req *AttachVolumeRequest, opts ...scw.RequestOption) newVolumes := volumesToVolumeTemplates(volumes) // add volume to volumes list - key := fmt.Sprintf("%d", len(volumes)) - newVolumes[key] = &VolumeTemplate{ - ID: req.VolumeID, - // name is ignored on this PATCH - Name: req.VolumeID, + // We loop through all the possible volume keys (0 to len(volumes)) + // to find a non existing key and assign it to the requested volume. + // A key should always be found. However we return an error if no keys were found. + found := false + for i := 0; i <= len(volumes); i++ { + key := fmt.Sprintf("%d", i) + if _, ok := newVolumes[key]; !ok { + newVolumes[key] = &VolumeTemplate{ + ID: req.VolumeID, + // name is ignored on this PATCH + Name: req.VolumeID, + } + found = true + break + } + } + + if !found { + return nil, fmt.Errorf("could not find key to attach volume %s", req.VolumeID) } // update server - updateServerResponse, err := s.UpdateServer(&UpdateServerRequest{ + updateServerResponse, err := s.updateServer(&UpdateServerRequest{ Zone: req.Zone, ServerID: req.ServerID, Volumes: &newVolumes, @@ -148,8 +165,8 @@ func (s *API) AttachVolume(req *AttachVolumeRequest, opts ...scw.RequestOption) // DetachVolumeRequest contains the parameters to detach a volume from a server type DetachVolumeRequest struct { - Zone utils.Zone `json:"-"` - VolumeID string `json:"-"` + Zone scw.Zone `json:"-"` + VolumeID string `json:"-"` } // DetachVolumeResponse contains the updated server after detaching a volume @@ -158,6 +175,8 @@ type DetachVolumeResponse struct { } // DetachVolume detaches a volume from a server +// +// Note: Implementation is thread-safe. func (s *API) DetachVolume(req *DetachVolumeRequest, opts ...scw.RequestOption) (*DetachVolumeResponse, error) { // get volume getVolumeResponse, err := s.GetVolume(&GetVolumeRequest{ @@ -168,13 +187,14 @@ func (s *API) DetachVolume(req *DetachVolumeRequest, opts ...scw.RequestOption) return nil, err } if getVolumeResponse.Volume == nil { - return nil, fmt.Errorf("expected volume to have value in response") + return nil, errors.New("expected volume to have value in response") } if getVolumeResponse.Volume.Server == nil { - return nil, fmt.Errorf("server should be attached to a server") + return nil, errors.New("volume should be attached to a server") } serverID := getVolumeResponse.Volume.Server.ID + defer lockServer(req.Zone, serverID).Unlock() // get server with volumes getServerResponse, err := s.GetServer(&GetServerRequest{ Zone: req.Zone, @@ -194,7 +214,7 @@ func (s *API) DetachVolume(req *DetachVolumeRequest, opts ...scw.RequestOption) newVolumes := volumesToVolumeTemplates(volumes) // update server - updateServerResponse, err := s.UpdateServer(&UpdateServerRequest{ + updateServerResponse, err := s.updateServer(&UpdateServerRequest{ Zone: req.Zone, ServerID: serverID, Volumes: &newVolumes, @@ -220,7 +240,7 @@ func (r *ListBootscriptsResponse) UnsafeSetTotalCount(totalCount int) { // UnsafeSetTotalCount should not be used // Internal usage only -func (r *ListIpsResponse) UnsafeSetTotalCount(totalCount int) { +func (r *ListIPsResponse) UnsafeSetTotalCount(totalCount int) { r.TotalCount = uint32(totalCount) } @@ -253,3 +273,57 @@ func (r *ListSnapshotsResponse) UnsafeSetTotalCount(totalCount int) { func (r *ListVolumesResponse) UnsafeSetTotalCount(totalCount int) { r.TotalCount = uint32(totalCount) } + +// UnsafeSetTotalCount should not be used +// Internal usage only +func (r *ListImagesResponse) UnsafeSetTotalCount(totalCount int) { + r.TotalCount = uint32(totalCount) +} + +// UnsafeGetTotalCount should not be used +// Internal usage only +func (r *ListServersTypesResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount +} + +// UnsafeAppend should not be used +// Internal usage only +func (r *ListServersTypesResponse) UnsafeAppend(res interface{}) (uint32, error) { + results, ok := res.(*ListServersTypesResponse) + if !ok { + return 0, errors.New("%T type cannot be appended to type %T", res, r) + } + + if r.Servers == nil { + r.Servers = make(map[string]*ServerType, len(results.Servers)) + } + + for name, serverType := range results.Servers { + r.Servers[name] = serverType + } + + r.TotalCount += uint32(len(results.Servers)) + return uint32(len(results.Servers)), nil +} + +func (v *NullableStringValue) UnmarshalJSON(b []byte) error { + if string(b) == "null" { + v.Null = true + return nil + } + + var tmp string + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + v.Null = false + v.Value = tmp + return nil +} + +func (v *NullableStringValue) MarshalJSON() ([]byte, error) { + if v.Null { + return []byte("null"), nil + } + return json.Marshal(v.Value) +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/security_group_utils.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/security_group_utils.go new file mode 100644 index 000000000..250df5df2 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/security_group_utils.go @@ -0,0 +1,208 @@ +package instance + +import ( + "fmt" + + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +// UpdateSecurityGroupRequest contains the parameters to update a security group +type UpdateSecurityGroupRequest struct { + Zone scw.Zone `json:"-"` + SecurityGroupID string `json:"-"` + + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + InboundDefaultPolicy *SecurityGroupPolicy `json:"inbound_default_policy,omitempty"` + OutboundDefaultPolicy *SecurityGroupPolicy `json:"outbound_default_policy,omitempty"` + Stateful *bool `json:"stateful,omitempty"` + OrganizationDefault *bool `json:"organization_default,omitempty"` +} + +type UpdateSecurityGroupResponse struct { + SecurityGroup *SecurityGroup +} + +// UpdateSecurityGroup updates a security group. +func (s *API) UpdateSecurityGroup(req *UpdateSecurityGroupRequest, opts ...scw.RequestOption) (*UpdateSecurityGroupResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.SecurityGroupID) == "" { + return nil, errors.New("field SecurityGroupID cannot be empty in request") + } + + getSGResponse, err := s.GetSecurityGroup(&GetSecurityGroupRequest{ + Zone: req.Zone, + SecurityGroupID: req.SecurityGroupID, + }, opts...) + if err != nil { + return nil, err + } + + setRequest := &setSecurityGroupRequest{ + ID: getSGResponse.SecurityGroup.ID, + Name: getSGResponse.SecurityGroup.Name, + Description: getSGResponse.SecurityGroup.Description, + Organization: getSGResponse.SecurityGroup.Organization, + OrganizationDefault: getSGResponse.SecurityGroup.OrganizationDefault, + OutboundDefaultPolicy: getSGResponse.SecurityGroup.OutboundDefaultPolicy, + InboundDefaultPolicy: getSGResponse.SecurityGroup.InboundDefaultPolicy, + Stateful: getSGResponse.SecurityGroup.Stateful, + Zone: req.Zone, + EnableDefaultSecurity: getSGResponse.SecurityGroup.EnableDefaultSecurity, + CreationDate: getSGResponse.SecurityGroup.CreationDate, + ModificationDate: getSGResponse.SecurityGroup.ModificationDate, + Servers: getSGResponse.SecurityGroup.Servers, + } + + // Override the values that need to be updated + if req.Name != nil { + setRequest.Name = *req.Name + } + if req.Description != nil { + setRequest.Description = *req.Description + } + if req.InboundDefaultPolicy != nil { + setRequest.InboundDefaultPolicy = *req.InboundDefaultPolicy + } + if req.OutboundDefaultPolicy != nil { + setRequest.OutboundDefaultPolicy = *req.OutboundDefaultPolicy + } + if req.Stateful != nil { + setRequest.Stateful = *req.Stateful + } + if req.OrganizationDefault != nil { + setRequest.OrganizationDefault = *req.OrganizationDefault + } + + setRes, err := s.setSecurityGroup(setRequest, opts...) + if err != nil { + return nil, err + } + + return &UpdateSecurityGroupResponse{ + SecurityGroup: setRes.SecurityGroup, + }, nil +} + +// UpdateSecurityGroupRuleRequest contains the parameters to update a security group rule +type UpdateSecurityGroupRuleRequest struct { + Zone scw.Zone `json:"-"` + SecurityGroupID string `json:"-"` + SecurityGroupRuleID string `json:"-"` + + Protocol *SecurityGroupRuleProtocol `json:"protocol"` + Direction *SecurityGroupRuleDirection `json:"direction"` + Action *SecurityGroupRuleAction `json:"action"` + IPRange *scw.IPNet `json:"ip_range"` + Position *uint32 `json:"position"` + + // If set to 0, DestPortFrom will be removed. + // See SecurityGroupRule.DestPortFrom for more information + DestPortFrom *uint32 `json:"dest_port_from"` + + // If set to 0, DestPortTo will be removed. + // See SecurityGroupRule.DestPortTo for more information + DestPortTo *uint32 `json:"dest_port_to"` +} + +type UpdateSecurityGroupRuleResponse struct { + Rule *SecurityGroupRule `json:"security_rule"` +} + +// UpdateSecurityGroupRule updates a security group. +func (s *API) UpdateSecurityGroupRule(req *UpdateSecurityGroupRuleRequest, opts ...scw.RequestOption) (*UpdateSecurityGroupRuleResponse, error) { + var err error + + if fmt.Sprint(req.Zone) == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + res, err := s.GetSecurityGroupRule(&GetSecurityGroupRuleRequest{ + SecurityGroupRuleID: req.SecurityGroupRuleID, + SecurityGroupID: req.SecurityGroupID, + Zone: req.Zone, + }) + if err != nil { + return nil, err + } + + setRequest := &setSecurityGroupRuleRequest{ + Zone: req.Zone, + SecurityGroupID: req.SecurityGroupID, + SecurityGroupRuleID: req.SecurityGroupRuleID, + ID: req.SecurityGroupRuleID, + Direction: res.Rule.Direction, + Protocol: res.Rule.Protocol, + DestPortFrom: res.Rule.DestPortFrom, + DestPortTo: res.Rule.DestPortTo, + IPRange: res.Rule.IPRange, + Action: res.Rule.Action, + Position: res.Rule.Position, + Editable: res.Rule.Editable, + } + + // Override the values that need to be updated + if req.Action != nil { + setRequest.Action = *req.Action + } + if req.IPRange != nil { + setRequest.IPRange = *req.IPRange + } + if req.DestPortTo != nil { + if *req.DestPortTo > 0 { + setRequest.DestPortTo = req.DestPortTo + } else { + setRequest.DestPortTo = nil + } + } + if req.DestPortFrom != nil { + if *req.DestPortFrom > 0 { + setRequest.DestPortFrom = req.DestPortFrom + } else { + setRequest.DestPortFrom = nil + } + } + if req.DestPortFrom != nil && req.DestPortTo != nil && *req.DestPortFrom == *req.DestPortTo { + setRequest.DestPortTo = nil + } + if req.Protocol != nil { + setRequest.Protocol = *req.Protocol + } + if req.Direction != nil { + setRequest.Direction = *req.Direction + } + if req.Position != nil { + setRequest.Position = *req.Position + } + + // When we use ICMP protocol portFrom and portTo should be set to nil + if req.Protocol != nil && *req.Protocol == SecurityGroupRuleProtocolICMP { + setRequest.DestPortFrom = nil + setRequest.DestPortTo = nil + } + + resp, err := s.setSecurityGroupRule(setRequest) + if err != nil { + return nil, err + } + + return &UpdateSecurityGroupRuleResponse{ + Rule: resp.Rule, + }, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/server_utils.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/server_utils.go index 309117583..66c352939 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/server_utils.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/server_utils.go @@ -1,29 +1,65 @@ package instance import ( + "bytes" + "fmt" + "io" + "net/http" "time" + "github.com/scaleway/scaleway-sdk-go/api/marketplace/v1" "github.com/scaleway/scaleway-sdk-go/internal/async" - "github.com/scaleway/scaleway-sdk-go/utils" + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/scaleway-sdk-go/validation" ) -// WaitForServerRequest is used by WaitForServer method +const ( + defaultTimeout = 5 * time.Minute + defaultRetryInterval = 5 * time.Second +) + +var ( + RetryInterval = defaultRetryInterval +) + +// CreateServer creates a server. +func (s *API) CreateServer(req *CreateServerRequest, opts ...scw.RequestOption) (*CreateServerResponse, error) { + // If image is not a UUID we try to fetch it from marketplace. + if req.Image != "" && !validation.IsUUID(req.Image) { + apiMarketplace := marketplace.NewAPI(s.client) + imageID, err := apiMarketplace.GetLocalImageIDByLabel(&marketplace.GetLocalImageIDByLabelRequest{ + ImageLabel: req.Image, + Zone: req.Zone, + CommercialType: req.CommercialType, + }) + if err != nil { + return nil, err + } + req.Image = imageID + } + + return s.createServer(req, opts...) +} + +// UpdateServer updates a server. +// +// Note: Implementation is thread-safe. +func (s *API) UpdateServer(req *UpdateServerRequest, opts ...scw.RequestOption) (*UpdateServerResponse, error) { + defer lockServer(req.Zone, req.ServerID).Unlock() + return s.updateServer(req, opts...) +} + +// WaitForServerRequest is used by WaitForServer method. type WaitForServerRequest struct { ServerID string - Zone utils.Zone - - // Timeout: maximum time to wait before (default: 5 minutes) - Timeout time.Duration + Zone scw.Zone + Timeout time.Duration } // WaitForServer wait for the server to be in a "terminal state" before returning. // This function can be used to wait for a server to be started for example. func (s *API) WaitForServer(req *WaitForServerRequest) (*Server, error) { - - if req.Timeout == 0 { - req.Timeout = 5 * time.Minute - } - terminalStatus := map[ServerState]struct{}{ ServerStateStopped: {}, ServerStateStoppedInPlace: {}, @@ -32,22 +68,329 @@ func (s *API) WaitForServer(req *WaitForServerRequest) (*Server, error) { } server, err := async.WaitSync(&async.WaitSyncConfig{ - Get: func() (interface{}, error, bool) { + Get: func() (interface{}, bool, error) { res, err := s.GetServer(&GetServerRequest{ ServerID: req.ServerID, Zone: req.Zone, }) if err != nil { - return nil, err, false + return nil, false, err } _, isTerminal := terminalStatus[res.Server.State] - return res.Server, err, isTerminal + return res.Server, isTerminal, err }, Timeout: req.Timeout, - IntervalStrategy: async.LinearIntervalStrategy(5 * time.Second), + IntervalStrategy: async.LinearIntervalStrategy(RetryInterval), }) - - return server.(*Server), err + if err != nil { + return nil, errors.Wrap(err, "waiting for server failed") + } + return server.(*Server), nil +} + +// ServerActionAndWaitRequest is used by ServerActionAndWait method. +type ServerActionAndWaitRequest struct { + ServerID string + Zone scw.Zone + Action ServerAction + + // Timeout: maximum time to wait before (default: 5 minutes) + Timeout time.Duration +} + +// ServerActionAndWait start an action and wait for the server to be in the correct "terminal state" +// expected by this action. +func (s *API) ServerActionAndWait(req *ServerActionAndWaitRequest) error { + if req.Timeout == 0 { + req.Timeout = defaultTimeout + } + + _, err := s.ServerAction(&ServerActionRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + Action: req.Action, + }) + if err != nil { + return err + } + + finalServer, err := s.WaitForServer(&WaitForServerRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + Timeout: req.Timeout, + }) + if err != nil { + return err + } + + // check the action was properly executed + expectedState := ServerState("unknown") + switch req.Action { + case ServerActionPoweron, ServerActionReboot: + expectedState = ServerStateRunning + case ServerActionPoweroff: + expectedState = ServerStateStopped + case ServerActionStopInPlace: + expectedState = ServerStateStoppedInPlace + } + + // backup can be performed from any state + if expectedState != ServerState("unknown") && finalServer.State != expectedState { + return errors.New("expected state %s but found %s: %s", expectedState, finalServer.State, finalServer.StateDetail) + } + + return nil +} + +// GetServerTypeRequest is used by GetServerType. +type GetServerTypeRequest struct { + Zone scw.Zone + Name string +} + +// GetServerType get server type info by it's name. +func (s *API) GetServerType(req *GetServerTypeRequest) (*ServerType, error) { + res, err := s.ListServersTypes(&ListServersTypesRequest{ + Zone: req.Zone, + }, scw.WithAllPages()) + + if err != nil { + return nil, err + } + + if serverType, exist := res.Servers[req.Name]; exist { + return serverType, nil + } + + return nil, errors.New("could not find server type %q", req.Name) +} + +// GetServerUserDataRequest is used by GetServerUserData method. +type GetServerUserDataRequest struct { + Zone scw.Zone `json:"-"` + ServerID string `json:"-"` + + // Key defines the user data key to get. + Key string `json:"-"` +} + +// GetServerUserData gets the content of a user data on a server for the given key. +func (s *API) GetServerUserData(req *GetServerUserDataRequest, opts ...scw.RequestOption) (io.Reader, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.ServerID) == "" { + return nil, errors.New("field ServerID cannot be empty in request") + } + + if fmt.Sprint(req.Key) == "" { + return nil, errors.New("field Key cannot be empty in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "GET", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/servers/" + fmt.Sprint(req.ServerID) + "/user_data/" + fmt.Sprint(req.Key), + Headers: http.Header{}, + } + + res := &bytes.Buffer{} + + err = s.client.Do(scwReq, res, opts...) + if err != nil { + return nil, err + } + + return res, nil +} + +// SetServerUserDataRequest is used by SetServerUserData method. +type SetServerUserDataRequest struct { + Zone scw.Zone `json:"-"` + ServerID string `json:"-"` + + // Key defines the user data key to set. + Key string `json:"-"` + + // Content defines the data to set. + Content io.Reader +} + +// SetServerUserData sets the content of a user data on a server for the given key. +func (s *API) SetServerUserData(req *SetServerUserDataRequest, opts ...scw.RequestOption) error { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.ServerID) == "" { + return errors.New("field ServerID cannot be empty in request") + } + + if fmt.Sprint(req.Key) == "" { + return errors.New("field Key cannot be empty in request") + } + + if req.Content == nil { + return errors.New("field Content cannot be nil in request") + } + + scwReq := &scw.ScalewayRequest{ + Method: "PATCH", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/servers/" + fmt.Sprint(req.ServerID) + "/user_data/" + fmt.Sprint(req.Key), + Headers: http.Header{}, + } + + err = scwReq.SetBody(req.Content) + if err != nil { + return err + } + + err = s.client.Do(scwReq, nil, opts...) + if err != nil { + return err + } + + return nil +} + +// GetAllServerUserDataRequest is used by GetAllServerUserData method. +type GetAllServerUserDataRequest struct { + Zone scw.Zone `json:"-"` + ServerID string `json:"-"` +} + +// GetAllServerUserDataResponse is used by GetAllServerUserData method. +type GetAllServerUserDataResponse struct { + UserData map[string]io.Reader `json:"-"` +} + +// GetAllServerUserData gets all user data on a server. +func (s *API) GetAllServerUserData(req *GetAllServerUserDataRequest, opts ...scw.RequestOption) (*GetAllServerUserDataResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.ServerID) == "" { + return nil, errors.New("field ServerID cannot be empty in request") + } + + // get all user data keys + allUserDataRes, err := s.ListServerUserData(&ListServerUserDataRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + }) + if err != nil { + return nil, err + } + + res := &GetAllServerUserDataResponse{ + UserData: make(map[string]io.Reader, len(allUserDataRes.UserData)), + } + + // build a map with all user data + for _, key := range allUserDataRes.UserData { + value, err := s.GetServerUserData(&GetServerUserDataRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + Key: key, + }) + if err != nil { + return nil, err + } + res.UserData[key] = value + } + + return res, nil +} + +// SetAllServerUserDataRequest is used by SetAllServerUserData method. +type SetAllServerUserDataRequest struct { + Zone scw.Zone `json:"-"` + ServerID string `json:"-"` + + // UserData defines all user data that will be set to the server. + // This map is idempotent, it means that all the current data will be overwritten and + // all keys not present in this map will be deleted.. All data will be removed if this map is nil. + UserData map[string]io.Reader `json:"-"` +} + +// SetAllServerUserData sets all user data on a server. +func (s *API) SetAllServerUserData(req *SetAllServerUserDataRequest, opts ...scw.RequestOption) error { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.ServerID) == "" { + return errors.New("field ServerID cannot be empty in request") + } + + // get all current user data keys + allUserDataRes, err := s.ListServerUserData(&ListServerUserDataRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + }) + if err != nil { + return err + } + + // delete all current user data + for _, key := range allUserDataRes.UserData { + _, exist := req.UserData[key] + if exist { + continue + } + err := s.DeleteServerUserData(&DeleteServerUserDataRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + Key: key, + }) + if err != nil { + return err + } + } + + // set all new user data + for key, value := range req.UserData { + err := s.SetServerUserData(&SetServerUserDataRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + Key: key, + Content: value, + }) + if err != nil { + return err + } + } + + return nil } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/volume_utils.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/volume_utils.go new file mode 100644 index 000000000..e4ffe1361 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/instance/v1/volume_utils.go @@ -0,0 +1,113 @@ +package instance + +import ( + "fmt" + "net/http" + "time" + + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +// UpdateVolumeRequest contains the parameters to update on a volume +type UpdateVolumeRequest struct { + Zone scw.Zone `json:"-"` + // VolumeID is the volumes unique ID + VolumeID string `json:"-"` + // Name display the volumes names + Name *string `json:"name,omitempty"` +} + +// UpdateVolumeResponse contains the updated volume. +type UpdateVolumeResponse struct { + Volume *Volume `json:"volume,omitempty"` +} + +// setVolumeRequest contains all the params to PUT volumes +type setVolumeRequest struct { + Zone scw.Zone `json:"-"` + // ID display the volumes unique ID + ID string `json:"id"` + // Name display the volumes names + Name string `json:"name"` + // ExportURI show the volumes NBD export URI + ExportURI string `json:"export_uri"` + // Size display the volumes disk size + Size scw.Size `json:"size"` + // VolumeType display the volumes type + // + // Default value: l_ssd + VolumeType VolumeType `json:"volume_type"` + // CreationDate display the volumes creation date + CreationDate time.Time `json:"creation_date"` + // ModificationDate display the volumes modification date + ModificationDate time.Time `json:"modification_date"` + // Organization display the volumes organization + Organization string `json:"organization"` + // Server display information about the server attached to the volume + Server *ServerSummary `json:"server"` +} + +// UpdateVolume updates the set fields on the volume. +func (s *API) UpdateVolume(req *UpdateVolumeRequest, opts ...scw.RequestOption) (*UpdateVolumeResponse, error) { + var err error + + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } + + if fmt.Sprint(req.Zone) == "" { + return nil, errors.New("field Zone cannot be empty in request") + } + + if fmt.Sprint(req.VolumeID) == "" { + return nil, errors.New("field VolumeID cannot be empty in request") + } + + getVolumeResponse, err := s.GetVolume(&GetVolumeRequest{ + Zone: req.Zone, + VolumeID: req.VolumeID, + }) + if err != nil { + return nil, err + } + + setVolumeRequest := &setVolumeRequest{ + Zone: req.Zone, + ID: getVolumeResponse.Volume.ID, + Name: getVolumeResponse.Volume.Name, + ExportURI: getVolumeResponse.Volume.ExportURI, + Size: getVolumeResponse.Volume.Size, + VolumeType: getVolumeResponse.Volume.VolumeType, + CreationDate: getVolumeResponse.Volume.CreationDate, + ModificationDate: getVolumeResponse.Volume.ModificationDate, + Organization: getVolumeResponse.Volume.Organization, + Server: getVolumeResponse.Volume.Server, + } + + // Override the values that need to be updated + if req.Name != nil { + setVolumeRequest.Name = *req.Name + } + + scwReq := &scw.ScalewayRequest{ + Method: "PUT", + Path: "/instance/v1/zones/" + fmt.Sprint(req.Zone) + "/volumes/" + fmt.Sprint(req.VolumeID) + "", + Headers: http.Header{}, + } + + err = scwReq.SetBody(setVolumeRequest) + if err != nil { + return nil, err + } + + var res UpdateVolumeResponse + + err = s.client.Do(scwReq, &res, opts...) + if err != nil { + return nil, err + } + + return &res, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_sdk.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_sdk.go index 58c8f1af2..6cfa674e0 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_sdk.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_sdk.go @@ -1,6 +1,7 @@ // This file was automatically generated. DO NOT EDIT. // If you have any remark or suggestion do not hesitate to open an issue. +// Package marketplace provides methods and message types of the marketplace v1 API. package marketplace import ( @@ -15,8 +16,8 @@ import ( "github.com/scaleway/scaleway-sdk-go/internal/errors" "github.com/scaleway/scaleway-sdk-go/internal/marshaler" "github.com/scaleway/scaleway-sdk-go/internal/parameter" + "github.com/scaleway/scaleway-sdk-go/namegenerator" "github.com/scaleway/scaleway-sdk-go/scw" - "github.com/scaleway/scaleway-sdk-go/utils" ) // always import dependencies @@ -31,8 +32,9 @@ var ( _ scw.ScalewayRequest _ marshaler.Duration - _ utils.File + _ scw.File _ = parameter.AddToQuery + _ = namegenerator.GetRandomName ) // API marketplace API @@ -48,79 +50,91 @@ func NewAPI(client *scw.Client) *API { } type GetImageResponse struct { - Image *Image `json:"image,omitempty"` + Image *Image `json:"image"` } type GetServiceInfoResponse struct { - API string `json:"api,omitempty"` + API string `json:"api"` - Description string `json:"description,omitempty"` + Description string `json:"description"` - Version string `json:"version,omitempty"` + Version string `json:"version"` } type GetVersionResponse struct { - Version *Version `json:"version,omitempty"` + Version *Version `json:"version"` } +// Image image type Image struct { - ID string `json:"id,omitempty"` + // ID uUID of this image + ID string `json:"id"` + // Name name of the image + Name string `json:"name"` + // Description text description of this image + Description string `json:"description"` + // Logo uRL of this image's logo + Logo string `json:"logo"` + // Categories list of categories this image belongs to + Categories []string `json:"categories"` + // CreationDate creation date of this image + CreationDate time.Time `json:"creation_date"` + // ModificationDate date of the last modification of this image + ModificationDate time.Time `json:"modification_date"` + // ValidUntil expiration date of this image + ValidUntil time.Time `json:"valid_until"` + // Label label of this image + Label string `json:"label"` + // Versions list of versions of this image + Versions []*Version `json:"versions"` + // Organization organization this image belongs to + Organization *Organization `json:"organization"` - Name string `json:"name,omitempty"` - - Description string `json:"description,omitempty"` - - Logo string `json:"logo,omitempty"` - - Categories []string `json:"categories,omitempty"` - - Organization *Organization `json:"organization,omitempty"` - - ValidUntil time.Time `json:"valid_until,omitempty"` - - CreationDate time.Time `json:"creation_date,omitempty"` - - ModificationDate time.Time `json:"modification_date,omitempty"` - - Versions []*Version `json:"versions,omitempty"` - - CurrentPublicVersion string `json:"current_public_version,omitempty"` + CurrentPublicVersion string `json:"current_public_version"` } type ListImagesResponse struct { - Images []*Image `json:"images,omitempty"` + Images []*Image `json:"images"` + + TotalCount uint32 `json:"total_count"` } type ListVersionsResponse struct { - Versions []*Version `json:"versions,omitempty"` + Versions []*Version `json:"versions"` + + TotalCount uint32 `json:"total_count"` } +// LocalImage local image type LocalImage struct { - ID string `json:"id,omitempty"` - - Arch string `json:"arch,omitempty"` - - Zone utils.Zone `json:"zone,omitempty"` - - CompatibleCommercialTypes []string `json:"compatible_commercial_types,omitempty"` + // ID uUID of this local image + ID string `json:"id"` + // CompatibleCommercialTypes list of all commercial types that are compatible with this local image + CompatibleCommercialTypes []string `json:"compatible_commercial_types"` + // Arch supported architecture for this local image + Arch string `json:"arch"` + // Zone availability Zone where this local image is available + Zone scw.Zone `json:"zone"` } type Organization struct { - ID string `json:"id,omitempty"` + ID string `json:"id"` - Name string `json:"name,omitempty"` + Name string `json:"name"` } +// Version version type Version struct { - ID string `json:"id,omitempty"` - - Name string `json:"name,omitempty"` - - CreationDate time.Time `json:"creation_date,omitempty"` - - ModificationDate time.Time `json:"modification_date,omitempty"` - - LocalImages []*LocalImage `json:"local_images,omitempty"` + // ID uUID of this version + ID string `json:"id"` + // Name name of this version + Name string `json:"name"` + // CreationDate creation date of this image version + CreationDate time.Time `json:"creation_date"` + // ModificationDate date of the last modification of this version + ModificationDate time.Time `json:"modification_date"` + // LocalImages list of local images available in this version + LocalImages []*LocalImage `json:"local_images"` } // Service API @@ -147,11 +161,13 @@ func (s *API) GetServiceInfo(req *GetServiceInfoRequest, opts ...scw.RequestOpti } type ListImagesRequest struct { - PerPage *int32 `json:"-"` - + // PerPage a positive integer lower or equal to 100 to select the number of items to display + PerPage *uint32 `json:"-"` + // Page a positive integer to choose the page to display Page *int32 `json:"-"` } +// ListImages list marketplace images func (s *API) ListImages(req *ListImagesRequest, opts ...scw.RequestOption) (*ListImagesResponse, error) { var err error @@ -180,10 +196,31 @@ func (s *API) ListImages(req *ListImagesRequest, opts ...scw.RequestOption) (*Li return &resp, nil } +// UnsafeGetTotalCount should not be used +// Internal usage only +func (r *ListImagesResponse) UnsafeGetTotalCount() uint32 { + return r.TotalCount +} + +// UnsafeAppend should not be used +// Internal usage only +func (r *ListImagesResponse) UnsafeAppend(res interface{}) (uint32, error) { + results, ok := res.(*ListImagesResponse) + if !ok { + return 0, errors.New("%T type cannot be appended to type %T", res, r) + } + + r.Images = append(r.Images, results.Images...) + r.TotalCount += uint32(len(results.Images)) + return uint32(len(results.Images)), nil +} + type GetImageRequest struct { + // ImageID display the image name ImageID string `json:"-"` } +// GetImage get a specific marketplace image func (s *API) GetImage(req *GetImageRequest, opts ...scw.RequestOption) (*GetImageResponse, error) { var err error diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_utils.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_utils.go index a8c90e55b..2d78bb266 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_utils.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/api/marketplace/v1/marketplace_utils.go @@ -2,16 +2,16 @@ package marketplace import ( "fmt" + "strings" - "github.com/scaleway/scaleway-sdk-go/utils" + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/scw" ) // getLocalImage returns the correct local version of an image matching // the current zone and the compatible commercial type -func (version *Version) getLocalImage(zone utils.Zone, commercialType string) (*LocalImage, error) { - +func (version *Version) getLocalImage(zone scw.Zone, commercialType string) (*LocalImage, error) { for _, localImage := range version.LocalImages { - // Check if in correct zone if localImage.Zone != zone { continue @@ -26,56 +26,73 @@ func (version *Version) getLocalImage(zone utils.Zone, commercialType string) (* } return nil, fmt.Errorf("couldn't find compatible local image for this image version (%s)", version.ID) - } // getLatestVersion returns the current/latests version on an image, // or an error in case the image doesn't have a public version. func (image *Image) getLatestVersion() (*Version, error) { - for _, version := range image.Versions { if version.ID == image.CurrentPublicVersion { return version, nil } } - return nil, fmt.Errorf("latest version could not be found for image %s", image.Name) + return nil, errors.New("latest version could not be found for image %s", image.Label) } -// FindLocalImageIDByName search for an image with the given name (exact match) in the given region +// GetLocalImageIDByLabelRequest is used by GetLocalImageIDByLabel +type GetLocalImageIDByLabelRequest struct { + ImageLabel string + Zone scw.Zone + CommercialType string +} + +// GetLocalImageIDByLabel search for an image with the given label (exact match) in the given region // it returns the latest version of this specific image. -func (s *API) FindLocalImageIDByName(imageName string, zone utils.Zone, commercialType string) (string, error) { +func (s *API) GetLocalImageIDByLabel(req *GetLocalImageIDByLabelRequest) (string, error) { + if req.Zone == "" { + defaultZone, _ := s.client.GetDefaultZone() + req.Zone = defaultZone + } listImageRequest := &ListImagesRequest{} - listImageResponse, err := s.ListImages(listImageRequest) + listImageResponse, err := s.ListImages(listImageRequest, scw.WithAllPages()) if err != nil { return "", err } - // TODO: handle pagination - images := listImageResponse.Images - _ = images + label := strings.Replace(req.ImageLabel, "-", "_", -1) + commercialType := strings.ToUpper(req.CommercialType) for _, image := range images { - - // Match name of the image - if image.Name == imageName { - + // Match label of the image + if label == image.Label { latestVersion, err := image.getLatestVersion() if err != nil { - return "", fmt.Errorf("couldn't find a matching image for the given name (%s), zone (%s) and commercial type (%s): %s", imageName, zone, commercialType, err) + return "", errors.Wrap(err, "couldn't find a matching image for the given label (%s), zone (%s) and commercial type (%s)", req.ImageLabel, req.Zone, req.CommercialType) } - localImage, err := latestVersion.getLocalImage(zone, commercialType) + localImage, err := latestVersion.getLocalImage(req.Zone, commercialType) if err != nil { - return "", fmt.Errorf("couldn't find a matching image for the given name (%s), zone (%s) and commercial type (%s): %s", imageName, zone, commercialType, err) + return "", errors.Wrap(err, "couldn't find a matching image for the given label (%s), zone (%s) and commercial type (%s)", req.ImageLabel, req.Zone, req.CommercialType) } return localImage.ID, nil } - } - return "", fmt.Errorf("couldn't find a matching image for the given name (%s), zone (%s) and commercial type (%s)", imageName, zone, commercialType) + return "", errors.New("couldn't find a matching image for the given label (%s), zone (%s) and commercial type (%s)", req.ImageLabel, req.Zone, req.CommercialType) +} + +// UnsafeSetTotalCount should not be used +// Internal usage only +func (r *ListImagesResponse) UnsafeSetTotalCount(totalCount int) { + r.TotalCount = uint32(totalCount) +} + +// UnsafeSetTotalCount should not be used +// Internal usage only +func (r *ListVersionsResponse) UnsafeSetTotalCount(totalCount int) { + r.TotalCount = uint32(totalCount) } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/async/wait.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/async/wait.go index 60fcb83e9..7e0d2158f 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/async/wait.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/async/wait.go @@ -15,7 +15,7 @@ type IntervalStrategy func() <-chan time.Time // WaitSyncConfig defines the waiting options. type WaitSyncConfig struct { // This method will be called from another goroutine. - Get func() (value interface{}, err error, isTerminal bool) + Get func() (value interface{}, isTerminal bool, err error) IntervalStrategy IntervalStrategy Timeout time.Duration } @@ -43,6 +43,7 @@ func WaitSync(config *WaitSyncConfig) (terminalValue interface{}, err error) { if config.IntervalStrategy == nil { config.IntervalStrategy = LinearIntervalStrategy(defaultInterval) } + if config.Timeout == 0 { config.Timeout = defaultTimeout } @@ -54,7 +55,7 @@ func WaitSync(config *WaitSyncConfig) (terminalValue interface{}, err error) { go func() { for { // get the payload - value, err, stopCondition := config.Get() + value, stopCondition, err := config.Get() // send the payload if err != nil { diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/no_auth.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/no_auth.go index f7ec2409d..2181c57c2 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/no_auth.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/no_auth.go @@ -2,18 +2,18 @@ package auth import "net/http" -type noAuth struct { +type NoAuth struct { } // NewNoAuth return an auth with no authentication method -func NewNoAuth() *noAuth { - return &noAuth{} +func NewNoAuth() *NoAuth { + return &NoAuth{} } -func (t *noAuth) Headers() http.Header { +func (t *NoAuth) Headers() http.Header { return http.Header{} } -func (t *noAuth) AnonymizedHeaders() http.Header { +func (t *NoAuth) AnonymizedHeaders() http.Header { return http.Header{} } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/token.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/token.go index ec19d1c09..6a0902755 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/token.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/auth/token.go @@ -2,41 +2,44 @@ package auth import "net/http" -type token struct { - accessKey string - secretKey string +// Token is the pair accessKey + secretKey. +// This type is public because it's an internal package. +type Token struct { + AccessKey string + SecretKey string } // XAuthTokenHeader is Scaleway standard auth header -const XAuthTokenHeader = "X-Auth-Token" +const XAuthTokenHeader = "X-Auth-Token" // #nosec G101 // NewToken create a token authentication from an // access key and a secret key -func NewToken(accessKey, secretKey string) *token { - return &token{accessKey: accessKey, secretKey: secretKey} +func NewToken(accessKey, secretKey string) *Token { + return &Token{AccessKey: accessKey, SecretKey: secretKey} } // Headers returns headers that must be add to the http request -func (t *token) Headers() http.Header { +func (t *Token) Headers() http.Header { headers := http.Header{} - headers.Set(XAuthTokenHeader, t.secretKey) + headers.Set(XAuthTokenHeader, t.SecretKey) return headers } // AnonymizedHeaders returns an anonymized version of Headers() // This method could be use for logging purpose. -func (t *token) AnonymizedHeaders() http.Header { +func (t *Token) AnonymizedHeaders() http.Header { headers := http.Header{} - var secret string - - switch { - case len(t.secretKey) == 0: - secret = "" - case len(t.secretKey) > 8: - secret = t.secretKey[0:8] + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - default: - secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - headers.Set(XAuthTokenHeader, secret) + headers.Set(XAuthTokenHeader, HideSecretKey(t.SecretKey)) return headers } + +func HideSecretKey(k string) string { + switch { + case len(k) == 0: + return "" + case len(k) > 8: + return k[0:8] + "-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + default: + return "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/errors/error.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/errors/error.go index bc126bed7..351dd7084 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/errors/error.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/errors/error.go @@ -4,20 +4,20 @@ import "fmt" // Error is a base error that implement scw.SdkError type Error struct { - str string - err error + Str string + Err error } // Error implement standard xerror.Wrapper interface func (e *Error) Unwrap() error { - return e.err + return e.Err } // Error implement standard error interface func (e *Error) Error() string { - str := "[scaleway-sdk-go] " + e.str - if e.err != nil { - str += ": " + e.err.Error() + str := "scaleway-sdk-go: " + e.Str + if e.Err != nil { + str += ": " + e.Err.Error() } return str } @@ -28,14 +28,14 @@ func (e *Error) IsScwSdkError() {} // New creates a new error with that same interface as fmt.Errorf func New(format string, args ...interface{}) *Error { return &Error{ - str: fmt.Sprintf(format, args...), + Str: fmt.Sprintf(format, args...), } } // Wrap an error with additional information func Wrap(err error, format string, args ...interface{}) *Error { return &Error{ - err: err, - str: fmt.Sprintf(format, args...), + Err: err, + Str: fmt.Sprintf(format, args...), } } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/marshaler/duration.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/marshaler/duration.go index 5b07ee9cb..0eaf70e56 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/marshaler/duration.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/marshaler/duration.go @@ -137,3 +137,24 @@ func (ds *LongDurationSlice) Standard() []*time.Duration { } return t } + +// LongDurationint32Map is a int32 map of *LongDuration +type LongDurationint32Map map[int32]*LongDuration + +// NewLongDurationint32Map converts a map[int32]*time.LongDuration to a LongDurationint32Map type. +func NewLongDurationint32Map(t map[int32]*time.Duration) LongDurationint32Map { + dm := make(LongDurationint32Map, len(t)) + for i := range t { + dm[i] = NewLongDuration(t[i]) + } + return dm +} + +// Standard converts a LongDurationint32Map to a map[int32]*time.LongDuration type. +func (dm *LongDurationint32Map) Standard() map[int32]*time.Duration { + t := make(map[int32]*time.Duration, len(*dm)) + for key, value := range *dm { + t[key] = value.Standard() + } + return t +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/parameter/query.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/parameter/query.go index d72854d25..d140bd45e 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/parameter/query.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/internal/parameter/query.go @@ -27,5 +27,4 @@ func AddToQuery(query url.Values, key string, value interface{}) { default: query.Add(key, fmt.Sprint(elemValue.Interface())) } - } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/logger/default_logger.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/logger/default_logger.go index 6636af29d..04316d8e5 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/logger/default_logger.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/logger/default_logger.go @@ -94,9 +94,18 @@ func newLogger(w io.Writer, level LogLevel) *loggerT { // Info logs will be written to infoW and debugW. // Debug logs will be written to debugW. var m [4]*log.Logger - m[LogLevelError] = log.New(io.MultiWriter(debugW, infoW, warningW, errorW), severityName[LogLevelError]+": ", log.LstdFlags) - m[LogLevelWarning] = log.New(io.MultiWriter(debugW, infoW, warningW), severityName[LogLevelWarning]+": ", log.LstdFlags) - m[LogLevelInfo] = log.New(io.MultiWriter(debugW, infoW), severityName[LogLevelInfo]+": ", log.LstdFlags) - m[LogLevelDebug] = log.New(debugW, severityName[LogLevelDebug]+": ", log.LstdFlags) + + m[LogLevelError] = log.New(io.MultiWriter(debugW, infoW, warningW, errorW), + severityName[LogLevelError]+": ", log.LstdFlags) + + m[LogLevelWarning] = log.New(io.MultiWriter(debugW, infoW, warningW), + severityName[LogLevelWarning]+": ", log.LstdFlags) + + m[LogLevelInfo] = log.New(io.MultiWriter(debugW, infoW), + severityName[LogLevelInfo]+": ", log.LstdFlags) + + m[LogLevelDebug] = log.New(debugW, + severityName[LogLevelDebug]+": ", log.LstdFlags) + return &loggerT{m: m, v: level} } diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/namegenerator/name_generator.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/namegenerator/name_generator.go new file mode 100644 index 000000000..11fda4532 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/namegenerator/name_generator.go @@ -0,0 +1,863 @@ +// Source: github.com/docker/docker/pkg/namesgenerator + +package namegenerator + +import ( + "math/rand" + "strings" + "time" +) + +var r *rand.Rand + +func init() { + source := rand.NewSource(time.Now().UnixNano()) + r = rand.New(source) +} + +var ( + left = [...]string{ + "admiring", + "adoring", + "affectionate", + "agitated", + "amazing", + "angry", + "awesome", + "beautiful", + "blissful", + "bold", + "boring", + "brave", + "busy", + "charming", + "clever", + "cocky", + "cool", + "compassionate", + "competent", + "condescending", + "confident", + "cranky", + "crazy", + "dazzling", + "determined", + "distracted", + "dreamy", + "eager", + "ecstatic", + "elastic", + "elated", + "elegant", + "eloquent", + "epic", + "exciting", + "fervent", + "festive", + "flamboyant", + "focused", + "friendly", + "frosty", + "funny", + "gallant", + "gifted", + "goofy", + "gracious", + "great", + "happy", + "hardcore", + "heuristic", + "hopeful", + "hungry", + "infallible", + "inspiring", + "interesting", + "intelligent", + "jolly", + "jovial", + "keen", + "kind", + "laughing", + "loving", + "lucid", + "magical", + "mystifying", + "modest", + "musing", + "naughty", + "nervous", + "nice", + "nifty", + "nostalgic", + "objective", + "optimistic", + "peaceful", + "pedantic", + "pensive", + "practical", + "priceless", + "quirky", + "quizzical", + "recursing", + "relaxed", + "reverent", + "romantic", + "sad", + "serene", + "sharp", + "silly", + "sleepy", + "stoic", + "strange", + "stupefied", + "suspicious", + "sweet", + "tender", + "thirsty", + "trusting", + "unruffled", + "upbeat", + "vibrant", + "vigilant", + "vigorous", + "wizardly", + "wonderful", + "xenodochial", + "youthful", + "zealous", + "zen", + } + + // Docker, starting from 0.7.x, generates names from notable scientists and hackers. + // Please, for any amazing man that you add to the list, consider adding an equally amazing woman to it, and vice versa. + right = [...]string{ + // Muhammad ibn Jābir al-Ḥarrānī al-Battānī was a founding father of astronomy. https://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_J%C4%81bir_al-%E1%B8%A4arr%C4%81n%C4%AB_al-Batt%C4%81n%C4%AB + "albattani", + + // Frances E. Allen, became the first female IBM Fellow in 1989. In 2006, she became the first female recipient of the ACM's Turing Award. https://en.wikipedia.org/wiki/Frances_E._Allen + "allen", + + // June Almeida - Scottish virologist who took the first pictures of the rubella virus - https://en.wikipedia.org/wiki/June_Almeida + "almeida", + + // Kathleen Antonelli, American computer programmer and one of the six original programmers of the ENIAC - https://en.wikipedia.org/wiki/Kathleen_Antonelli + "antonelli", + + // Maria Gaetana Agnesi - Italian mathematician, philosopher, theologian and humanitarian. She was the first woman to write a mathematics handbook and the first woman appointed as a Mathematics Professor at a University. https://en.wikipedia.org/wiki/Maria_Gaetana_Agnesi + "agnesi", + + // Archimedes was a physicist, engineer and mathematician who invented too many things to list them here. https://en.wikipedia.org/wiki/Archimedes + "archimedes", + + // Maria Ardinghelli - Italian translator, mathematician and physicist - https://en.wikipedia.org/wiki/Maria_Ardinghelli + "ardinghelli", + + // Aryabhata - Ancient Indian mathematician-astronomer during 476-550 CE https://en.wikipedia.org/wiki/Aryabhata + "aryabhata", + + // Wanda Austin - Wanda Austin is the President and CEO of The Aerospace Corporation, a leading architect for the US security space programs. https://en.wikipedia.org/wiki/Wanda_Austin + "austin", + + // Charles Babbage invented the concept of a programmable computer. https://en.wikipedia.org/wiki/Charles_Babbage. + "babbage", + + // Stefan Banach - Polish mathematician, was one of the founders of modern functional analysis. https://en.wikipedia.org/wiki/Stefan_Banach + "banach", + + // Buckaroo Banzai and his mentor Dr. Hikita perfectd the "oscillation overthruster", a device that allows one to pass through solid matter. - https://en.wikipedia.org/wiki/The_Adventures_of_Buckaroo_Banzai_Across_the_8th_Dimension + "banzai", + + // John Bardeen co-invented the transistor - https://en.wikipedia.org/wiki/John_Bardeen + "bardeen", + + // Jean Bartik, born Betty Jean Jennings, was one of the original programmers for the ENIAC computer. https://en.wikipedia.org/wiki/Jean_Bartik + "bartik", + + // Laura Bassi, the world's first female professor https://en.wikipedia.org/wiki/Laura_Bassi + "bassi", + + // Hugh Beaver, British engineer, founder of the Guinness Book of World Records https://en.wikipedia.org/wiki/Hugh_Beaver + "beaver", + + // Alexander Graham Bell - an eminent Scottish-born scientist, inventor, engineer and innovator who is credited with inventing the first practical telephone - https://en.wikipedia.org/wiki/Alexander_Graham_Bell + "bell", + + // Karl Friedrich Benz - a German automobile engineer. Inventor of the first practical motorcar. https://en.wikipedia.org/wiki/Karl_Benz + "benz", + + // Homi J Bhabha - was an Indian nuclear physicist, founding director, and professor of physics at the Tata Institute of Fundamental Research. Colloquially known as "father of Indian nuclear programme"- https://en.wikipedia.org/wiki/Homi_J._Bhabha + "bhabha", + + // Bhaskara II - Ancient Indian mathematician-astronomer whose work on calculus predates Newton and Leibniz by over half a millennium - https://en.wikipedia.org/wiki/Bh%C4%81skara_II#Calculus + "bhaskara", + + // Sue Black - British computer scientist and campaigner. She has been instrumental in saving Bletchley Park, the site of World War II codebreaking - https://en.wikipedia.org/wiki/Sue_Black_(computer_scientist) + "black", + + // Elizabeth Helen Blackburn - Australian-American Nobel laureate; best known for co-discovering telomerase. https://en.wikipedia.org/wiki/Elizabeth_Blackburn + "blackburn", + + // Elizabeth Blackwell - American doctor and first American woman to receive a medical degree - https://en.wikipedia.org/wiki/Elizabeth_Blackwell + "blackwell", + + // Niels Bohr is the father of quantum theory. https://en.wikipedia.org/wiki/Niels_Bohr. + "bohr", + + // Kathleen Booth, she's credited with writing the first assembly language. https://en.wikipedia.org/wiki/Kathleen_Booth + "booth", + + // Anita Borg - Anita Borg was the founding director of the Institute for Women and Technology (IWT). https://en.wikipedia.org/wiki/Anita_Borg + "borg", + + // Satyendra Nath Bose - He provided the foundation for Bose–Einstein statistics and the theory of the Bose–Einstein condensate. - https://en.wikipedia.org/wiki/Satyendra_Nath_Bose + "bose", + + // Katherine Louise Bouman is an imaging scientist and Assistant Professor of Computer Science at the California Institute of Technology. She researches computational methods for imaging, and developed an algorithm that made possible the picture first visualization of a black hole using the Event Horizon Telescope. - https://en.wikipedia.org/wiki/Katie_Bouman + "bouman", + + // Evelyn Boyd Granville - She was one of the first African-American woman to receive a Ph.D. in mathematics; she earned it in 1949 from Yale University. https://en.wikipedia.org/wiki/Evelyn_Boyd_Granville + "boyd", + + // Brahmagupta - Ancient Indian mathematician during 598-670 CE who gave rules to compute with zero - https://en.wikipedia.org/wiki/Brahmagupta#Zero + "brahmagupta", + + // Walter Houser Brattain co-invented the transistor - https://en.wikipedia.org/wiki/Walter_Houser_Brattain + "brattain", + + // Emmett Brown invented time travel. https://en.wikipedia.org/wiki/Emmett_Brown (thanks Brian Goff) + "brown", + + // Linda Brown Buck - American biologist and Nobel laureate best known for her genetic and molecular analyses of the mechanisms of smell. https://en.wikipedia.org/wiki/Linda_B._Buck + "buck", + + // Dame Susan Jocelyn Bell Burnell - Northern Irish astrophysicist who discovered radio pulsars and was the first to analyse them. https://en.wikipedia.org/wiki/Jocelyn_Bell_Burnell + "burnell", + + // Annie Jump Cannon - pioneering female astronomer who classified hundreds of thousands of stars and created the system we use to understand stars today. https://en.wikipedia.org/wiki/Annie_Jump_Cannon + "cannon", + + // Rachel Carson - American marine biologist and conservationist, her book Silent Spring and other writings are credited with advancing the global environmental movement. https://en.wikipedia.org/wiki/Rachel_Carson + "carson", + + // Dame Mary Lucy Cartwright - British mathematician who was one of the first to study what is now known as chaos theory. Also known for Cartwright's theorem which finds applications in signal processing. https://en.wikipedia.org/wiki/Mary_Cartwright + "cartwright", + + // Vinton Gray Cerf - American Internet pioneer, recognised as one of "the fathers of the Internet". With Robert Elliot Kahn, he designed TCP and IP, the primary data communication protocols of the Internet and other computer networks. https://en.wikipedia.org/wiki/Vint_Cerf + "cerf", + + // Subrahmanyan Chandrasekhar - Astrophysicist known for his mathematical theory on different stages and evolution in structures of the stars. He has won nobel prize for physics - https://en.wikipedia.org/wiki/Subrahmanyan_Chandrasekhar + "chandrasekhar", + + // Sergey Alexeyevich Chaplygin (Russian: Серге́й Алексе́евич Чаплы́гин; April 5, 1869 – October 8, 1942) was a Russian and Soviet physicist, mathematician, and mechanical engineer. He is known for mathematical formulas such as Chaplygin's equation and for a hypothetical substance in cosmology called Chaplygin gas, named after him. https://en.wikipedia.org/wiki/Sergey_Chaplygin + "chaplygin", + + // Émilie du Châtelet - French natural philosopher, mathematician, physicist, and author during the early 1730s, known for her translation of and commentary on Isaac Newton's book Principia containing basic laws of physics. https://en.wikipedia.org/wiki/%C3%89milie_du_Ch%C3%A2telet + "chatelet", + + // Asima Chatterjee was an Indian organic chemist noted for her research on vinca alkaloids, development of drugs for treatment of epilepsy and malaria - https://en.wikipedia.org/wiki/Asima_Chatterjee + "chatterjee", + + // Pafnuty Chebyshev - Russian mathematician. He is known fo his works on probability, statistics, mechanics, analytical geometry and number theory https://en.wikipedia.org/wiki/Pafnuty_Chebyshev + "chebyshev", + + // Bram Cohen - American computer programmer and author of the BitTorrent peer-to-peer protocol. https://en.wikipedia.org/wiki/Bram_Cohen + "cohen", + + // David Lee Chaum - American computer scientist and cryptographer. Known for his seminal contributions in the field of anonymous communication. https://en.wikipedia.org/wiki/David_Chaum + "chaum", + + // Joan Clarke - Bletchley Park code breaker during the Second World War who pioneered techniques that remained top secret for decades. Also an accomplished numismatist https://en.wikipedia.org/wiki/Joan_Clarke + "clarke", + + // Jane Colden - American botanist widely considered the first female American botanist - https://en.wikipedia.org/wiki/Jane_Colden + "colden", + + // Gerty Theresa Cori - American biochemist who became the third woman—and first American woman—to win a Nobel Prize in science, and the first woman to be awarded the Nobel Prize in Physiology or Medicine. Cori was born in Prague. https://en.wikipedia.org/wiki/Gerty_Cori + "cori", + + // Seymour Roger Cray was an American electrical engineer and supercomputer architect who designed a series of computers that were the fastest in the world for decades. https://en.wikipedia.org/wiki/Seymour_Cray + "cray", + + // This entry reflects a husband and wife team who worked together: + // Joan Curran was a Welsh scientist who developed radar and invented chaff, a radar countermeasure. https://en.wikipedia.org/wiki/Joan_Curran + // Samuel Curran was an Irish physicist who worked alongside his wife during WWII and invented the proximity fuse. https://en.wikipedia.org/wiki/Samuel_Curran + "curran", + + // Marie Curie discovered radioactivity. https://en.wikipedia.org/wiki/Marie_Curie. + "curie", + + // Charles Darwin established the principles of natural evolution. https://en.wikipedia.org/wiki/Charles_Darwin. + "darwin", + + // Leonardo Da Vinci invented too many things to list here. https://en.wikipedia.org/wiki/Leonardo_da_Vinci. + "davinci", + + // A. K. (Alexander Keewatin) Dewdney, Canadian mathematician, computer scientist, author and filmmaker. Contributor to Scientific American's "Computer Recreations" from 1984 to 1991. Author of Core War (program), The Planiverse, The Armchair Universe, The Magic Machine, The New Turing Omnibus, and more. https://en.wikipedia.org/wiki/Alexander_Dewdney + "dewdney", + + // Satish Dhawan - Indian mathematician and aerospace engineer, known for leading the successful and indigenous development of the Indian space programme. https://en.wikipedia.org/wiki/Satish_Dhawan + "dhawan", + + // Bailey Whitfield Diffie - American cryptographer and one of the pioneers of public-key cryptography. https://en.wikipedia.org/wiki/Whitfield_Diffie + "diffie", + + // Edsger Wybe Dijkstra was a Dutch computer scientist and mathematical scientist. https://en.wikipedia.org/wiki/Edsger_W._Dijkstra. + "dijkstra", + + // Paul Adrien Maurice Dirac - English theoretical physicist who made fundamental contributions to the early development of both quantum mechanics and quantum electrodynamics. https://en.wikipedia.org/wiki/Paul_Dirac + "dirac", + + // Agnes Meyer Driscoll - American cryptanalyst during World Wars I and II who successfully cryptanalysed a number of Japanese ciphers. She was also the co-developer of one of the cipher machines of the US Navy, the CM. https://en.wikipedia.org/wiki/Agnes_Meyer_Driscoll + "driscoll", + + // Donna Dubinsky - played an integral role in the development of personal digital assistants (PDAs) serving as CEO of Palm, Inc. and co-founding Handspring. https://en.wikipedia.org/wiki/Donna_Dubinsky + "dubinsky", + + // Annie Easley - She was a leading member of the team which developed software for the Centaur rocket stage and one of the first African-Americans in her field. https://en.wikipedia.org/wiki/Annie_Easley + "easley", + + // Thomas Alva Edison, prolific inventor https://en.wikipedia.org/wiki/Thomas_Edison + "edison", + + // Albert Einstein invented the general theory of relativity. https://en.wikipedia.org/wiki/Albert_Einstein + "einstein", + + // Alexandra Asanovna Elbakyan (Russian: Алекса́ндра Аса́новна Элбакя́н) is a Kazakhstani graduate student, computer programmer, internet pirate in hiding, and the creator of the site Sci-Hub. Nature has listed her in 2016 in the top ten people that mattered in science, and Ars Technica has compared her to Aaron Swartz. - https://en.wikipedia.org/wiki/Alexandra_Elbakyan + "elbakyan", + + // Taher A. ElGamal - Egyptian cryptographer best known for the ElGamal discrete log cryptosystem and the ElGamal digital signature scheme. https://en.wikipedia.org/wiki/Taher_Elgamal + "elgamal", + + // Gertrude Elion - American biochemist, pharmacologist and the 1988 recipient of the Nobel Prize in Medicine - https://en.wikipedia.org/wiki/Gertrude_Elion + "elion", + + // James Henry Ellis - British engineer and cryptographer employed by the GCHQ. Best known for conceiving for the first time, the idea of public-key cryptography. https://en.wikipedia.org/wiki/James_H._Ellis + "ellis", + + // Douglas Engelbart gave the mother of all demos: https://en.wikipedia.org/wiki/Douglas_Engelbart + "engelbart", + + // Euclid invented geometry. https://en.wikipedia.org/wiki/Euclid + "euclid", + + // Leonhard Euler invented large parts of modern mathematics. https://de.wikipedia.org/wiki/Leonhard_Euler + "euler", + + // Michael Faraday - British scientist who contributed to the study of electromagnetism and electrochemistry. https://en.wikipedia.org/wiki/Michael_Faraday + "faraday", + + // Horst Feistel - German-born American cryptographer who was one of the earliest non-government researchers to study the design and theory of block ciphers. Co-developer of DES and Lucifer. Feistel networks, a symmetric structure used in the construction of block ciphers are named after him. https://en.wikipedia.org/wiki/Horst_Feistel + "feistel", + + // Pierre de Fermat pioneered several aspects of modern mathematics. https://en.wikipedia.org/wiki/Pierre_de_Fermat + "fermat", + + // Enrico Fermi invented the first nuclear reactor. https://en.wikipedia.org/wiki/Enrico_Fermi. + "fermi", + + // Richard Feynman was a key contributor to quantum mechanics and particle physics. https://en.wikipedia.org/wiki/Richard_Feynman + "feynman", + + // Benjamin Franklin is famous for his experiments in electricity and the invention of the lightning rod. + "franklin", + + // Yuri Alekseyevich Gagarin - Soviet pilot and cosmonaut, best known as the first human to journey into outer space. https://en.wikipedia.org/wiki/Yuri_Gagarin + "gagarin", + + // Galileo was a founding father of modern astronomy, and faced politics and obscurantism to establish scientific truth. https://en.wikipedia.org/wiki/Galileo_Galilei + "galileo", + + // Évariste Galois - French mathematician whose work laid the foundations of Galois theory and group theory, two major branches of abstract algebra, and the subfield of Galois connections, all while still in his late teens. https://en.wikipedia.org/wiki/%C3%89variste_Galois + "galois", + + // Kadambini Ganguly - Indian physician, known for being the first South Asian female physician, trained in western medicine, to graduate in South Asia. https://en.wikipedia.org/wiki/Kadambini_Ganguly + "ganguly", + + // William Henry "Bill" Gates III is an American business magnate, philanthropist, investor, computer programmer, and inventor. https://en.wikipedia.org/wiki/Bill_Gates + "gates", + + // Johann Carl Friedrich Gauss - German mathematician who made significant contributions to many fields, including number theory, algebra, statistics, analysis, differential geometry, geodesy, geophysics, mechanics, electrostatics, magnetic fields, astronomy, matrix theory, and optics. https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss + "gauss", + + // Marie-Sophie Germain - French mathematician, physicist and philosopher. Known for her work on elasticity theory, number theory and philosophy. https://en.wikipedia.org/wiki/Sophie_Germain + "germain", + + // Adele Goldberg, was one of the designers and developers of the Smalltalk language. https://en.wikipedia.org/wiki/Adele_Goldberg_(computer_scientist) + "goldberg", + + // Adele Goldstine, born Adele Katz, wrote the complete technical description for the first electronic digital computer, ENIAC. https://en.wikipedia.org/wiki/Adele_Goldstine + "goldstine", + + // Shafi Goldwasser is a computer scientist known for creating theoretical foundations of modern cryptography. Winner of 2012 ACM Turing Award. https://en.wikipedia.org/wiki/Shafi_Goldwasser + "goldwasser", + + // James Golick, all around gangster. + "golick", + + // Jane Goodall - British primatologist, ethologist, and anthropologist who is considered to be the world's foremost expert on chimpanzees - https://en.wikipedia.org/wiki/Jane_Goodall + "goodall", + + // Stephen Jay Gould was was an American paleontologist, evolutionary biologist, and historian of science. He is most famous for the theory of punctuated equilibrium - https://en.wikipedia.org/wiki/Stephen_Jay_Gould + "gould", + + // Carolyn Widney Greider - American molecular biologist and joint winner of the 2009 Nobel Prize for Physiology or Medicine for the discovery of telomerase. https://en.wikipedia.org/wiki/Carol_W._Greider + "greider", + + // Alexander Grothendieck - German-born French mathematician who became a leading figure in the creation of modern algebraic geometry. https://en.wikipedia.org/wiki/Alexander_Grothendieck + "grothendieck", + + // Lois Haibt - American computer scientist, part of the team at IBM that developed FORTRAN - https://en.wikipedia.org/wiki/Lois_Haibt + "haibt", + + // Margaret Hamilton - Director of the Software Engineering Division of the MIT Instrumentation Laboratory, which developed on-board flight software for the Apollo space program. https://en.wikipedia.org/wiki/Margaret_Hamilton_(scientist) + "hamilton", + + // Caroline Harriet Haslett - English electrical engineer, electricity industry administrator and champion of women's rights. Co-author of British Standard 1363 that specifies AC power plugs and sockets used across the United Kingdom (which is widely considered as one of the safest designs). https://en.wikipedia.org/wiki/Caroline_Haslett + "haslett", + + // Stephen Hawking pioneered the field of cosmology by combining general relativity and quantum mechanics. https://en.wikipedia.org/wiki/Stephen_Hawking + "hawking", + + // Martin Edward Hellman - American cryptologist, best known for his invention of public-key cryptography in co-operation with Whitfield Diffie and Ralph Merkle. https://en.wikipedia.org/wiki/Martin_Hellman + "hellman", + + // Werner Heisenberg was a founding father of quantum mechanics. https://en.wikipedia.org/wiki/Werner_Heisenberg + "heisenberg", + + // Grete Hermann was a German philosopher noted for her philosophical work on the foundations of quantum mechanics. https://en.wikipedia.org/wiki/Grete_Hermann + "hermann", + + // Caroline Lucretia Herschel - German astronomer and discoverer of several comets. https://en.wikipedia.org/wiki/Caroline_Herschel + "herschel", + + // Heinrich Rudolf Hertz - German physicist who first conclusively proved the existence of the electromagnetic waves. https://en.wikipedia.org/wiki/Heinrich_Hertz + "hertz", + + // Jaroslav Heyrovský was the inventor of the polarographic method, father of the electroanalytical method, and recipient of the Nobel Prize in 1959. His main field of work was polarography. https://en.wikipedia.org/wiki/Jaroslav_Heyrovsk%C3%BD + "heyrovsky", + + // Dorothy Hodgkin was a British biochemist, credited with the development of protein crystallography. She was awarded the Nobel Prize in Chemistry in 1964. https://en.wikipedia.org/wiki/Dorothy_Hodgkin + "hodgkin", + + // Douglas R. Hofstadter is an American professor of cognitive science and author of the Pulitzer Prize and American Book Award-winning work Goedel, Escher, Bach: An Eternal Golden Braid in 1979. A mind-bending work which coined Hofstadter's Law: "It always takes longer than you expect, even when you take into account Hofstadter's Law." https://en.wikipedia.org/wiki/Douglas_Hofstadter + "hofstadter", + + // Erna Schneider Hoover revolutionized modern communication by inventing a computerized telephone switching method. https://en.wikipedia.org/wiki/Erna_Schneider_Hoover + "hoover", + + // Grace Hopper developed the first compiler for a computer programming language and is credited with popularizing the term "debugging" for fixing computer glitches. https://en.wikipedia.org/wiki/Grace_Hopper + "hopper", + + // Frances Hugle, she was an American scientist, engineer, and inventor who contributed to the understanding of semiconductors, integrated circuitry, and the unique electrical principles of microscopic materials. https://en.wikipedia.org/wiki/Frances_Hugle + "hugle", + + // Hypatia - Greek Alexandrine Neoplatonist philosopher in Egypt who was one of the earliest mothers of mathematics - https://en.wikipedia.org/wiki/Hypatia + "hypatia", + + // Teruko Ishizaka - Japanese scientist and immunologist who co-discovered the antibody class Immunoglobulin E. https://en.wikipedia.org/wiki/Teruko_Ishizaka + "ishizaka", + + // Mary Jackson, American mathematician and aerospace engineer who earned the highest title within NASA's engineering department - https://en.wikipedia.org/wiki/Mary_Jackson_(engineer) + "jackson", + + // Yeong-Sil Jang was a Korean scientist and astronomer during the Joseon Dynasty; he invented the first metal printing press and water gauge. https://en.wikipedia.org/wiki/Jang_Yeong-sil + "jang", + + // Betty Jennings - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Jean_Bartik + "jennings", + + // Mary Lou Jepsen, was the founder and chief technology officer of One Laptop Per Child (OLPC), and the founder of Pixel Qi. https://en.wikipedia.org/wiki/Mary_Lou_Jepsen + "jepsen", + + // Katherine Coleman Goble Johnson - American physicist and mathematician contributed to the NASA. https://en.wikipedia.org/wiki/Katherine_Johnson + "johnson", + + // Irène Joliot-Curie - French scientist who was awarded the Nobel Prize for Chemistry in 1935. Daughter of Marie and Pierre Curie. https://en.wikipedia.org/wiki/Ir%C3%A8ne_Joliot-Curie + "joliot", + + // Karen Spärck Jones came up with the concept of inverse document frequency, which is used in most search engines today. https://en.wikipedia.org/wiki/Karen_Sp%C3%A4rck_Jones + "jones", + + // A. P. J. Abdul Kalam - is an Indian scientist aka Missile Man of India for his work on the development of ballistic missile and launch vehicle technology - https://en.wikipedia.org/wiki/A._P._J._Abdul_Kalam + "kalam", + + // Sergey Petrovich Kapitsa (Russian: Серге́й Петро́вич Капи́ца; 14 February 1928 – 14 August 2012) was a Russian physicist and demographer. He was best known as host of the popular and long-running Russian scientific TV show, Evident, but Incredible. His father was the Nobel laureate Soviet-era physicist Pyotr Kapitsa, and his brother was the geographer and Antarctic explorer Andrey Kapitsa. - https://en.wikipedia.org/wiki/Sergey_Kapitsa + "kapitsa", + + // Susan Kare, created the icons and many of the interface elements for the original Apple Macintosh in the 1980s, and was an original employee of NeXT, working as the Creative Director. https://en.wikipedia.org/wiki/Susan_Kare + "kare", + + // Mstislav Keldysh - a Soviet scientist in the field of mathematics and mechanics, academician of the USSR Academy of Sciences (1946), President of the USSR Academy of Sciences (1961–1975), three times Hero of Socialist Labor (1956, 1961, 1971), fellow of the Royal Society of Edinburgh (1968). https://en.wikipedia.org/wiki/Mstislav_Keldysh + "keldysh", + + // Mary Kenneth Keller, Sister Mary Kenneth Keller became the first American woman to earn a PhD in Computer Science in 1965. https://en.wikipedia.org/wiki/Mary_Kenneth_Keller + "keller", + + // Johannes Kepler, German astronomer known for his three laws of planetary motion - https://en.wikipedia.org/wiki/Johannes_Kepler + "kepler", + + // Omar Khayyam - Persian mathematician, astronomer and poet. Known for his work on the classification and solution of cubic equations, for his contribution to the understanding of Euclid's fifth postulate and for computing the length of a year very accurately. https://en.wikipedia.org/wiki/Omar_Khayyam + "khayyam", + + // Har Gobind Khorana - Indian-American biochemist who shared the 1968 Nobel Prize for Physiology - https://en.wikipedia.org/wiki/Har_Gobind_Khorana + "khorana", + + // Jack Kilby invented silicone integrated circuits and gave Silicon Valley its name. - https://en.wikipedia.org/wiki/Jack_Kilby + "kilby", + + // Maria Kirch - German astronomer and first woman to discover a comet - https://en.wikipedia.org/wiki/Maria_Margarethe_Kirch + "kirch", + + // Donald Knuth - American computer scientist, author of "The Art of Computer Programming" and creator of the TeX typesetting system. https://en.wikipedia.org/wiki/Donald_Knuth + "knuth", + + // Sophie Kowalevski - Russian mathematician responsible for important original contributions to analysis, differential equations and mechanics - https://en.wikipedia.org/wiki/Sofia_Kovalevskaya + "kowalevski", + + // Marie-Jeanne de Lalande - French astronomer, mathematician and cataloguer of stars - https://en.wikipedia.org/wiki/Marie-Jeanne_de_Lalande + "lalande", + + // Hedy Lamarr - Actress and inventor. The principles of her work are now incorporated into modern Wi-Fi, CDMA and Bluetooth technology. https://en.wikipedia.org/wiki/Hedy_Lamarr + "lamarr", + + // Leslie B. Lamport - American computer scientist. Lamport is best known for his seminal work in distributed systems and was the winner of the 2013 Turing Award. https://en.wikipedia.org/wiki/Leslie_Lamport + "lamport", + + // Mary Leakey - British paleoanthropologist who discovered the first fossilized Proconsul skull - https://en.wikipedia.org/wiki/Mary_Leakey + "leakey", + + // Henrietta Swan Leavitt - she was an American astronomer who discovered the relation between the luminosity and the period of Cepheid variable stars. https://en.wikipedia.org/wiki/Henrietta_Swan_Leavitt + "leavitt", + + // Esther Miriam Zimmer Lederberg - American microbiologist and a pioneer of bacterial genetics. https://en.wikipedia.org/wiki/Esther_Lederberg + "lederberg", + + // Inge Lehmann - Danish seismologist and geophysicist. Known for discovering in 1936 that the Earth has a solid inner core inside a molten outer core. https://en.wikipedia.org/wiki/Inge_Lehmann + "lehmann", + + // Daniel Lewin - Mathematician, Akamai co-founder, soldier, 9/11 victim-- Developed optimization techniques for routing traffic on the internet. Died attempting to stop the 9-11 hijackers. https://en.wikipedia.org/wiki/Daniel_Lewin + "lewin", + + // Ruth Lichterman - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Ruth_Teitelbaum + "lichterman", + + // Barbara Liskov - co-developed the Liskov substitution principle. Liskov was also the winner of the Turing Prize in 2008. - https://en.wikipedia.org/wiki/Barbara_Liskov + "liskov", + + // Ada Lovelace invented the first algorithm. https://en.wikipedia.org/wiki/Ada_Lovelace (thanks James Turnbull) + "lovelace", + + // Auguste and Louis Lumière - the first filmmakers in history - https://en.wikipedia.org/wiki/Auguste_and_Louis_Lumi%C3%A8re + "lumiere", + + // Mahavira - Ancient Indian mathematician during 9th century AD who discovered basic algebraic identities - https://en.wikipedia.org/wiki/Mah%C4%81v%C4%ABra_(mathematician) + "mahavira", + + // Lynn Margulis (b. Lynn Petra Alexander) - an American evolutionary theorist and biologist, science author, educator, and popularizer, and was the primary modern proponent for the significance of symbiosis in evolution. - https://en.wikipedia.org/wiki/Lynn_Margulis + "margulis", + + // Yukihiro Matsumoto - Japanese computer scientist and software programmer best known as the chief designer of the Ruby programming language. https://en.wikipedia.org/wiki/Yukihiro_Matsumoto + "matsumoto", + + // James Clerk Maxwell - Scottish physicist, best known for his formulation of electromagnetic theory. https://en.wikipedia.org/wiki/James_Clerk_Maxwell + "maxwell", + + // Maria Mayer - American theoretical physicist and Nobel laureate in Physics for proposing the nuclear shell model of the atomic nucleus - https://en.wikipedia.org/wiki/Maria_Mayer + "mayer", + + // John McCarthy invented LISP: https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist) + "mccarthy", + + // Barbara McClintock - a distinguished American cytogeneticist, 1983 Nobel Laureate in Physiology or Medicine for discovering transposons. https://en.wikipedia.org/wiki/Barbara_McClintock + "mcclintock", + + // Anne Laura Dorinthea McLaren - British developmental biologist whose work helped lead to human in-vitro fertilisation. https://en.wikipedia.org/wiki/Anne_McLaren + "mclaren", + + // Malcolm McLean invented the modern shipping container: https://en.wikipedia.org/wiki/Malcom_McLean + "mclean", + + // Kay McNulty - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Kathleen_Antonelli + "mcnulty", + + // Gregor Johann Mendel - Czech scientist and founder of genetics. https://en.wikipedia.org/wiki/Gregor_Mendel + "mendel", + + // Dmitri Mendeleev - a chemist and inventor. He formulated the Periodic Law, created a farsighted version of the periodic table of elements, and used it to correct the properties of some already discovered elements and also to predict the properties of eight elements yet to be discovered. https://en.wikipedia.org/wiki/Dmitri_Mendeleev + "mendeleev", + + // Lise Meitner - Austrian/Swedish physicist who was involved in the discovery of nuclear fission. The element meitnerium is named after her - https://en.wikipedia.org/wiki/Lise_Meitner + "meitner", + + // Carla Meninsky, was the game designer and programmer for Atari 2600 games Dodge 'Em and Warlords. https://en.wikipedia.org/wiki/Carla_Meninsky + "meninsky", + + // Ralph C. Merkle - American computer scientist, known for devising Merkle's puzzles - one of the very first schemes for public-key cryptography. Also, inventor of Merkle trees and co-inventor of the Merkle-Damgård construction for building collision-resistant cryptographic hash functions and the Merkle-Hellman knapsack cryptosystem. https://en.wikipedia.org/wiki/Ralph_Merkle + "merkle", + + // Johanna Mestorf - German prehistoric archaeologist and first female museum director in Germany - https://en.wikipedia.org/wiki/Johanna_Mestorf + "mestorf", + + // Marvin Minsky - Pioneer in Artificial Intelligence, co-founder of the MIT's AI Lab, won the Turing Award in 1969. https://en.wikipedia.org/wiki/Marvin_Minsky + "minsky", + + // Maryam Mirzakhani - an Iranian mathematician and the first woman to win the Fields Medal. https://en.wikipedia.org/wiki/Maryam_Mirzakhani + "mirzakhani", + + // Gordon Earle Moore - American engineer, Silicon Valley founding father, author of Moore's law. https://en.wikipedia.org/wiki/Gordon_Moore + "moore", + + // Samuel Morse - contributed to the invention of a single-wire telegraph system based on European telegraphs and was a co-developer of the Morse code - https://en.wikipedia.org/wiki/Samuel_Morse + "morse", + + // Ian Murdock - founder of the Debian project - https://en.wikipedia.org/wiki/Ian_Murdock + "murdock", + + // May-Britt Moser - Nobel prize winner neuroscientist who contributed to the discovery of grid cells in the brain. https://en.wikipedia.org/wiki/May-Britt_Moser + "moser", + + // John Napier of Merchiston - Scottish landowner known as an astronomer, mathematician and physicist. Best known for his discovery of logarithms. https://en.wikipedia.org/wiki/John_Napier + "napier", + + // John Forbes Nash, Jr. - American mathematician who made fundamental contributions to game theory, differential geometry, and the study of partial differential equations. https://en.wikipedia.org/wiki/John_Forbes_Nash_Jr. + "nash", + + // John von Neumann - todays computer architectures are based on the von Neumann architecture. https://en.wikipedia.org/wiki/Von_Neumann_architecture + "neumann", + + // Isaac Newton invented classic mechanics and modern optics. https://en.wikipedia.org/wiki/Isaac_Newton + "newton", + + // Xavier Niel - ;) https://en.wikipedia.org/wiki/Xavier_Niel + "niel", + + // Florence Nightingale, more prominently known as a nurse, was also the first female member of the Royal Statistical Society and a pioneer in statistical graphics https://en.wikipedia.org/wiki/Florence_Nightingale#Statistics_and_sanitary_reform + "nightingale", + + // Alfred Nobel - a Swedish chemist, engineer, innovator, and armaments manufacturer (inventor of dynamite) - https://en.wikipedia.org/wiki/Alfred_Nobel + "nobel", + + // Emmy Noether, German mathematician. Noether's Theorem is named after her. https://en.wikipedia.org/wiki/Emmy_Noether + "noether", + + // Poppy Northcutt. Poppy Northcutt was the first woman to work as part of NASA’s Mission Control. http://www.businessinsider.com/poppy-northcutt-helped-apollo-astronauts-2014-12?op=1 + "northcutt", + + // Robert Noyce invented silicone integrated circuits and gave Silicon Valley its name. - https://en.wikipedia.org/wiki/Robert_Noyce + "noyce", + + // Panini - Ancient Indian linguist and grammarian from 4th century CE who worked on the world's first formal system - https://en.wikipedia.org/wiki/P%C4%81%E1%B9%87ini#Comparison_with_modern_formal_systems + "panini", + + // Ambroise Pare invented modern surgery. https://en.wikipedia.org/wiki/Ambroise_Par%C3%A9 + "pare", + + // Blaise Pascal, French mathematician, physicist, and inventor - https://en.wikipedia.org/wiki/Blaise_Pascal + "pascal", + + // Louis Pasteur discovered vaccination, fermentation and pasteurization. https://en.wikipedia.org/wiki/Louis_Pasteur. + "pasteur", + + // Cecilia Payne-Gaposchkin was an astronomer and astrophysicist who, in 1925, proposed in her Ph.D. thesis an explanation for the composition of stars in terms of the relative abundances of hydrogen and helium. https://en.wikipedia.org/wiki/Cecilia_Payne-Gaposchkin + "payne", + + // Radia Perlman is a software designer and network engineer and most famous for her invention of the spanning-tree protocol (STP). https://en.wikipedia.org/wiki/Radia_Perlman + "perlman", + + // Rob Pike was a key contributor to Unix, Plan 9, the X graphic system, utf-8, and the Go programming language. https://en.wikipedia.org/wiki/Rob_Pike + "pike", + + // Henri Poincaré made fundamental contributions in several fields of mathematics. https://en.wikipedia.org/wiki/Henri_Poincar%C3%A9 + "poincare", + + // Laura Poitras is a director and producer whose work, made possible by open source crypto tools, advances the causes of truth and freedom of information by reporting disclosures by whistleblowers such as Edward Snowden. https://en.wikipedia.org/wiki/Laura_Poitras + "poitras", + + // Tat’yana Avenirovna Proskuriakova (Russian: Татья́на Авени́ровна Проскуряко́ва) (January 23 [O.S. January 10] 1909 – August 30, 1985) was a Russian-American Mayanist scholar and archaeologist who contributed significantly to the deciphering of Maya hieroglyphs, the writing system of the pre-Columbian Maya civilization of Mesoamerica. https://en.wikipedia.org/wiki/Tatiana_Proskouriakoff + "proskuriakova", + + // Claudius Ptolemy - a Greco-Egyptian writer of Alexandria, known as a mathematician, astronomer, geographer, astrologer, and poet of a single epigram in the Greek Anthology - https://en.wikipedia.org/wiki/Ptolemy + "ptolemy", + + // C. V. Raman - Indian physicist who won the Nobel Prize in 1930 for proposing the Raman effect. - https://en.wikipedia.org/wiki/C._V._Raman + "raman", + + // Srinivasa Ramanujan - Indian mathematician and autodidact who made extraordinary contributions to mathematical analysis, number theory, infinite series, and continued fractions. - https://en.wikipedia.org/wiki/Srinivasa_Ramanujan + "ramanujan", + + // Sally Kristen Ride was an American physicist and astronaut. She was the first American woman in space, and the youngest American astronaut. https://en.wikipedia.org/wiki/Sally_Ride + "ride", + + // Rita Levi-Montalcini - Won Nobel Prize in Physiology or Medicine jointly with colleague Stanley Cohen for the discovery of nerve growth factor (https://en.wikipedia.org/wiki/Rita_Levi-Montalcini) + "montalcini", + + // Dennis Ritchie - co-creator of UNIX and the C programming language. - https://en.wikipedia.org/wiki/Dennis_Ritchie + "ritchie", + + // Ida Rhodes - American pioneer in computer programming, designed the first computer used for Social Security. https://en.wikipedia.org/wiki/Ida_Rhodes + "rhodes", + + // Julia Hall Bowman Robinson - American mathematician renowned for her contributions to the fields of computability theory and computational complexity theory. https://en.wikipedia.org/wiki/Julia_Robinson + "robinson", + + // Wilhelm Conrad Röntgen - German physicist who was awarded the first Nobel Prize in Physics in 1901 for the discovery of X-rays (Röntgen rays). https://en.wikipedia.org/wiki/Wilhelm_R%C3%B6ntgen + "roentgen", + + // Rosalind Franklin - British biophysicist and X-ray crystallographer whose research was critical to the understanding of DNA - https://en.wikipedia.org/wiki/Rosalind_Franklin + "rosalind", + + // Vera Rubin - American astronomer who pioneered work on galaxy rotation rates. https://en.wikipedia.org/wiki/Vera_Rubin + "rubin", + + // Meghnad Saha - Indian astrophysicist best known for his development of the Saha equation, used to describe chemical and physical conditions in stars - https://en.wikipedia.org/wiki/Meghnad_Saha + "saha", + + // Jean E. Sammet developed FORMAC, the first widely used computer language for symbolic manipulation of mathematical formulas. https://en.wikipedia.org/wiki/Jean_E._Sammet + "sammet", + + // Mildred Sanderson - American mathematician best known for Sanderson's theorem concerning modular invariants. https://en.wikipedia.org/wiki/Mildred_Sanderson + "sanderson", + + // Satoshi Nakamoto is the name used by the unknown person or group of people who developed bitcoin, authored the bitcoin white paper, and created and deployed bitcoin's original reference implementation. https://en.wikipedia.org/wiki/Satoshi_Nakamoto + "satoshi", + + // Adi Shamir - Israeli cryptographer whose numerous inventions and contributions to cryptography include the Ferge Fiat Shamir identification scheme, the Rivest Shamir Adleman (RSA) public-key cryptosystem, the Shamir's secret sharing scheme, the breaking of the Merkle-Hellman cryptosystem, the TWINKLE and TWIRL factoring devices and the discovery of differential cryptanalysis (with Eli Biham). https://en.wikipedia.org/wiki/Adi_Shamir + "shamir", + + // Claude Shannon - The father of information theory and founder of digital circuit design theory. (https://en.wikipedia.org/wiki/Claude_Shannon) + "shannon", + + // Carol Shaw - Originally an Atari employee, Carol Shaw is said to be the first female video game designer. https://en.wikipedia.org/wiki/Carol_Shaw_(video_game_designer) + "shaw", + + // Dame Stephanie "Steve" Shirley - Founded a software company in 1962 employing women working from home. https://en.wikipedia.org/wiki/Steve_Shirley + "shirley", + + // William Shockley co-invented the transistor - https://en.wikipedia.org/wiki/William_Shockley + "shockley", + + // Lina Solomonovna Stern (or Shtern; Russian: Лина Соломоновна Штерн; 26 August 1878 – 7 March 1968) was a Soviet biochemist, physiologist and humanist whose medical discoveries saved thousands of lives at the fronts of World War II. She is best known for her pioneering work on blood–brain barrier, which she described as hemato-encephalic barrier in 1921. https://en.wikipedia.org/wiki/Lina_Stern + "shtern", + + // Françoise Barré-Sinoussi - French virologist and Nobel Prize Laureate in Physiology or Medicine; her work was fundamental in identifying HIV as the cause of AIDS. https://en.wikipedia.org/wiki/Fran%C3%A7oise_Barr%C3%A9-Sinoussi + "sinoussi", + + // Betty Snyder - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Betty_Holberton + "snyder", + + // Cynthia Solomon - Pioneer in the fields of artificial intelligence, computer science and educational computing. Known for creation of Logo, an educational programming language. https://en.wikipedia.org/wiki/Cynthia_Solomon + "solomon", + + // Frances Spence - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Frances_Spence + "spence", + + // Richard Matthew Stallman - the founder of the Free Software movement, the GNU project, the Free Software Foundation, and the League for Programming Freedom. He also invented the concept of copyleft to protect the ideals of this movement, and enshrined this concept in the widely-used GPL (General Public License) for software. https://en.wikiquote.org/wiki/Richard_Stallman + "stallman", + + // Michael Stonebraker is a database research pioneer and architect of Ingres, Postgres, VoltDB and SciDB. Winner of 2014 ACM Turing Award. https://en.wikipedia.org/wiki/Michael_Stonebraker + "stonebraker", + + // Ivan Edward Sutherland - American computer scientist and Internet pioneer, widely regarded as the father of computer graphics. https://en.wikipedia.org/wiki/Ivan_Sutherland + "sutherland", + + // Janese Swanson (with others) developed the first of the Carmen Sandiego games. She went on to found Girl Tech. https://en.wikipedia.org/wiki/Janese_Swanson + "swanson", + + // Aaron Swartz was influential in creating RSS, Markdown, Creative Commons, Reddit, and much of the internet as we know it today. He was devoted to freedom of information on the web. https://en.wikiquote.org/wiki/Aaron_Swartz + "swartz", + + // Bertha Swirles was a theoretical physicist who made a number of contributions to early quantum theory. https://en.wikipedia.org/wiki/Bertha_Swirles + "swirles", + + // Helen Brooke Taussig - American cardiologist and founder of the field of paediatric cardiology. https://en.wikipedia.org/wiki/Helen_B._Taussig + "taussig", + + // Valentina Tereshkova is a Russian engineer, cosmonaut and politician. She was the first woman to fly to space in 1963. In 2013, at the age of 76, she offered to go on a one-way mission to Mars. https://en.wikipedia.org/wiki/Valentina_Tereshkova + "tereshkova", + + // Nikola Tesla invented the AC electric system and every gadget ever used by a James Bond villain. https://en.wikipedia.org/wiki/Nikola_Tesla + "tesla", + + // Marie Tharp - American geologist and oceanic cartographer who co-created the first scientific map of the Atlantic Ocean floor. Her work led to the acceptance of the theories of plate tectonics and continental drift. https://en.wikipedia.org/wiki/Marie_Tharp + "tharp", + + // Ken Thompson - co-creator of UNIX and the C programming language - https://en.wikipedia.org/wiki/Ken_Thompson + "thompson", + + // Linus Torvalds invented Linux and Git. https://en.wikipedia.org/wiki/Linus_Torvalds + "torvalds", + + // Youyou Tu - Chinese pharmaceutical chemist and educator known for discovering artemisinin and dihydroartemisinin, used to treat malaria, which has saved millions of lives. Joint winner of the 2015 Nobel Prize in Physiology or Medicine. https://en.wikipedia.org/wiki/Tu_Youyou + "tu", + + // Alan Turing was a founding father of computer science. https://en.wikipedia.org/wiki/Alan_Turing. + "turing", + + // Varahamihira - Ancient Indian mathematician who discovered trigonometric formulae during 505-587 CE - https://en.wikipedia.org/wiki/Var%C4%81hamihira#Contributions + "varahamihira", + + // Dorothy Vaughan was a NASA mathematician and computer programmer on the SCOUT launch vehicle program that put America's first satellites into space - https://en.wikipedia.org/wiki/Dorothy_Vaughan + "vaughan", + + // Sir Mokshagundam Visvesvaraya - is a notable Indian engineer. He is a recipient of the Indian Republic's highest honour, the Bharat Ratna, in 1955. On his birthday, 15 September is celebrated as Engineer's Day in India in his memory - https://en.wikipedia.org/wiki/Visvesvaraya + "visvesvaraya", + + // Christiane Nüsslein-Volhard - German biologist, won Nobel Prize in Physiology or Medicine in 1995 for research on the genetic control of embryonic development. https://en.wikipedia.org/wiki/Christiane_N%C3%BCsslein-Volhard + "volhard", + + // Cédric Villani - French mathematician, won Fields Medal, Fermat Prize and Poincaré Price for his work in differential geometry and statistical mechanics. https://en.wikipedia.org/wiki/C%C3%A9dric_Villani + "villani", + + // Marlyn Wescoff - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Marlyn_Meltzer + "wescoff", + + // Sylvia B. Wilbur - British computer scientist who helped develop the ARPANET, was one of the first to exchange email in the UK and a leading researcher in computer-supported collaborative work. https://en.wikipedia.org/wiki/Sylvia_Wilbur + "wilbur", + + // Andrew Wiles - Notable British mathematician who proved the enigmatic Fermat's Last Theorem - https://en.wikipedia.org/wiki/Andrew_Wiles + "wiles", + + // Roberta Williams, did pioneering work in graphical adventure games for personal computers, particularly the King's Quest series. https://en.wikipedia.org/wiki/Roberta_Williams + "williams", + + // Malcolm John Williamson - British mathematician and cryptographer employed by the GCHQ. Developed in 1974 what is now known as Diffie-Hellman key exchange (Diffie and Hellman first published the scheme in 1976). https://en.wikipedia.org/wiki/Malcolm_J._Williamson + "williamson", + + // Sophie Wilson designed the first Acorn Micro-Computer and the instruction set for ARM processors. https://en.wikipedia.org/wiki/Sophie_Wilson + "wilson", + + // Jeannette Wing - co-developed the Liskov substitution principle. - https://en.wikipedia.org/wiki/Jeannette_Wing + "wing", + + // Steve Wozniak invented the Apple I and Apple II. https://en.wikipedia.org/wiki/Steve_Wozniak + "wozniak", + + // The Wright brothers, Orville and Wilbur - credited with inventing and building the world's first successful airplane and making the first controlled, powered and sustained heavier-than-air human flight - https://en.wikipedia.org/wiki/Wright_brothers + "wright", + + // Chien-Shiung Wu - Chinese-American experimental physicist who made significant contributions to nuclear physics. https://en.wikipedia.org/wiki/Chien-Shiung_Wu + "wu", + + // Rosalyn Sussman Yalow - Rosalyn Sussman Yalow was an American medical physicist, and a co-winner of the 1977 Nobel Prize in Physiology or Medicine for development of the radioimmunoassay technique. https://en.wikipedia.org/wiki/Rosalyn_Sussman_Yalow + "yalow", + + // Ada Yonath - an Israeli crystallographer, the first woman from the Middle East to win a Nobel prize in the sciences. https://en.wikipedia.org/wiki/Ada_Yonath + "yonath", + + // Nikolay Yegorovich Zhukovsky (Russian: Никола́й Его́рович Жуко́вский, January 17 1847 – March 17, 1921) was a Russian scientist, mathematician and engineer, and a founding father of modern aero- and hydrodynamics. Whereas contemporary scientists scoffed at the idea of human flight, Zhukovsky was the first to undertake the study of airflow. He is often called the Father of Russian Aviation. https://en.wikipedia.org/wiki/Nikolay_Yegorovich_Zhukovsky + "zhukovsky", + } +) + +// GetRandomName generates a random name from the list of adjectives and surnames in this package +// formatted as "scw-adjective-surname". For example 'scw-focused-turing'. +func GetRandomName(prefixes ...string) string { +begin: + parts := append(prefixes, left[r.Intn(len(left))], right[r.Intn(len(right))]) + name := strings.Join(parts, "-") + if strings.Contains(name, "boring-wozniak") /* Steve Wozniak is not boring */ { + goto begin + } + + return name +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/README.md b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/README.md similarity index 62% rename from src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/README.md rename to src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/README.md index 0accb8db6..0ab7eae24 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/README.md +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/README.md @@ -8,32 +8,38 @@ Recommended config file: # get your credentials on https://console.scaleway.com/account/credentials access_key: SCWXXXXXXXXXXXXXXXXX secret_key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -default_project_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +default_organization_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx default_region: fr-par default_zone: fr-par-1 ``` ## Config file path -This package will try to locate the config file in the following ways: +The function [`GetConfigPath`](https://godoc.org/github.com/scaleway/scaleway-sdk-go/scw#GetConfigPath) will try to locate the config file in the following ways: 1. Custom directory: `$SCW_CONFIG_PATH` 2. [XDG base directory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html): `$XDG_CONFIG_HOME/scw/config.yaml` -3. Home directory: `$HOME/.config/scw/config.yaml` (`%USERPROFILE%/.config/scw/config.yaml` on windows) +3. Unix home directory: `$HOME/.config/scw/config.yaml` +3. Windows home directory: `%USERPROFILE%/.config/scw/config.yaml` ## V1 config (DEPRECATED) -The V1 config `.scwrc` is supported but deprecated. -When found in the home directory, the V1 config is automatically migrated to a V2 config file in `$HOME/.config/scw/config.yaml`. +The V1 config (AKA legacy config) `.scwrc` is deprecated. +To migrate the V1 config to the new format use the function [`MigrateLegacyConfig`](https://godoc.org/github.com/scaleway/scaleway-sdk-go/scw#MigrateLegacyConfig), this will create a [proper config file](#tl-dr) the new [config file path](#config-file-path). ## Reading config order -When getting the value of a config field, the following priority order will be respected: +[ClientOption](https://godoc.org/github.com/scaleway/scaleway-sdk-go/scw#ClientOption) ordering will decide the order in which the config should apply: -1. Environment variable -2. Legacy environment variable -3. Config file V2 -4. Config file V1 +```go +p, _ := scw.MustLoadConfig().GetActiveProfile() + +scw.NewClient( + scw.WithProfile(p), // active profile applies first + scw.WithEnv(), // existing env variables may overwrite active profile + scw.WithDefaultRegion(scw.RegionFrPar) // any prior region set will be discarded to usr the new one +) +``` ## Environment variables @@ -41,8 +47,9 @@ When getting the value of a config field, the following priority order will be r | :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------ | | `$SCW_ACCESS_KEY` | Access key of a token ([get yours](https://console.scaleway.com/account/credentials)) | `$SCALEWAY_ACCESS_KEY` (used by terraform) | | `$SCW_SECRET_KEY` | Secret key of a token ([get yours](https://console.scaleway.com/account/credentials)) | `$SCW_TOKEN` (used by cli), `$SCALEWAY_TOKEN` (used by terraform), `$SCALEWAY_ACCESS_KEY` (used by terraform) | -| `$SCW_DEFAULT_PROJECT_ID` | Your default project ID, if you don't have one use your organization ID ([get yours](https://console.scaleway.com/account/credentials)) | `$SCW_ORGANIZATION` (used by cli),`$SCALEWAY_ORGANIZATION` (used by terraform) | +| `$SCW_DEFAULT_ORGANIZATION_ID` | Your default organization ID, if you don't have one use your organization ID ([get yours](https://console.scaleway.com/account/credentials)) | `$SCW_ORGANIZATION` (used by cli),`$SCALEWAY_ORGANIZATION` (used by terraform) | | `$SCW_DEFAULT_REGION` | Your default [region](https://developers.scaleway.com/en/quickstart/#region-and-zone) | `$SCW_REGION` (used by cli),`$SCALEWAY_REGION` (used by terraform) | | `$SCW_DEFAULT_ZONE` | Your default [availability zone](https://developers.scaleway.com/en/quickstart/#region-and-zone) | `$SCW_ZONE` (used by cli),`$SCALEWAY_ZONE` (used by terraform) | | `$SCW_API_URL` | Url of the API | - | | `$SCW_INSECURE` | Set this to `true` to enable the insecure mode | `$SCW_TLSVERIFY` (inverse flag used by the cli) | +| `$SCW_PROFILE` | Set the config profile to use | - | diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client.go index 0a462c038..0636dc0b5 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client.go @@ -3,9 +3,12 @@ package scw import ( "crypto/tls" "encoding/json" + "io" + "math" "net" "net/http" "net/http/httputil" + "reflect" "strconv" "sync/atomic" "time" @@ -13,7 +16,6 @@ import ( "github.com/scaleway/scaleway-sdk-go/internal/auth" "github.com/scaleway/scaleway-sdk-go/internal/errors" "github.com/scaleway/scaleway-sdk-go/logger" - "github.com/scaleway/scaleway-sdk-go/utils" ) // Client is the Scaleway client which performs API requests. @@ -21,18 +23,19 @@ import ( // This client should be passed in the `NewApi` functions whenever an API instance is created. // Creating a Client is done with the `NewClient` function. type Client struct { - httpClient httpClient - auth auth.Auth - apiURL string - userAgent string - defaultProjectID *string - defaultRegion *utils.Region - defaultZone *utils.Zone - defaultPageSize *int32 + httpClient httpClient + auth auth.Auth + apiURL string + userAgent string + defaultOrganizationID *string + defaultRegion *Region + defaultZone *Zone + defaultPageSize *uint32 } func defaultOptions() []ClientOption { return []ClientOption{ + WithoutAuth(), WithAPIURL("https://api.scaleway.com"), withDefaultUserAgent(userAgent), } @@ -68,51 +71,51 @@ func NewClient(opts ...ClientOption) (*Client, error) { logger.Debugf("client: using sdk version " + version) return &Client{ - auth: s.token, - httpClient: s.httpClient, - apiURL: s.apiURL, - userAgent: s.userAgent, - defaultProjectID: s.defaultProjectID, - defaultRegion: s.defaultRegion, - defaultZone: s.defaultZone, - defaultPageSize: s.defaultPageSize, + auth: s.token, + httpClient: s.httpClient, + apiURL: s.apiURL, + userAgent: s.userAgent, + defaultOrganizationID: s.defaultOrganizationID, + defaultRegion: s.defaultRegion, + defaultZone: s.defaultZone, + defaultPageSize: s.defaultPageSize, }, nil } -// GetDefaultProjectID return the default project ID +// GetDefaultOrganizationID returns the default organization ID // of the client. This value can be set in the client option -// WithDefaultProjectID(). Be aware this value can be empty. -func (c *Client) GetDefaultProjectID() (string, bool) { - if c.defaultProjectID != nil { - return *c.defaultProjectID, true +// WithDefaultOrganizationID(). Be aware this value can be empty. +func (c *Client) GetDefaultOrganizationID() (organizationID string, exists bool) { + if c.defaultOrganizationID != nil { + return *c.defaultOrganizationID, true } return "", false } -// GetDefaultRegion return the default region of the client. +// GetDefaultRegion returns the default region of the client. // This value can be set in the client option // WithDefaultRegion(). Be aware this value can be empty. -func (c *Client) GetDefaultRegion() (utils.Region, bool) { +func (c *Client) GetDefaultRegion() (region Region, exists bool) { if c.defaultRegion != nil { return *c.defaultRegion, true } - return utils.Region(""), false + return Region(""), false } -// GetDefaultZone return the default zone of the client. +// GetDefaultZone returns the default zone of the client. // This value can be set in the client option // WithDefaultZone(). Be aware this value can be empty. -func (c *Client) GetDefaultZone() (utils.Zone, bool) { +func (c *Client) GetDefaultZone() (zone Zone, exists bool) { if c.defaultZone != nil { return *c.defaultZone, true } - return utils.Zone(""), false + return Zone(""), false } -// GetDefaultPageSize return the default page size of the client. +// GetDefaultPageSize returns the default page size of the client. // This value can be set in the client option // WithDefaultPageSize(). Be aware this value can be empty. -func (c *Client) GetDefaultPageSize() (int32, bool) { +func (c *Client) GetDefaultPageSize() (pageSize uint32, exists bool) { if c.defaultPageSize != nil { return *c.defaultPageSize, true } @@ -122,22 +125,20 @@ func (c *Client) GetDefaultPageSize() (int32, bool) { // Do performs HTTP request(s) based on the ScalewayRequest object. // RequestOptions are applied prior to doing the request. func (c *Client) Do(req *ScalewayRequest, res interface{}, opts ...RequestOption) (err error) { - requestSettings := newRequestSettings() - // apply request options - requestSettings.apply(opts) + req.apply(opts) // validate request options - err = requestSettings.validate() + err = req.validate() if err != nil { return err } - if requestSettings.ctx != nil { - req.Ctx = requestSettings.ctx + if req.auth == nil { + req.auth = c.auth } - if requestSettings.allPages { + if req.allPages { return c.doListAll(req, res) } @@ -149,8 +150,7 @@ func (c *Client) Do(req *ScalewayRequest, res interface{}, opts ...RequestOption var requestNumber uint32 // do performs a single HTTP request based on the ScalewayRequest object. -func (c *Client) do(req *ScalewayRequest, res interface{}) (sdkErr SdkError) { - +func (c *Client) do(req *ScalewayRequest, res interface{}) (sdkErr error) { currentRequestNumber := atomic.AddUint32(&requestNumber, 1) if req == nil { @@ -170,19 +170,18 @@ func (c *Client) do(req *ScalewayRequest, res interface{}) (sdkErr SdkError) { return errors.Wrap(err, "could not create request") } - httpRequest.Header = req.getAllHeaders(c.auth, c.userAgent, false) + httpRequest.Header = req.getAllHeaders(req.auth, c.userAgent, false) - if req.Ctx != nil { - httpRequest = httpRequest.WithContext(req.Ctx) + if req.ctx != nil { + httpRequest = httpRequest.WithContext(req.ctx) } if logger.ShouldLog(logger.LogLevelDebug) { - // Keep original headers (before anonymization) originalHeaders := httpRequest.Header // Get anonymized headers - httpRequest.Header = req.getAllHeaders(c.auth, c.userAgent, true) + httpRequest.Header = req.getAllHeaders(req.auth, c.userAgent, true) dump, err := httputil.DumpRequestOut(httpRequest, true) if err != nil { @@ -232,9 +231,24 @@ func (c *Client) do(req *ScalewayRequest, res interface{}) (sdkErr SdkError) { } if res != nil { - err = json.NewDecoder(httpResponse.Body).Decode(&res) - if err != nil { - return errors.Wrap(err, "could not parse response body") + contentType := httpResponse.Header.Get("Content-Type") + + switch contentType { + case "application/json": + err = json.NewDecoder(httpResponse.Body).Decode(&res) + if err != nil { + return errors.Wrap(err, "could not parse %s response body", contentType) + } + default: + buffer, isBuffer := res.(io.Writer) + if !isBuffer { + return errors.Wrap(err, "could not handle %s response body with %T result type", contentType, buffer) + } + + _, err := io.Copy(buffer, httpResponse.Body) + if err != nil { + return errors.Wrap(err, "could not copy %s response body", contentType) + } } // Handle instance API X-Total-Count header @@ -246,12 +260,66 @@ func (c *Client) do(req *ScalewayRequest, res interface{}) (sdkErr SdkError) { } legacyLister.UnsafeSetTotalCount(xTotalCount) } - } return nil } +type lister interface { + UnsafeGetTotalCount() uint32 + UnsafeAppend(interface{}) (uint32, error) +} + +type legacyLister interface { + UnsafeSetTotalCount(totalCount int) +} + +const maxPageCount uint32 = math.MaxUint32 + +// doListAll collects all pages of a List request and aggregate all results on a single response. +func (c *Client) doListAll(req *ScalewayRequest, res interface{}) (err error) { + // check for lister interface + if response, isLister := res.(lister); isLister { + pageCount := maxPageCount + for page := uint32(1); page <= pageCount; page++ { + // set current page + req.Query.Set("page", strconv.FormatUint(uint64(page), 10)) + + // request the next page + nextPage := newVariableFromType(response) + err := c.do(req, nextPage) + if err != nil { + return err + } + + // append results + pageSize, err := response.UnsafeAppend(nextPage) + if err != nil { + return err + } + + if pageSize == 0 { + return nil + } + + // set total count on first request + if pageCount == maxPageCount { + totalCount := nextPage.(lister).UnsafeGetTotalCount() + pageCount = (totalCount + pageSize - 1) / pageSize + } + } + return nil + } + + return errors.New("%T does not support pagination", res) +} + +// newVariableFromType returns a variable set to the zero value of the given type +func newVariableFromType(t interface{}) interface{} { + // reflect.New always create a pointer, that's why we use reflect.Indirect before + return reflect.New(reflect.Indirect(reflect.ValueOf(t)).Type()).Interface() +} + func newHTTPClient() *http.Client { return &http.Client{ Timeout: 30 * time.Second, @@ -280,25 +348,3 @@ func setInsecureMode(c httpClient) { } transportClient.TLSClientConfig.InsecureSkipVerify = true } - -func hasResponseError(res *http.Response) SdkError { - if res.StatusCode >= 200 && res.StatusCode <= 299 { - return nil - } - - newErr := &ResponseError{ - StatusCode: res.StatusCode, - Status: res.Status, - } - - if res.Body == nil { - return newErr - } - - err := json.NewDecoder(res.Body).Decode(newErr) - if err != nil { - return errors.Wrap(err, "could not parse error response body") - } - - return newErr -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client_option.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client_option.go index b59cb51e8..bb3753455 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client_option.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/client_option.go @@ -2,10 +2,11 @@ package scw import ( "net/http" + "strings" "github.com/scaleway/scaleway-sdk-go/internal/auth" - "github.com/scaleway/scaleway-sdk-go/scwconfig" - "github.com/scaleway/scaleway-sdk-go/utils" + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/validation" ) // ClientOption is a function which applies options to a settings object. @@ -68,56 +69,61 @@ func withDefaultUserAgent(ua string) ClientOption { } } -// WithConfig client option configure a client with Scaleway configuration. -func WithConfig(config scwconfig.Config) ClientOption { +// WithProfile client option configures a client from the given profile. +func WithProfile(p *Profile) ClientOption { return func(s *settings) { - // The access key is not used for API authentications. - accessKey, _ := config.GetAccessKey() - secretKey, secretKeyExist := config.GetSecretKey() - if secretKeyExist { - s.token = auth.NewToken(accessKey, secretKey) + accessKey := "" + if p.AccessKey != nil { + accessKey = *p.AccessKey } - apiURL, exist := config.GetAPIURL() - if exist { - s.apiURL = apiURL + if p.SecretKey != nil { + s.token = auth.NewToken(accessKey, *p.SecretKey) } - insecure, exist := config.GetInsecure() - if exist { - s.insecure = insecure + if p.APIURL != nil { + s.apiURL = *p.APIURL } - defaultProjectID, exist := config.GetDefaultProjectID() - if exist { - s.defaultProjectID = &defaultProjectID + if p.Insecure != nil { + s.insecure = *p.Insecure } - defaultRegion, exist := config.GetDefaultRegion() - if exist { + if p.DefaultOrganizationID != nil { + organizationID := *p.DefaultOrganizationID + s.defaultOrganizationID = &organizationID + } + + if p.DefaultRegion != nil { + defaultRegion := Region(*p.DefaultRegion) s.defaultRegion = &defaultRegion } - defaultZone, exist := config.GetDefaultZone() - if exist { + if p.DefaultZone != nil { + defaultZone := Zone(*p.DefaultZone) s.defaultZone = &defaultZone } } } -// WithDefaultProjectID client option sets the client default project ID. +// WithProfile client option configures a client from the environment variables. +func WithEnv() ClientOption { + return WithProfile(LoadEnvProfile()) +} + +// WithDefaultOrganizationID client option sets the client default organization ID. // -// It will be used as the default value of the project_id field in all requests made with this client. -func WithDefaultProjectID(projectID string) ClientOption { +// It will be used as the default value of the organization_id field in all requests made with this client. +func WithDefaultOrganizationID(organizationID string) ClientOption { return func(s *settings) { - s.defaultProjectID = &projectID + s.defaultOrganizationID = &organizationID } } // WithDefaultRegion client option sets the client default region. // // It will be used as the default value of the region field in all requests made with this client. -func WithDefaultRegion(region utils.Region) ClientOption { +func WithDefaultRegion(region Region) ClientOption { return func(s *settings) { s.defaultRegion = ®ion } @@ -126,7 +132,7 @@ func WithDefaultRegion(region utils.Region) ClientOption { // WithDefaultZone client option sets the client default zone. // // It will be used as the default value of the zone field in all requests made with this client. -func WithDefaultZone(zone utils.Zone) ClientOption { +func WithDefaultZone(zone Zone) ClientOption { return func(s *settings) { s.defaultZone = &zone } @@ -135,8 +141,100 @@ func WithDefaultZone(zone utils.Zone) ClientOption { // WithDefaultPageSize client option overrides the default page size of the SDK. // // It will be used as the default value of the page_size field in all requests made with this client. -func WithDefaultPageSize(pageSize int32) ClientOption { +func WithDefaultPageSize(pageSize uint32) ClientOption { return func(s *settings) { s.defaultPageSize = &pageSize } } + +// settings hold the values of all client options +type settings struct { + apiURL string + token auth.Auth + userAgent string + httpClient httpClient + insecure bool + defaultOrganizationID *string + defaultRegion *Region + defaultZone *Zone + defaultPageSize *uint32 +} + +func newSettings() *settings { + return &settings{} +} + +func (s *settings) apply(opts []ClientOption) { + for _, opt := range opts { + opt(s) + } +} + +func (s *settings) validate() error { + // Auth. + if s.token == nil { + // It should not happen, WithoutAuth option is used by default. + panic(errors.New("no credential option provided")) + } + if token, isToken := s.token.(*auth.Token); isToken { + if token.AccessKey == "" { + return NewInvalidClientOptionError("access key cannot be empty") + } + if !validation.IsAccessKey(token.AccessKey) { + return NewInvalidClientOptionError("invalid access key format '%s', expected SCWXXXXXXXXXXXXXXXXX format", token.AccessKey) + } + if token.SecretKey == "" { + return NewInvalidClientOptionError("secret key cannot be empty") + } + if !validation.IsSecretKey(token.SecretKey) { + return NewInvalidClientOptionError("invalid secret key format '%s', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", token.SecretKey) + } + } + + // Default Organization ID. + if s.defaultOrganizationID != nil { + if *s.defaultOrganizationID == "" { + return NewInvalidClientOptionError("default organization ID cannot be empty") + } + if !validation.IsOrganizationID(*s.defaultOrganizationID) { + return NewInvalidClientOptionError("invalid organization ID format '%s', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", *s.defaultOrganizationID) + } + } + + // Default Region. + if s.defaultRegion != nil { + if *s.defaultRegion == "" { + return NewInvalidClientOptionError("default region cannot be empty") + } + if !validation.IsRegion(string(*s.defaultRegion)) { + regions := []string(nil) + for _, r := range AllRegions { + regions = append(regions, string(r)) + } + return NewInvalidClientOptionError("invalid default region format '%s', available regions are: %s", *s.defaultRegion, strings.Join(regions, ", ")) + } + } + + // Default Zone. + if s.defaultZone != nil { + if *s.defaultZone == "" { + return NewInvalidClientOptionError("default zone cannot be empty") + } + if !validation.IsZone(string(*s.defaultZone)) { + zones := []string(nil) + for _, z := range AllZones { + zones = append(zones, string(z)) + } + return NewInvalidClientOptionError("invalid default zone format '%s', available zones are: %s", *s.defaultZone, strings.Join(zones, ", ")) + } + } + + // API URL. + if !validation.IsURL(s.apiURL) { + return NewInvalidClientOptionError("invalid url %s", s.apiURL) + } + + // TODO: check for max s.defaultPageSize + + return nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config.go new file mode 100644 index 000000000..4880daa4b --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config.go @@ -0,0 +1,318 @@ +package scw + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" + "syscall" + "text/template" + + "github.com/scaleway/scaleway-sdk-go/internal/auth" + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/logger" + "gopkg.in/yaml.v2" +) + +const ( + documentationLink = "https://github.com/scaleway/scaleway-sdk-go/blob/master/scw/README.md" + defaultConfigPermission = 0600 +) + +const configFileTemplate = `# Scaleway configuration file +# https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config + +# This configuration file can be used with: +# - Scaleway SDK Go (https://github.com/scaleway/scaleway-sdk-go) +# - Scaleway CLI (>2.0.0) (https://github.com/scaleway/scaleway-cli) +# - Scaleway Terraform Provider (https://www.terraform.io/docs/providers/scaleway/index.html) + +# You need an access key and a secret key to connect to Scaleway API. +# Generate your token at the following address: https://console.scaleway.com/account/credentials + +# An access key is a secret key identifier. +{{ if .AccessKey }}access_key: {{.AccessKey}}{{ else }}# access_key: SCW11111111111111111{{ end }} + +# The secret key is the value that can be used to authenticate against the API (the value used in X-Auth-Token HTTP-header). +# The secret key MUST remain secret and not given to anyone or published online. +{{ if .SecretKey }}secret_key: {{ .SecretKey }}{{ else }}# secret_key: 11111111-1111-1111-1111-111111111111{{ end }} + +# Your organization ID is the identifier of your account inside Scaleway infrastructure. +{{ if .DefaultOrganizationID }}default_organization_id: {{ .DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }} + +# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam). +# It can contain multiple availability zones. +# Example of region: fr-par, nl-ams +{{ if .DefaultRegion }}default_region: {{ .DefaultRegion }}{{ else }}# default_region: fr-par{{ end }} + +# A region can be split into many availability zones (AZ). +# Latency between multiple AZ of the same region are low as they have a common network layer. +# Example of zones: fr-par-1, nl-ams-1 +{{ if .DefaultZone }}default_zone: {{.DefaultZone}}{{ else }}# default_zone: fr-par-1{{ end }} + +# APIURL overrides the API URL of the Scaleway API to the given URL. +# Change that if you want to direct requests to a different endpoint. +{{ if .APIURL }}apiurl: {{ .APIURL }}{{ else }}# api_url: https://api.scaleway.com{{ end }} + +# Insecure enables insecure transport on the client. +# Default to false +{{ if .Insecure }}insecure: {{ .Insecure }}{{ else }}# insecure: false{{ end }} + +# A configuration is a named set of Scaleway properties. +# Starting off with a Scaleway SDK or Scaleway CLI, you’ll work with a single configuration named default. +# You can set properties of the default profile by running either scw init or scw config set. +# This single default configuration is suitable for most use cases. +{{ if .ActiveProfile }}active_profile: {{ .ActiveProfile }}{{ else }}# active_profile: myProfile{{ end }} + +# To improve the Scaleway CLI we rely on diagnostic and usage data. +# Sending such data is optional and can be disable at any time by setting send_telemetry variable to false. +{{ if .SendTelemetry }}send_telemetry: {{ .SendTelemetry }}{{ else }}# send_telemetry: false{{ end }} + +# To work with multiple projects or authorization accounts, you can set up multiple configurations with scw config configurations create and switch among them accordingly. +# You can use a profile by either: +# - Define the profile you want to use as the SCW_PROFILE environment variable +# - Use the GetActiveProfile() function in the SDK +# - Use the --profile flag with the CLI + +# You can define a profile using the following syntax: +{{ if gt (len .Profiles) 0 }} +profiles: +{{- range $k,$v := .Profiles }} + {{ $k }}: + {{ if $v.AccessKey }}access_key: {{ $v.AccessKey }}{{ else }}# access_key: SCW11111111111111111{{ end }} + {{ if $v.SecretKey }}secret_key: {{ $v.SecretKey }}{{ else }}# secret_key: 11111111-1111-1111-1111-111111111111{{ end }} + {{ if $v.DefaultOrganizationID }}default_organization_id: {{ $v.DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }} + {{ if $v.DefaultZone }}default_zone: {{ $v.DefaultZone }}{{ else }}# default_zone: fr-par-1{{ end }} + {{ if $v.DefaultRegion }}default_region: {{ $v.DefaultRegion }}{{ else }}# default_region: fr-par{{ end }} + {{ if $v.APIURL }}api_url: {{ $v.APIURL }}{{ else }}# api_url: https://api.scaleway.com{{ end }} + {{ if $v.Insecure }}insecure: {{ $v.Insecure }}{{ else }}# insecure: false{{ end }} +{{ end }} +{{- else }} +# profiles: +# myProfile: +# access_key: 11111111-1111-1111-1111-111111111111 +# secret_key: 11111111-1111-1111-1111-111111111111 +# organization_id: 11111111-1111-1111-1111-111111111111 +# default_zone: fr-par-1 +# default_region: fr-par +# api_url: https://api.scaleway.com +# insecure: false +{{ end -}} +` + +type Config struct { + Profile `yaml:",inline"` + ActiveProfile *string `yaml:"active_profile,omitempty"` + SendTelemetry bool `yaml:"send_telemetry,omitempty"` + Profiles map[string]*Profile `yaml:"profiles,omitempty"` +} + +type Profile struct { + AccessKey *string `yaml:"access_key,omitempty"` + SecretKey *string `yaml:"secret_key,omitempty"` + APIURL *string `yaml:"api_url,omitempty"` + Insecure *bool `yaml:"insecure,omitempty"` + DefaultOrganizationID *string `yaml:"default_organization_id,omitempty"` + DefaultRegion *string `yaml:"default_region,omitempty"` + DefaultZone *string `yaml:"default_zone,omitempty"` +} + +func (p *Profile) String() string { + p2 := *p + p2.SecretKey = hideSecretKey(p2.SecretKey) + configRaw, _ := yaml.Marshal(p2) + return string(configRaw) +} + +// clone deep copy config object +func (c *Config) clone() *Config { + c2 := &Config{} + configRaw, _ := yaml.Marshal(c) + _ = yaml.Unmarshal(configRaw, c2) + return c2 +} + +func (c *Config) String() string { + c2 := c.clone() + c2.SecretKey = hideSecretKey(c2.SecretKey) + for _, p := range c2.Profiles { + p.SecretKey = hideSecretKey(p.SecretKey) + } + + configRaw, _ := yaml.Marshal(c2) + return string(configRaw) +} + +func hideSecretKey(key *string) *string { + if key == nil { + return nil + } + + newKey := auth.HideSecretKey(*key) + return &newKey +} + +func unmarshalConfV2(content []byte) (*Config, error) { + var config Config + + err := yaml.Unmarshal(content, &config) + if err != nil { + return nil, err + } + return &config, nil +} + +// MustLoadConfig is like LoadConfig but panic instead of returning an error. +func MustLoadConfig() *Config { + c, err := LoadConfigFromPath(GetConfigPath()) + if err != nil { + panic(err) + } + return c +} + +// LoadConfig read the config from the default path. +func LoadConfig() (*Config, error) { + return LoadConfigFromPath(GetConfigPath()) +} + +// LoadConfigFromPath read the config from the given path. +func LoadConfigFromPath(path string) (*Config, error) { + file, err := ioutil.ReadFile(path) + if err != nil { + if pathError, isPathError := err.(*os.PathError); isPathError && pathError.Err == syscall.ENOENT { + return nil, configFileNotFound(pathError.Path) + } + return nil, errors.Wrap(err, "cannot read config file") + } + + _, err = unmarshalConfV1(file) + if err == nil { + // reject V1 config + return nil, errors.New("found legacy config in %s: legacy config is not allowed, please switch to the new config file format: %s", path, documentationLink) + } + + confV2, err := unmarshalConfV2(file) + if err != nil { + return nil, errors.Wrap(err, "content of config file %s is invalid", path) + } + + return confV2, nil +} + +// GetProfile returns the profile corresponding to the given profile name. +func (c *Config) GetProfile(profileName string) (*Profile, error) { + if profileName == "" { + return nil, errors.New("active profile cannot be empty") + } + + p, exist := c.Profiles[profileName] + if !exist { + return nil, errors.New("given profile %s does not exist", profileName) + } + + // Merge selected profile on top of default profile + return MergeProfiles(&c.Profile, p), nil +} + +// GetActiveProfile returns the active profile of the config based on the following order: +// env SCW_PROFILE > config active_profile > config root profile +func (c *Config) GetActiveProfile() (*Profile, error) { + switch { + case os.Getenv(scwActiveProfileEnv) != "": + logger.Debugf("using active profile from env: %s=%s", scwActiveProfileEnv, os.Getenv(scwActiveProfileEnv)) + return c.GetProfile(os.Getenv(scwActiveProfileEnv)) + case c.ActiveProfile != nil: + logger.Debugf("using active profile from config: active_profile=%s", scwActiveProfileEnv, *c.ActiveProfile) + return c.GetProfile(*c.ActiveProfile) + default: + return &c.Profile, nil + } +} + +// SaveTo will save the config to the default config path. This +// action will overwrite the previous file when it exists. +func (c *Config) Save() error { + return c.SaveTo(GetConfigPath()) +} + +// HumanConfig will generate a config file with documented arguments. +func (c *Config) HumanConfig() (string, error) { + tmpl, err := template.New("configuration").Parse(configFileTemplate) + if err != nil { + return "", err + } + + var buf bytes.Buffer + err = tmpl.Execute(&buf, c) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +// SaveTo will save the config to the given path. This action will +// overwrite the previous file when it exists. +func (c *Config) SaveTo(path string) error { + path = filepath.Clean(path) + + // STEP 1: Render the configuration file as a file + file, err := c.HumanConfig() + if err != nil { + return err + } + + // STEP 2: create config path dir in cases it didn't exist before + err = os.MkdirAll(filepath.Dir(path), 0700) + if err != nil { + return err + } + + // STEP 3: write new config file + err = ioutil.WriteFile(path, []byte(file), defaultConfigPermission) + if err != nil { + return err + } + + return nil +} + +// MergeProfiles merges profiles in a new one. The last profile has priority. +func MergeProfiles(original *Profile, others ...*Profile) *Profile { + np := &Profile{ + AccessKey: original.AccessKey, + SecretKey: original.SecretKey, + APIURL: original.APIURL, + Insecure: original.Insecure, + DefaultOrganizationID: original.DefaultOrganizationID, + DefaultRegion: original.DefaultRegion, + DefaultZone: original.DefaultZone, + } + + for _, other := range others { + if other.AccessKey != nil { + np.AccessKey = other.AccessKey + } + if other.SecretKey != nil { + np.SecretKey = other.SecretKey + } + if other.APIURL != nil { + np.APIURL = other.APIURL + } + if other.Insecure != nil { + np.Insecure = other.Insecure + } + if other.DefaultOrganizationID != nil { + np.DefaultOrganizationID = other.DefaultOrganizationID + } + if other.DefaultRegion != nil { + np.DefaultRegion = other.DefaultRegion + } + if other.DefaultZone != nil { + np.DefaultZone = other.DefaultZone + } + } + + return np +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config_legacy.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config_legacy.go new file mode 100644 index 000000000..e914fac26 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/config_legacy.go @@ -0,0 +1,91 @@ +package scw + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/logger" + "gopkg.in/yaml.v2" +) + +// configV1 is a Scaleway CLI configuration file +type configV1 struct { + // Organization is the identifier of the Scaleway organization + Organization string `json:"organization"` + + // Token is the authentication token for the Scaleway organization + Token string `json:"token"` + + // Version is the actual version of scw CLI + Version string `json:"version"` +} + +func unmarshalConfV1(content []byte) (*configV1, error) { + var config configV1 + err := json.Unmarshal(content, &config) + if err != nil { + return nil, err + } + return &config, err +} + +func (v1 *configV1) toV2() *Config { + return &Config{ + Profile: Profile{ + DefaultOrganizationID: &v1.Organization, + SecretKey: &v1.Token, + // ignore v1 version + }, + } +} + +// MigrateLegacyConfig will migrate the legacy config to the V2 when none exist yet. +// Returns a boolean set to true when the migration happened. +// TODO: get accesskey from account? +func MigrateLegacyConfig() (bool, error) { + // STEP 1: try to load config file V2 + v2Path, v2PathOk := getConfigV2FilePath() + if !v2PathOk || fileExist(v2Path) { + return false, nil + } + + // STEP 2: try to load config file V1 + v1Path, v1PathOk := getConfigV1FilePath() + if !v1PathOk { + return false, nil + } + file, err := ioutil.ReadFile(v1Path) + if err != nil { + return false, nil + } + confV1, err := unmarshalConfV1(file) + if err != nil { + return false, errors.Wrap(err, "content of config file %s is invalid json", v1Path) + } + + // STEP 3: create dir + err = os.MkdirAll(filepath.Dir(v2Path), 0700) + if err != nil { + return false, errors.Wrap(err, "mkdir did not work on %s", filepath.Dir(v2Path)) + } + + // STEP 4: marshal yaml config + newConfig := confV1.toV2() + file, err = yaml.Marshal(newConfig) + if err != nil { + return false, err + } + + // STEP 5: save config + err = ioutil.WriteFile(v2Path, file, defaultConfigPermission) + if err != nil { + return false, errors.Wrap(err, "cannot write file %s", v2Path) + } + + // STEP 6: log success + logger.Warningf("migrated existing config to %s", v2Path) + return true, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/convert.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/convert.go new file mode 100644 index 000000000..74864b340 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/convert.go @@ -0,0 +1,171 @@ +package scw + +import ( + "net" + "time" +) + +// StringPtr returns a pointer to the string value passed in. +func StringPtr(v string) *string { + return &v +} + +// StringSlicePtr converts a slice of string values into a slice of +// string pointers +func StringSlicePtr(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringsPtr returns a pointer to the []string value passed in. +func StringsPtr(v []string) *[]string { + return &v +} + +// StringsSlicePtr converts a slice of []string values into a slice of +// []string pointers +func StringsSlicePtr(src [][]string) []*[]string { + dst := make([]*[]string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BytesPtr returns a pointer to the []byte value passed in. +func BytesPtr(v []byte) *[]byte { + return &v +} + +// BytesSlicePtr converts a slice of []byte values into a slice of +// []byte pointers +func BytesSlicePtr(src [][]byte) []*[]byte { + dst := make([]*[]byte, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolPtr returns a pointer to the bool value passed in. +func BoolPtr(v bool) *bool { + return &v +} + +// BoolSlicePtr converts a slice of bool values into a slice of +// bool pointers +func BoolSlicePtr(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int32Ptr returns a pointer to the int32 value passed in. +func Int32Ptr(v int32) *int32 { + return &v +} + +// Int32SlicePtr converts a slice of int32 values into a slice of +// int32 pointers +func Int32SlicePtr(src []int32) []*int32 { + dst := make([]*int32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64Ptr returns a pointer to the int64 value passed in. +func Int64Ptr(v int64) *int64 { + return &v +} + +// Int64SlicePtr converts a slice of int64 values into a slice of +// int64 pointers +func Int64SlicePtr(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint32Ptr returns a pointer to the uint32 value passed in. +func Uint32Ptr(v uint32) *uint32 { + return &v +} + +// Uint32SlicePtr converts a slice of uint32 values into a slice of +// uint32 pointers +func Uint32SlicePtr(src []uint32) []*uint32 { + dst := make([]*uint32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Uint64Ptr returns a pointer to the uint64 value passed in. +func Uint64Ptr(v uint64) *uint64 { + return &v +} + +// Uint64SlicePtr converts a slice of uint64 values into a slice of +// uint64 pointers +func Uint64SlicePtr(src []uint64) []*uint64 { + dst := make([]*uint64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float32Ptr returns a pointer to the float32 value passed in. +func Float32Ptr(v float32) *float32 { + return &v +} + +// Float32SlicePtr converts a slice of float32 values into a slice of +// float32 pointers +func Float32SlicePtr(src []float32) []*float32 { + dst := make([]*float32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64Ptr returns a pointer to the float64 value passed in. +func Float64Ptr(v float64) *float64 { + return &v +} + +// Float64SlicePtr converts a slice of float64 values into a slice of +// float64 pointers +func Float64SlicePtr(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// DurationPtr returns a pointer to the Duration value passed in. +func DurationPtr(v time.Duration) *time.Duration { + return &v +} + +// SizePtr returns a pointer to the Size value passed in. +func SizePtr(v Size) *Size { + return &v +} + +// IPPtr returns a pointer to the net.IP value passed in. +func IPPtr(v net.IP) *net.IP { + return &v +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/custom_types.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/custom_types.go new file mode 100644 index 000000000..75da2b159 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/custom_types.go @@ -0,0 +1,339 @@ +package scw + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net" + "strconv" + "strings" + "time" + + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/logger" +) + +// ServiceInfo contains API metadata +// These metadata are only here for debugging. Do not rely on these values +type ServiceInfo struct { + // Name is the name of the API + Name string `json:"name"` + + // Description is a human readable description for the API + Description string `json:"description"` + + // Version is the version of the API + Version string `json:"version"` + + // DocumentationURL is the a web url where the documentation of the API can be found + DocumentationURL *string `json:"documentation_url"` +} + +// File is the structure used to receive / send a file from / to the API +type File struct { + // Name of the file + Name string `json:"name"` + + // ContentType used in the HTTP header `Content-Type` + ContentType string `json:"content_type"` + + // Content of the file + Content io.Reader `json:"content"` +} + +func (f *File) UnmarshalJSON(b []byte) error { + type file File + var tmpFile struct { + file + Content []byte `json:"content"` + } + + err := json.Unmarshal(b, &tmpFile) + if err != nil { + return err + } + + tmpFile.file.Content = bytes.NewReader(tmpFile.Content) + + *f = File(tmpFile.file) + return nil +} + +// Money represents an amount of money with its currency type. +type Money struct { + // CurrencyCode is the 3-letter currency code defined in ISO 4217. + CurrencyCode string `json:"currency_code"` + + // Units is the whole units of the amount. + // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. + Units int64 `json:"units"` + + // Nanos is the number of nano (10^-9) units of the amount. + // The value must be between -999,999,999 and +999,999,999 inclusive. + // If `units` is positive, `nanos` must be positive or zero. + // If `units` is zero, `nanos` can be positive, zero, or negative. + // If `units` is negative, `nanos` must be negative or zero. + // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. + Nanos int32 `json:"nanos"` +} + +// NewMoneyFromFloat converts a float with currency to a Money. +// +// value: The float value. +// currencyCode: The 3-letter currency code defined in ISO 4217. +// precision: The number of digits after the decimal point used to parse the nanos part of the value. +// +// Examples: +// - (value = 1.3333, precision = 2) => Money{Units = 1, Nanos = 330000000} +// - (value = 1.123456789, precision = 9) => Money{Units = 1, Nanos = 123456789} +func NewMoneyFromFloat(value float64, currencyCode string, precision int) *Money { + if precision > 9 { + panic(fmt.Errorf("max precision is 9")) + } + + strValue := strconv.FormatFloat(value, 'f', precision, 64) + units, nanos, err := splitFloatString(strValue) + if err != nil { + panic(err) + } + + return &Money{ + CurrencyCode: currencyCode, + Units: units, + Nanos: nanos, + } +} + +// String returns the string representation of Money. +func (m Money) String() string { + currencySignsByCodes := map[string]string{ + "EUR": "€", + "USD": "$", + } + + currencySign, currencySignFound := currencySignsByCodes[m.CurrencyCode] + if !currencySignFound { + logger.Debugf("%s currency code is not supported", m.CurrencyCode) + currencySign = m.CurrencyCode + } + + cents := fmt.Sprintf("%09d", m.Nanos) + cents = cents[:2] + strings.TrimRight(cents[2:], "0") + + return fmt.Sprintf("%s %d.%s", currencySign, m.Units, cents) +} + +// ToFloat converts a Money object to a float. +func (m Money) ToFloat() float64 { + return float64(m.Units) + float64(m.Nanos)/1e9 +} + +// Size represents a size in bytes. +type Size uint64 + +const ( + B Size = 1 + KB = 1000 * B + MB = 1000 * KB + GB = 1000 * MB + TB = 1000 * GB + PB = 1000 * TB +) + +// String returns the string representation of a Size. +func (s Size) String() string { + return fmt.Sprintf("%d", s) +} + +// TimeSeries represents a time series that could be used for graph purposes. +type TimeSeries struct { + // Name of the metric. + Name string `json:"name"` + + // Points contains all the points that composed the series. + Points []*TimeSeriesPoint `json:"points"` + + // Metadata contains some string metadata related to a metric. + Metadata map[string]string `json:"metadata"` +} + +// TimeSeriesPoint represents a point of a time series. +type TimeSeriesPoint struct { + Timestamp time.Time + Value float32 +} + +func (tsp TimeSeriesPoint) MarshalJSON() ([]byte, error) { + timestamp := tsp.Timestamp.Format(time.RFC3339) + value, err := json.Marshal(tsp.Value) + if err != nil { + return nil, err + } + + return []byte(`["` + timestamp + `",` + string(value) + "]"), nil +} + +func (tsp *TimeSeriesPoint) UnmarshalJSON(b []byte) error { + point := [2]interface{}{} + + err := json.Unmarshal(b, &point) + if err != nil { + return err + } + + if len(point) != 2 { + return fmt.Errorf("invalid point array") + } + + strTimestamp, isStrTimestamp := point[0].(string) + if !isStrTimestamp { + return fmt.Errorf("%s timestamp is not a string in RFC 3339 format", point[0]) + } + timestamp, err := time.Parse(time.RFC3339, strTimestamp) + if err != nil { + return fmt.Errorf("%s timestamp is not in RFC 3339 format", point[0]) + } + tsp.Timestamp = timestamp + + // By default, JSON unmarshal a float in float64 but the TimeSeriesPoint is a float32 value. + value, isValue := point[1].(float64) + if !isValue { + return fmt.Errorf("%s is not a valid float32 value", point[1]) + } + tsp.Value = float32(value) + + return nil +} + +// IPNet inherits net.IPNet and represents an IP network. +type IPNet struct { + net.IPNet +} + +func (n IPNet) MarshalJSON() ([]byte, error) { + value := n.String() + if value == "" { + value = "" + } + return []byte(`"` + value + `"`), nil +} + +func (n *IPNet) UnmarshalJSON(b []byte) error { + var str string + + err := json.Unmarshal(b, &str) + if err != nil { + return err + } + if str == "" { + *n = IPNet{} + return nil + } + + switch ip := net.ParseIP(str); { + case ip.To4() != nil: + str += "/32" + case ip.To16() != nil: + str += "/128" + } + + _, value, err := net.ParseCIDR(str) + if err != nil { + return err + } + n.IPNet = *value + + return nil +} + +// Duration represents a signed, fixed-length span of time represented as a +// count of seconds and fractions of seconds at nanosecond resolution. It is +// independent of any calendar and concepts like "day" or "month". It is related +// to Timestamp in that the difference between two Timestamp values is a Duration +// and it can be added or subtracted from a Timestamp. +// Range is approximately +-10,000 years. +type Duration struct { + Seconds int64 + Nanos int32 +} + +func (d *Duration) ToTimeDuration() *time.Duration { + if d == nil { + return nil + } + timeDuration := time.Duration(d.Nanos) + time.Duration(d.Seconds/1e9) + return &timeDuration +} + +func (d Duration) MarshalJSON() ([]byte, error) { + nanos := d.Nanos + if nanos < 0 { + nanos = -nanos + } + + return []byte(`"` + fmt.Sprintf("%d.%09d", d.Seconds, nanos) + `s"`), nil +} + +func (d *Duration) UnmarshalJSON(b []byte) error { + if string(b) == "null" { + return nil + } + var str string + + err := json.Unmarshal(b, &str) + if err != nil { + return err + } + if str == "" { + *d = Duration{} + return nil + } + + seconds, nanos, err := splitFloatString(strings.TrimRight(str, "s")) + if err != nil { + return err + } + + *d = Duration{ + Seconds: seconds, + Nanos: nanos, + } + + return nil +} + +// splitFloatString splits a float represented in a string, and returns its units (left-coma part) and nanos (right-coma part). +// E.g.: +// "3" ==> units = 3 | nanos = 0 +// "3.14" ==> units = 3 | nanos = 14*1e7 +// "-3.14" ==> units = -3 | nanos = -14*1e7 +func splitFloatString(input string) (units int64, nanos int32, err error) { + parts := strings.SplitN(input, ".", 2) + + // parse units as int64 + units, err = strconv.ParseInt(parts[0], 10, 64) + if err != nil { + return 0, 0, errors.Wrap(err, "invalid units") + } + + // handle nanos + if len(parts) == 2 { + // add leading zeros + strNanos := parts[1] + "000000000"[len(parts[1]):] + + // parse nanos as int32 + n, err := strconv.ParseUint(strNanos, 10, 32) + if err != nil { + return 0, 0, errors.Wrap(err, "invalid nanos") + } + + nanos = int32(n) + } + + if units < 0 { + nanos = -nanos + } + + return units, nanos, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/env.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/env.go new file mode 100644 index 000000000..d73bdd52d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/env.go @@ -0,0 +1,137 @@ +package scw + +import ( + "os" + "strconv" + + "github.com/scaleway/scaleway-sdk-go/logger" +) + +// Environment variables +const ( + // Up-to-date + scwCacheDirEnv = "SCW_CACHE_DIR" + scwConfigPathEnv = "SCW_CONFIG_PATH" + scwAccessKeyEnv = "SCW_ACCESS_KEY" + scwSecretKeyEnv = "SCW_SECRET_KEY" // #nosec G101 + scwActiveProfileEnv = "SCW_PROFILE" + scwAPIURLEnv = "SCW_API_URL" + scwInsecureEnv = "SCW_INSECURE" + scwDefaultOrganizationIDEnv = "SCW_DEFAULT_ORGANIZATION_ID" + scwDefaultRegionEnv = "SCW_DEFAULT_REGION" + scwDefaultZoneEnv = "SCW_DEFAULT_ZONE" + + // All deprecated (cli&terraform) + terraformAccessKeyEnv = "SCALEWAY_ACCESS_KEY" // used both as access key and secret key + terraformSecretKeyEnv = "SCALEWAY_TOKEN" + terraformOrganizationEnv = "SCALEWAY_ORGANIZATION" + terraformRegionEnv = "SCALEWAY_REGION" + cliTLSVerifyEnv = "SCW_TLSVERIFY" + cliOrganizationEnv = "SCW_ORGANIZATION" + cliRegionEnv = "SCW_REGION" + cliSecretKeyEnv = "SCW_TOKEN" + + // TBD + //cliVerboseEnv = "SCW_VERBOSE_API" + //cliDebugEnv = "DEBUG" + //cliNoCheckVersionEnv = "SCW_NOCHECKVERSION" + //cliTestWithRealAPIEnv = "TEST_WITH_REAL_API" + //cliSecureExecEnv = "SCW_SECURE_EXEC" + //cliGatewayEnv = "SCW_GATEWAY" + //cliSensitiveEnv = "SCW_SENSITIVE" + //cliAccountAPIEnv = "SCW_ACCOUNT_API" + //cliMetadataAPIEnv = "SCW_METADATA_API" + //cliMarketPlaceAPIEnv = "SCW_MARKETPLACE_API" + //cliComputePar1APIEnv = "SCW_COMPUTE_PAR1_API" + //cliComputeAms1APIEnv = "SCW_COMPUTE_AMS1_API" + //cliCommercialTypeEnv = "SCW_COMMERCIAL_TYPE" + //cliTargetArchEnv = "SCW_TARGET_ARCH" +) + +const ( + v1RegionFrPar = "par1" + v1RegionNlAms = "ams1" +) + +func LoadEnvProfile() *Profile { + p := &Profile{} + + accessKey, _, envExist := getEnv(scwAccessKeyEnv, terraformAccessKeyEnv) + if envExist { + p.AccessKey = &accessKey + } + + secretKey, _, envExist := getEnv(scwSecretKeyEnv, cliSecretKeyEnv, terraformSecretKeyEnv, terraformAccessKeyEnv) + if envExist { + p.SecretKey = &secretKey + } + + apiURL, _, envExist := getEnv(scwAPIURLEnv) + if envExist { + p.APIURL = &apiURL + } + + insecureValue, envKey, envExist := getEnv(scwInsecureEnv, cliTLSVerifyEnv) + if envExist { + insecure, err := strconv.ParseBool(insecureValue) + if err != nil { + logger.Warningf("env variable %s cannot be parsed: %s is invalid boolean", envKey, insecureValue) + } + + if envKey == cliTLSVerifyEnv { + insecure = !insecure // TLSVerify is the inverse of Insecure + } + + p.Insecure = &insecure + } + + organizationID, _, envExist := getEnv(scwDefaultOrganizationIDEnv, cliOrganizationEnv, terraformOrganizationEnv) + if envExist { + p.DefaultOrganizationID = &organizationID + } + + region, _, envExist := getEnv(scwDefaultRegionEnv, cliRegionEnv, terraformRegionEnv) + if envExist { + region = v1RegionToV2(region) + p.DefaultRegion = ®ion + } + + zone, _, envExist := getEnv(scwDefaultZoneEnv) + if envExist { + p.DefaultZone = &zone + } + + return p +} + +func getEnv(upToDateKey string, deprecatedKeys ...string) (string, string, bool) { + value, exist := os.LookupEnv(upToDateKey) + if exist { + logger.Infof("reading value from %s", upToDateKey) + return value, upToDateKey, true + } + + for _, key := range deprecatedKeys { + value, exist := os.LookupEnv(key) + if exist { + logger.Infof("reading value from %s", key) + logger.Warningf("%s is deprecated, please use %s instead", key, upToDateKey) + return value, key, true + } + } + + return "", "", false +} + +func v1RegionToV2(region string) string { + switch region { + case v1RegionFrPar: + logger.Warningf("par1 is a deprecated name for region, use fr-par instead") + return "fr-par" + case v1RegionNlAms: + logger.Warningf("ams1 is a deprecated name for region, use nl-ams instead") + return "nl-ams" + default: + return region + } +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/errors.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/errors.go index 24fa93556..032b19ce7 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/errors.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/errors.go @@ -1,7 +1,15 @@ package scw import ( + "encoding/json" "fmt" + "io/ioutil" + "net/http" + "sort" + "strings" + "time" + + "github.com/scaleway/scaleway-sdk-go/internal/errors" ) // SdkError is a base interface for all Scaleway SDK errors. @@ -15,10 +23,13 @@ type ResponseError struct { // Message is a human-friendly error message Message string `json:"message"` - // Type is a string code that defines the kind of error + // Type is a string code that defines the kind of error. This field is only used by instance API Type string `json:"type,omitempty"` - // Fields contains detail about validation error + // Resource is a string code that defines the resource concerned by the error. This field is only used by instance API + Resource string `json:"resource,omitempty"` + + // Fields contains detail about validation error. This field is only used by instance API Fields map[string][]string `json:"fields,omitempty"` // StatusCode is the HTTP status code received @@ -26,11 +37,34 @@ type ResponseError struct { // Status is the HTTP status received Status string `json:"-"` + + RawBody json.RawMessage `json:"-"` } +func (e *ResponseError) UnmarshalJSON(b []byte) error { + type tmpResponseError ResponseError + tmp := tmpResponseError(*e) + + err := json.Unmarshal(b, &tmp) + if err != nil { + return err + } + + tmp.Message = strings.ToLower(tmp.Message) + + *e = ResponseError(tmp) + return nil +} + +// IsScwSdkError implement SdkError interface +func (e *ResponseError) IsScwSdkError() {} func (e *ResponseError) Error() string { s := fmt.Sprintf("scaleway-sdk-go: http error %s", e.Status) + if e.Resource != "" { + s = fmt.Sprintf("%s: resource %s", s, e.Resource) + } + if e.Message != "" { s = fmt.Sprintf("%s: %s", s, e.Message) } @@ -41,6 +75,347 @@ func (e *ResponseError) Error() string { return s } +func (e *ResponseError) GetRawBody() json.RawMessage { + return e.RawBody +} -// IsScwSdkError implement SdkError interface -func (e *ResponseError) IsScwSdkError() {} +// hasResponseError returns an SdkError when the HTTP status is not OK. +func hasResponseError(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode <= 299 { + return nil + } + + newErr := &ResponseError{ + StatusCode: res.StatusCode, + Status: res.Status, + } + + if res.Body == nil { + return newErr + } + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return errors.Wrap(err, "cannot read error response body") + } + newErr.RawBody = body + + // The error content is not encoded in JSON, only returns HTTP data. + if res.Header.Get("Content-Type") != "application/json" { + newErr.Message = res.Status + return newErr + } + + err = json.Unmarshal(body, newErr) + if err != nil { + return errors.Wrap(err, "could not parse error response body") + } + + err = unmarshalStandardError(newErr.Type, body) + if err != nil { + return err + } + + err = unmarshalNonStandardError(newErr.Type, body) + if err != nil { + return err + } + + return newErr +} + +func unmarshalStandardError(errorType string, body []byte) error { + var stdErr SdkError + + switch errorType { + case "invalid_arguments": + stdErr = &InvalidArgumentsError{RawBody: body} + case "quotas_exceeded": + stdErr = &QuotasExceededError{RawBody: body} + case "transient_state": + stdErr = &TransientStateError{RawBody: body} + case "not_found": + stdErr = &ResourceNotFoundError{RawBody: body} + case "permissions_denied": + stdErr = &PermissionsDeniedError{RawBody: body} + case "out_of_stock": + stdErr = &OutOfStockError{RawBody: body} + case "resource_expired": + stdErr = &ResourceExpiredError{RawBody: body} + default: + return nil + } + + err := json.Unmarshal(body, stdErr) + if err != nil { + return errors.Wrap(err, "could not parse error %s response body", errorType) + } + + return stdErr +} + +func unmarshalNonStandardError(errorType string, body []byte) error { + switch errorType { + // Only in instance API. + + case "invalid_request_error": + invalidRequestError := &InvalidRequestError{RawBody: body} + err := json.Unmarshal(body, invalidRequestError) + if err != nil { + return errors.Wrap(err, "could not parse error %s response body", errorType) + } + + invalidArgumentsError := invalidRequestError.ToInvalidArgumentsError() + if invalidArgumentsError != nil { + return invalidArgumentsError + } + + quotasExceededError := invalidRequestError.ToQuotasExceededError() + if quotasExceededError != nil { + return quotasExceededError + } + + // At this point, the invalid_request_error is not an InvalidArgumentsError and + // the default marshalling will be used. + return nil + + default: + return nil + } +} + +type InvalidArgumentsErrorDetail struct { + ArgumentName string `json:"argument_name"` + Reason string `json:"reason"` + HelpMessage string `json:"help_message"` +} + +type InvalidArgumentsError struct { + Details []InvalidArgumentsErrorDetail `json:"details"` + + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *InvalidArgumentsError) IsScwSdkError() {} +func (e *InvalidArgumentsError) Error() string { + invalidArgs := make([]string, len(e.Details)) + for i, d := range e.Details { + invalidArgs[i] = d.ArgumentName + switch d.Reason { + case "unknown": + invalidArgs[i] += " is invalid for unexpected reason" + case "required": + invalidArgs[i] += " is required" + case "format": + invalidArgs[i] += " is wrongly formatted" + case "constraint": + invalidArgs[i] += " does not respect constraint" + } + if d.HelpMessage != "" { + invalidArgs[i] += ", " + d.HelpMessage + } + } + + return "scaleway-sdk-go: invalid argument(s): " + strings.Join(invalidArgs, "; ") +} +func (e *InvalidArgumentsError) GetRawBody() json.RawMessage { + return e.RawBody +} + +// InvalidRequestError is only returned by the instance API. +// Warning: this is not a standard error. +type InvalidRequestError struct { + Message string `json:"message"` + + Fields map[string][]string `json:"fields"` + + Resource string `json:"resource"` + + RawBody json.RawMessage `json:"-"` +} + +// ToSdkError returns a standard error InvalidArgumentsError or nil Fields is nil. +func (e *InvalidRequestError) ToInvalidArgumentsError() SdkError { + // If error has no fields, it is not an InvalidArgumentsError. + if e.Fields == nil || len(e.Fields) == 0 { + return nil + } + + invalidArguments := &InvalidArgumentsError{ + RawBody: e.RawBody, + } + fieldNames := []string(nil) + for fieldName := range e.Fields { + fieldNames = append(fieldNames, fieldName) + } + sort.Strings(fieldNames) + for _, fieldName := range fieldNames { + for _, message := range e.Fields[fieldName] { + invalidArguments.Details = append(invalidArguments.Details, InvalidArgumentsErrorDetail{ + ArgumentName: fieldName, + Reason: "constraint", + HelpMessage: message, + }) + } + } + return invalidArguments +} + +func (e *InvalidRequestError) ToQuotasExceededError() SdkError { + if !strings.Contains(strings.ToLower(e.Message), "quota exceeded for this resource") { + return nil + } + + return &QuotasExceededError{ + Details: []QuotasExceededErrorDetail{ + { + Resource: e.Resource, + Quota: 0, + Current: 0, + }, + }, + RawBody: e.RawBody, + } +} + +type QuotasExceededErrorDetail struct { + Resource string `json:"resource"` + Quota uint32 `json:"quota"` + Current uint32 `json:"current"` +} + +type QuotasExceededError struct { + Details []QuotasExceededErrorDetail `json:"details"` + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *QuotasExceededError) IsScwSdkError() {} +func (e *QuotasExceededError) Error() string { + invalidArgs := make([]string, len(e.Details)) + for i, d := range e.Details { + invalidArgs[i] = fmt.Sprintf("%s has reached its quota (%d/%d)", d.Resource, d.Current, d.Current) + } + + return "scaleway-sdk-go: quota exceeded(s): " + strings.Join(invalidArgs, "; ") +} +func (e *QuotasExceededError) GetRawBody() json.RawMessage { + return e.RawBody +} + +type PermissionsDeniedError struct { + Details []struct { + Resource string `json:"resource"` + Action string `json:"action"` + } `json:"details"` + + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *PermissionsDeniedError) IsScwSdkError() {} +func (e *PermissionsDeniedError) Error() string { + invalidArgs := make([]string, len(e.Details)) + for i, d := range e.Details { + invalidArgs[i] = fmt.Sprintf("%s %s", d.Action, d.Resource) + } + + return "scaleway-sdk-go: insufficient permissions: " + strings.Join(invalidArgs, "; ") +} +func (e *PermissionsDeniedError) GetRawBody() json.RawMessage { + return e.RawBody +} + +type TransientStateError struct { + Resource string `json:"resource"` + ResourceID string `json:"resource_id"` + CurrentState string `json:"current_state"` + + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *TransientStateError) IsScwSdkError() {} +func (e *TransientStateError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: resource %s with ID %s is in a transient state: %s", e.Resource, e.ResourceID, e.CurrentState) +} +func (e *TransientStateError) GetRawBody() json.RawMessage { + return e.RawBody +} + +type ResourceNotFoundError struct { + Resource string `json:"resource"` + ResourceID string `json:"resource_id"` + + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *ResourceNotFoundError) IsScwSdkError() {} +func (e *ResourceNotFoundError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: resource %s with ID %s is not found", e.Resource, e.ResourceID) +} +func (e *ResourceNotFoundError) GetRawBody() json.RawMessage { + return e.RawBody +} + +type OutOfStockError struct { + Resource string `json:"resource"` + + RawBody json.RawMessage `json:"-"` +} + +// IsScwSdkError implements the SdkError interface +func (e *OutOfStockError) IsScwSdkError() {} +func (e *OutOfStockError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: resource %s is out of stock", e.Resource) +} +func (e *OutOfStockError) GetRawBody() json.RawMessage { + return e.RawBody +} + +// InvalidClientOptionError indicates that at least one of client data has been badly provided for the client creation. +type InvalidClientOptionError struct { + errorType string +} + +func NewInvalidClientOptionError(format string, a ...interface{}) *InvalidClientOptionError { + return &InvalidClientOptionError{errorType: fmt.Sprintf(format, a...)} +} + +// IsScwSdkError implements the SdkError interface +func (e InvalidClientOptionError) IsScwSdkError() {} +func (e InvalidClientOptionError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: %s", e.errorType) +} + +// ConfigFileNotFound indicates that the config file could not be found +type ConfigFileNotFoundError struct { + path string +} + +func configFileNotFound(path string) *ConfigFileNotFoundError { + return &ConfigFileNotFoundError{path: path} +} + +// ConfigFileNotFoundError implements the SdkError interface +func (e ConfigFileNotFoundError) IsScwSdkError() {} +func (e ConfigFileNotFoundError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: cannot read config file %s: no such file or directory", e.path) +} + +// ResourceExpiredError implements the SdkError interface +type ResourceExpiredError struct { + Resource string `json:"resource"` + ResourceID string `json:"resource_id"` + ExpiredSince time.Time `json:"expired_since"` + + RawBody json.RawMessage `json:"-"` +} + +func (r ResourceExpiredError) Error() string { + return fmt.Sprintf("scaleway-sdk-go: resource %s with ID %s expired since %s", r.Resource, r.ResourceID, r.ExpiredSince.String()) +} + +func (r ResourceExpiredError) IsScwSdkError() {} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/lister.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/lister.go deleted file mode 100644 index 8867a4c2e..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/lister.go +++ /dev/null @@ -1,64 +0,0 @@ -package scw - -import ( - "math" - "reflect" - "strconv" - - "github.com/scaleway/scaleway-sdk-go/internal/errors" -) - -type lister interface { - UnsafeGetTotalCount() int - UnsafeAppend(interface{}) (int, SdkError) -} - -type legacyLister interface { - UnsafeSetTotalCount(totalCount int) -} - -// doListAll collects all pages of a List request and aggregate all results on a single response. -func (c *Client) doListAll(req *ScalewayRequest, res interface{}) (err SdkError) { - - // check for lister interface - if response, isLister := res.(lister); isLister { - - pageCount := math.MaxUint32 - for page := 1; page <= pageCount; page++ { - // set current page - req.Query.Set("page", strconv.Itoa(page)) - - // request the next page - nextPage := newPage(response) - err := c.do(req, nextPage) - if err != nil { - return err - } - - // append results - pageSize, err := response.UnsafeAppend(nextPage) - if err != nil { - return err - } - - if pageSize == 0 { - return nil - } - - // set total count on first request - if pageCount == math.MaxUint32 { - totalCount := nextPage.(lister).UnsafeGetTotalCount() - pageCount = (totalCount + pageSize - 1) / pageSize - } - } - return nil - } - - return errors.New("%T does not support pagination", res) -} - -// newPage returns a variable set to the zero value of the given type -func newPage(v interface{}) interface{} { - // reflect.New always create a pointer, that's why we use reflect.Indirect before - return reflect.New(reflect.Indirect(reflect.ValueOf(v)).Type()).Interface() -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/locality.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/locality.go similarity index 68% rename from src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/locality.go rename to src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/locality.go index 80f27559f..69278d28d 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/locality.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/locality.go @@ -1,11 +1,18 @@ -package utils +package scw import ( "encoding/json" + "fmt" + "strings" + "github.com/scaleway/scaleway-sdk-go/internal/errors" "github.com/scaleway/scaleway-sdk-go/logger" + "github.com/scaleway/scaleway-sdk-go/validation" ) +// localityPartsSeparator is the separator used in Zone and Region +const localityPartsSeparator = "-" + // Zone is an availability zone type Zone string @@ -37,6 +44,22 @@ func (zone *Zone) Exists() bool { return false } +// String returns a Zone as a string +func (zone *Zone) String() string { + return string(*zone) +} + +// Region returns the parent Region for the Zone. +// Manipulates the string directly to allow unlisted zones formatted as xx-yyy-z. +func (zone *Zone) Region() (Region, error) { + zoneStr := zone.String() + if !validation.IsZone(zoneStr) { + return "", fmt.Errorf("invalid zone '%v'", zoneStr) + } + zoneParts := strings.Split(zoneStr, localityPartsSeparator) + return Region(strings.Join(zoneParts[:2], localityPartsSeparator)), nil +} + // Region is a geographical location type Region string @@ -77,7 +100,7 @@ func (region Region) GetZones() []Zone { } } -// ParseZone parse a string value into a Zone object +// ParseZone parses a string value into a Zone and returns an error if it has a bad format. func ParseZone(zone string) (Zone, error) { switch zone { case "par1": @@ -89,6 +112,14 @@ func ParseZone(zone string) (Zone, error) { // logger.Warningf("ams1 is a deprecated name for zone, use nl-ams-1 instead") return ZoneNlAms1, nil default: + if !validation.IsZone(zone) { + zones := []string(nil) + for _, z := range AllZones { + zones = append(zones, string(z)) + } + return "", errors.New("bad zone format, available zones are: %s", strings.Join(zones, ", ")) + } + newZone := Zone(zone) if !newZone.Exists() { logger.Warningf("%s is an unknown zone", newZone) @@ -100,7 +131,6 @@ func ParseZone(zone string) (Zone, error) { // UnmarshalJSON implements the Unmarshaler interface for a Zone. // this to call ParseZone on the string input and return the correct Zone object. func (zone *Zone) UnmarshalJSON(input []byte) error { - // parse input value as string var stringValue string err := json.Unmarshal(input, &stringValue) @@ -116,7 +146,7 @@ func (zone *Zone) UnmarshalJSON(input []byte) error { return nil } -// ParseRegion parse a string value into a Zone object +// ParseRegion parses a string value into a Region and returns an error if it has a bad format. func ParseRegion(region string) (Region, error) { switch region { case "par1": @@ -128,6 +158,14 @@ func ParseRegion(region string) (Region, error) { // logger.Warningf("ams1 is a deprecated name for region, use nl-ams instead") return RegionNlAms, nil default: + if !validation.IsRegion(region) { + regions := []string(nil) + for _, r := range AllRegions { + regions = append(regions, string(r)) + } + return "", errors.New("bad region format, available regions are: %s", strings.Join(regions, ", ")) + } + newRegion := Region(region) if !newRegion.Exists() { logger.Warningf("%s is an unknown region", newRegion) @@ -153,3 +191,8 @@ func (region *Region) UnmarshalJSON(input []byte) error { } return nil } + +// String returns a Region as a string +func (region *Region) String() string { + return string(*region) +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/path.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/path.go new file mode 100644 index 000000000..f65c5a63f --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/path.go @@ -0,0 +1,110 @@ +package scw + +import ( + "errors" + "os" + "path/filepath" +) + +const ( + // XDG wiki: https://wiki.archlinux.org/index.php/XDG_Base_Directory + xdgConfigDirEnv = "XDG_CONFIG_HOME" + xdgCacheDirEnv = "XDG_CACHE_HOME" + + unixHomeDirEnv = "HOME" + windowsHomeDirEnv = "USERPROFILE" + + defaultConfigFileName = "config.yaml" +) + +var ( + // ErrNoHomeDir errors when no user directory is found + ErrNoHomeDir = errors.New("user home directory not found") +) + +// GetCacheDirectory returns the default cache directory. +// Cache directory is based on the following priority order: +// - $SCW_CACHE_DIR +// - $XDG_CACHE_HOME/scw +// - $HOME/.cache/scw +// - $USERPROFILE/.cache/scw +func GetCacheDirectory() string { + cacheDir := "" + switch { + case os.Getenv(scwCacheDirEnv) != "": + cacheDir = os.Getenv(scwCacheDirEnv) + case os.Getenv(xdgCacheDirEnv) != "": + cacheDir = filepath.Join(os.Getenv(xdgCacheDirEnv), "scw") + case os.Getenv(unixHomeDirEnv) != "": + cacheDir = filepath.Join(os.Getenv(unixHomeDirEnv), ".cache", "scw") + case os.Getenv(windowsHomeDirEnv) != "": + cacheDir = filepath.Join(os.Getenv(windowsHomeDirEnv), ".cache", "scw") + default: + // TODO: fallback on local folder? + } + + // Clean the cache directory path when exiting the function + return filepath.Clean(cacheDir) +} + +// GetConfigPath returns the default path. +// Default path is based on the following priority order: +// - $SCW_CONFIG_PATH +// - $XDG_CONFIG_HOME/scw/config.yaml +// - $HOME/.config/scw/config.yaml +// - $USERPROFILE/.config/scw/config.yaml +func GetConfigPath() string { + configPath := os.Getenv(scwConfigPathEnv) + if configPath == "" { + configPath, _ = getConfigV2FilePath() + } + return filepath.Clean(configPath) +} + +// getConfigV2FilePath returns the path to the v2 config file +func getConfigV2FilePath() (string, bool) { + configDir, err := getScwConfigDir() + if err != nil { + return "", false + } + return filepath.Clean(filepath.Join(configDir, defaultConfigFileName)), true +} + +// getConfigV1FilePath returns the path to the v1 config file +func getConfigV1FilePath() (string, bool) { + path, err := getHomeDir() + if err != nil { + return "", false + } + return filepath.Clean(filepath.Join(path, ".scwrc")), true +} + +// getScwConfigDir returns the path to scw config folder +func getScwConfigDir() (string, error) { + if xdgPath := os.Getenv(xdgConfigDirEnv); xdgPath != "" { + return filepath.Join(xdgPath, "scw"), nil + } + + homeDir, err := getHomeDir() + if err != nil { + return "", err + } + return filepath.Join(homeDir, ".config", "scw"), nil +} + +// getHomeDir returns the path to your home directory +func getHomeDir() (string, error) { + switch { + case os.Getenv(unixHomeDirEnv) != "": + return os.Getenv(unixHomeDirEnv), nil + case os.Getenv(windowsHomeDirEnv) != "": + return os.Getenv(windowsHomeDirEnv), nil + default: + return "", ErrNoHomeDir + } +} + +func fileExist(name string) bool { + _, err := os.Stat(name) + return err == nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request.go index 12ca85a1e..19f0dd4d5 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request.go @@ -10,7 +10,6 @@ import ( "github.com/scaleway/scaleway-sdk-go/internal/auth" "github.com/scaleway/scaleway-sdk-go/internal/errors" - "github.com/scaleway/scaleway-sdk-go/utils" ) // ScalewayRequest contains all the contents related to performing a request on the Scaleway API. @@ -20,7 +19,11 @@ type ScalewayRequest struct { Headers http.Header Query url.Values Body io.Reader - Ctx context.Context + + // request options + ctx context.Context + auth auth.Auth + allPages bool } // getAllHeaders constructs a http.Header object and aggregates all headers into the object. @@ -34,11 +37,12 @@ func (req *ScalewayRequest) getAllHeaders(token auth.Auth, userAgent string, ano allHeaders.Set("User-Agent", userAgent) if req.Body != nil { - allHeaders.Set("content-type", "application/json") + allHeaders.Set("Content-Type", "application/json") } for key, value := range req.Headers { + allHeaders.Del(key) for _, v := range value { - allHeaders.Set(key, v) + allHeaders.Add(key, v) } } @@ -46,7 +50,7 @@ func (req *ScalewayRequest) getAllHeaders(token auth.Auth, userAgent string, ano } // getURL constructs a URL based on the base url and the client. -func (req *ScalewayRequest) getURL(baseURL string) (*url.URL, SdkError) { +func (req *ScalewayRequest) getURL(baseURL string) (*url.URL, error) { url, err := url.Parse(baseURL + req.Path) if err != nil { return nil, errors.New("invalid url %s: %s", baseURL+req.Path, err) @@ -63,9 +67,12 @@ func (req *ScalewayRequest) SetBody(body interface{}) error { var content io.Reader switch b := body.(type) { - case *utils.File: + case *File: contentType = b.ContentType content = b.Content + case io.Reader: + contentType = "text/plain" + content = b default: buf, err := json.Marshal(body) if err != nil { @@ -75,8 +82,23 @@ func (req *ScalewayRequest) SetBody(body interface{}) error { content = bytes.NewReader(buf) } + if req.Headers == nil { + req.Headers = http.Header{} + } + req.Headers.Set("Content-Type", contentType) req.Body = content return nil } + +func (req *ScalewayRequest) apply(opts []RequestOption) { + for _, opt := range opts { + opt(req) + } +} + +func (req *ScalewayRequest) validate() error { + // nothing so far + return nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request_option.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request_option.go index a3af9b549..a5ff37663 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request_option.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/request_option.go @@ -2,14 +2,16 @@ package scw import ( "context" + + "github.com/scaleway/scaleway-sdk-go/internal/auth" ) // RequestOption is a function that applies options to a ScalewayRequest. -type RequestOption func(*requestSettings) +type RequestOption func(*ScalewayRequest) // WithContext request option sets the context of a ScalewayRequest func WithContext(ctx context.Context) RequestOption { - return func(s *requestSettings) { + return func(s *ScalewayRequest) { s.ctx = ctx } } @@ -17,27 +19,14 @@ func WithContext(ctx context.Context) RequestOption { // WithAllPages aggregate all pages in the response of a List request. // Will error when pagination is not supported on the request. func WithAllPages() RequestOption { - return func(s *requestSettings) { + return func(s *ScalewayRequest) { s.allPages = true } } -type requestSettings struct { - ctx context.Context - allPages bool -} - -func newRequestSettings() *requestSettings { - return &requestSettings{} -} - -func (s *requestSettings) apply(opts []RequestOption) { - for _, opt := range opts { - opt(s) +// WithAuthRequest overwrites the client access key and secret key used in the request. +func WithAuthRequest(accessKey, secretKey string) RequestOption { + return func(s *ScalewayRequest) { + s.auth = auth.NewToken(accessKey, secretKey) } } - -func (s *requestSettings) validate() SdkError { - // nothing so far - return nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/settings.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/settings.go deleted file mode 100644 index 7607fc5ae..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/settings.go +++ /dev/null @@ -1,64 +0,0 @@ -package scw - -import ( - "fmt" - "net/url" - - "github.com/scaleway/scaleway-sdk-go/internal/auth" - "github.com/scaleway/scaleway-sdk-go/utils" -) - -type settings struct { - apiURL string - token auth.Auth - userAgent string - httpClient httpClient - insecure bool - defaultProjectID *string - defaultRegion *utils.Region - defaultZone *utils.Zone - defaultPageSize *int32 -} - -func newSettings() *settings { - return &settings{} -} - -func (s *settings) apply(opts []ClientOption) { - for _, opt := range opts { - opt(s) - } -} - -func (s *settings) validate() error { - var err error - if s.token == nil { - return fmt.Errorf("no credential option provided") - } - - _, err = url.Parse(s.apiURL) - if err != nil { - return fmt.Errorf("invalid url %s: %s", s.apiURL, err) - } - - // TODO: Check ProjectID format - if s.defaultProjectID != nil && *s.defaultProjectID == "" { - return fmt.Errorf("default project id cannot be empty") - } - - // TODO: Check Region format - if s.defaultRegion != nil && *s.defaultRegion == "" { - return fmt.Errorf("default region cannot be empty") - } - - // TODO: Check Zone format - if s.defaultZone != nil && *s.defaultZone == "" { - return fmt.Errorf("default zone cannot be empty") - } - - if s.defaultPageSize != nil && *s.defaultPageSize <= 0 { - return fmt.Errorf("default page size cannot be <= 0") - } - - return nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/version.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/version.go index d961ada74..3f98429c2 100644 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/version.go +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scw/version.go @@ -5,7 +5,7 @@ import ( "runtime" ) -// TODO: versionning process -const version = "0.0.0" +// TODO: versioning process +const version = "v1.0.0-beta.6" var userAgent = fmt.Sprintf("scaleway-sdk-go/%s (%s; %s; %s)", version, runtime.Version(), runtime.GOOS, runtime.GOARCH) diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/config.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/config.go deleted file mode 100644 index 540d4cbd0..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/config.go +++ /dev/null @@ -1,423 +0,0 @@ -package scwconfig - -import ( - "encoding/json" - "fmt" - "os" - "strconv" - - "github.com/scaleway/scaleway-sdk-go/logger" - "github.com/scaleway/scaleway-sdk-go/utils" - "gopkg.in/yaml.v2" -) - -// Environment variables -const ( - // Up-to-date - scwConfigPathEnv = "SCW_CONFIG_PATH" - scwAccessKeyEnv = "SCW_ACCESS_KEY" - scwSecretKeyEnv = "SCW_SECRET_KEY" - scwActiveProfileEnv = "SCW_PROFILE" - scwAPIURLEnv = "SCW_API_URL" - scwInsecureEnv = "SCW_INSECURE" - scwDefaultProjectIDEnv = "SCW_DEFAULT_PROJECT_ID" - scwDefaultRegionEnv = "SCW_DEFAULT_REGION" - scwDefaultZoneEnv = "SCW_DEFAULT_ZONE" - - // All deprecated (cli&terraform) - terraformAccessKeyEnv = "SCALEWAY_ACCESS_KEY" // used both as access key and secret key - terraformSecretKeyEnv = "SCALEWAY_TOKEN" - terraformOrganizationEnv = "SCALEWAY_ORGANIZATION" - terraformRegionEnv = "SCALEWAY_REGION" - cliTLSVerifyEnv = "SCW_TLSVERIFY" - cliOrganizationEnv = "SCW_ORGANIZATION" - cliRegionEnv = "SCW_REGION" - cliSecretKeyEnv = "SCW_TOKEN" - - // TBD - //cliVerboseEnv = "SCW_VERBOSE_API" - //cliDebugEnv = "DEBUG" - //cliNoCheckVersionEnv = "SCW_NOCHECKVERSION" - //cliTestWithRealAPIEnv = "TEST_WITH_REAL_API" - //cliSecureExecEnv = "SCW_SECURE_EXEC" - //cliGatewayEnv = "SCW_GATEWAY" - //cliSensitiveEnv = "SCW_SENSITIVE" - //cliAccountAPIEnv = "SCW_ACCOUNT_API" - //cliMetadataAPIEnv = "SCW_METADATA_API" - //cliMarketPlaceAPIEnv = "SCW_MARKETPLACE_API" - //cliComputePar1APIEnv = "SCW_COMPUTE_PAR1_API" - //cliComputeAms1APIEnv = "SCW_COMPUTE_AMS1_API" - //cliCommercialTypeEnv = "SCW_COMMERCIAL_TYPE" - //cliTargetArchEnv = "SCW_TARGET_ARCH" -) - -// Config interface is made of getters to retrieve -// the config field by field. -type Config interface { - GetAccessKey() (accessKey string, exist bool) - GetSecretKey() (secretKey string, exist bool) - GetAPIURL() (apiURL string, exist bool) - GetInsecure() (insecure bool, exist bool) - GetDefaultProjectID() (defaultProjectID string, exist bool) - GetDefaultRegion() (defaultRegion utils.Region, exist bool) - GetDefaultZone() (defaultZone utils.Zone, exist bool) -} - -type configV2 struct { - profile `yaml:",inline"` - ActiveProfile *string `yaml:"active_profile,omitempty"` - Profiles map[string]*profile `yaml:"profiles,omitempty"` - - // withProfile is used by LoadWithProfile to handle the following priority order: - // c.withProfile > os.Getenv("SCW_PROFILE") > c.ActiveProfile - withProfile string -} - -type profile struct { - AccessKey *string `yaml:"access_key,omitempty"` - SecretKey *string `yaml:"secret_key,omitempty"` - APIURL *string `yaml:"api_url,omitempty"` - Insecure *bool `yaml:"insecure,omitempty"` - DefaultProjectID *string `yaml:"default_project_id,omitempty"` - DefaultRegion *string `yaml:"default_region,omitempty"` - DefaultZone *string `yaml:"default_zone,omitempty"` -} - -func unmarshalConfV2(content []byte) (*configV2, error) { - var config configV2 - - err := yaml.Unmarshal(content, &config) - if err != nil { - return nil, err - } - return &config, nil -} - -func (c *configV2) catchInvalidProfile() (*configV2, error) { - activeProfile, err := c.getActiveProfile() - if err != nil { - return nil, err - } - if activeProfile == "" { - return c, nil - } - - _, exist := c.Profiles[activeProfile] - if !exist { - return nil, fmt.Errorf("profile %s does not exist %s", activeProfile, inConfigFile()) - } - return c, nil -} - -func (c *configV2) getActiveProfile() (string, error) { - switch { - case c.withProfile != "": - return c.withProfile, nil - case os.Getenv(scwActiveProfileEnv) != "": - return os.Getenv(scwActiveProfileEnv), nil - case c.ActiveProfile != nil: - if *c.ActiveProfile == "" { - return "", fmt.Errorf("active_profile key cannot be empty %s", inConfigFile()) - } - return *c.ActiveProfile, nil - default: - return "", nil - } -} - -// GetAccessKey retrieve the access key from the config. -// It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetAccessKey() (string, bool) { - envValue, _, envExist := getenv(scwAccessKeyEnv, terraformAccessKeyEnv) - activeProfile, _ := c.getActiveProfile() - - var accessKey string - switch { - case envExist: - accessKey = envValue - case activeProfile != "" && c.Profiles[activeProfile].AccessKey != nil: - accessKey = *c.Profiles[activeProfile].AccessKey - case c.AccessKey != nil: - accessKey = *c.AccessKey - default: - logger.Warningf("no access key found") - return "", false - } - - if accessKey == "" { - logger.Warningf("access key is empty") - } - - return accessKey, true -} - -// GetSecretKey retrieve the secret key from the config. -// It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetSecretKey() (string, bool) { - envValue, _, envExist := getenv(scwSecretKeyEnv, cliSecretKeyEnv, terraformSecretKeyEnv, terraformAccessKeyEnv) - activeProfile, _ := c.getActiveProfile() - - var secretKey string - switch { - case envExist: - secretKey = envValue - case activeProfile != "" && c.Profiles[activeProfile].SecretKey != nil: - secretKey = *c.Profiles[activeProfile].SecretKey - case c.SecretKey != nil: - secretKey = *c.SecretKey - default: - logger.Warningf("no secret key found") - return "", false - } - - if secretKey == "" { - logger.Warningf("secret key is empty") - } - - return secretKey, true -} - -// GetAPIURL retrieve the api url from the config. -// It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetAPIURL() (string, bool) { - envValue, _, envExist := getenv(scwAPIURLEnv) - activeProfile, _ := c.getActiveProfile() - - var apiURL string - switch { - case envExist: - apiURL = envValue - case activeProfile != "" && c.Profiles[activeProfile].APIURL != nil: - apiURL = *c.Profiles[activeProfile].APIURL - case c.APIURL != nil: - apiURL = *c.APIURL - default: - return "", false - } - - if apiURL == "" { - logger.Warningf("api URL is empty") - } - - return apiURL, true -} - -// GetInsecure retrieve the insecure flag from the config. -// It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetInsecure() (bool, bool) { - envValue, envKey, envExist := getenv(scwInsecureEnv, cliTLSVerifyEnv) - activeProfile, _ := c.getActiveProfile() - - var insecure bool - var err error - switch { - case envExist: - insecure, err = strconv.ParseBool(envValue) - if err != nil { - logger.Warningf("env variable %s cannot be parsed: %s is invalid boolean ", envKey, envValue) - return false, false - } - - if envKey == cliTLSVerifyEnv { - insecure = !insecure // TLSVerify is the inverse of Insecure - } - case activeProfile != "" && c.Profiles[activeProfile].Insecure != nil: - insecure = *c.Profiles[activeProfile].Insecure - case c.Insecure != nil: - insecure = *c.Insecure - default: - return false, false - } - - return insecure, true -} - -// GetDefaultProjectID retrieve the default project ID -// from the config. Legacy configs used the name -// "organization ID" or "organization" for -// this field. It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetDefaultProjectID() (string, bool) { - envValue, _, envExist := getenv(scwDefaultProjectIDEnv, cliOrganizationEnv, terraformOrganizationEnv) - activeProfile, _ := c.getActiveProfile() - - var defaultProj string - switch { - case envExist: - defaultProj = envValue - case activeProfile != "" && c.Profiles[activeProfile].DefaultProjectID != nil: - defaultProj = *c.Profiles[activeProfile].DefaultProjectID - case c.DefaultProjectID != nil: - defaultProj = *c.DefaultProjectID - default: - return "", false - } - - // todo: validate format - if defaultProj == "" { - logger.Warningf("default project ID is empty") - } - - return defaultProj, true -} - -// GetDefaultRegion retrieve the default region -// from the config. It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetDefaultRegion() (utils.Region, bool) { - envValue, _, envExist := getenv(scwDefaultRegionEnv, cliRegionEnv, terraformRegionEnv) - activeProfile, _ := c.getActiveProfile() - - var defaultRegion string - switch { - case envExist: - defaultRegion = v1RegionToV2(envValue) - case activeProfile != "" && c.Profiles[activeProfile].DefaultRegion != nil: - defaultRegion = *c.Profiles[activeProfile].DefaultRegion - case c.DefaultRegion != nil: - defaultRegion = *c.DefaultRegion - default: - return "", false - } - - // todo: validate format - if defaultRegion == "" { - logger.Warningf("default region is empty") - } - - return utils.Region(defaultRegion), true -} - -// GetDefaultZone retrieve the default zone -// from the config. It will check the following order: -// env, legacy env, active profile, default profile -// -// If the config is present in one of the above environment the -// value (which may be empty) is returned and the boolean is true. -// Otherwise the returned value will be empty and the boolean will -// be false. -func (c *configV2) GetDefaultZone() (utils.Zone, bool) { - envValue, _, envExist := getenv(scwDefaultZoneEnv) - activeProfile, _ := c.getActiveProfile() - - var defaultZone string - switch { - case envExist: - defaultZone = envValue - case activeProfile != "" && c.Profiles[activeProfile].DefaultZone != nil: - defaultZone = *c.Profiles[activeProfile].DefaultZone - case c.DefaultZone != nil: - defaultZone = *c.DefaultZone - default: - return "", false - } - - // todo: validate format - if defaultZone == "" { - logger.Warningf("default zone is empty") - } - - return utils.Zone(defaultZone), true -} - -func getenv(upToDateKey string, deprecatedKeys ...string) (string, string, bool) { - value, exist := os.LookupEnv(upToDateKey) - if exist { - logger.Infof("reading value from %s", upToDateKey) - return value, upToDateKey, true - } - - for _, key := range deprecatedKeys { - value, exist := os.LookupEnv(key) - if exist { - logger.Infof("reading value from %s", key) - logger.Warningf("%s is deprecated, please use %s instead", key, upToDateKey) - return value, key, true - } - } - - return "", "", false -} - -const ( - v1RegionFrPar = "par1" - v1RegionNlAms = "ams1" -) - -// configV1 is a Scaleway CLI configuration file -type configV1 struct { - // Organization is the identifier of the Scaleway organization - Organization string `json:"organization"` - - // Token is the authentication token for the Scaleway organization - Token string `json:"token"` - - // Version is the actual version of scw CLI - Version string `json:"version"` -} - -func unmarshalConfV1(content []byte) (*configV1, error) { - var config configV1 - err := json.Unmarshal(content, &config) - if err != nil { - return nil, err - } - return &config, err -} - -func (v1 *configV1) toV2() *configV2 { - return &configV2{ - profile: profile{ - DefaultProjectID: &v1.Organization, - SecretKey: &v1.Token, - // ignore v1 version - }, - } -} - -func v1RegionToV2(region string) string { - switch region { - case v1RegionFrPar: - logger.Warningf("par1 is a deprecated name for region, use fr-par instead") - return "fr-par" - case v1RegionNlAms: - logger.Warningf("ams1 is a deprecated name for region, use nl-ams instead") - return "nl-ams" - default: - return region - } -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/load.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/load.go deleted file mode 100644 index 4dc0cd09e..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/load.go +++ /dev/null @@ -1,104 +0,0 @@ -package scwconfig - -import ( - "fmt" - "io/ioutil" - "os" - - "github.com/scaleway/scaleway-sdk-go/logger" -) - -const ( - documentationLink = "https://github.com/scaleway/scaleway-sdk-go/blob/master/scwconfig/README.md" -) - -// LoadWithProfile call Load() and set withProfile with the profile name. -func LoadWithProfile(profileName string) (Config, error) { - config, err := Load() - if err != nil { - return nil, err - } - - v2Loaded := config.(*configV2) - v2Loaded.withProfile = profileName - return v2Loaded.catchInvalidProfile() -} - -// Load config in the following order: -// - config file from SCW_CONFIG_PATH (V2 or V1) -// - config file V2 -// - config file V1 -// When the latest is found it migrates the V1 config -// to a V2 config following the V2 config path. -func Load() (Config, error) { - // STEP 1: try to load config file from SCW_CONFIG_PATH - configPath := os.Getenv(scwConfigPathEnv) - if configPath != "" { - content, err := ioutil.ReadFile(configPath) - if err != nil { - return nil, fmt.Errorf("cannot read config file %s: %s", scwConfigPathEnv, err) - } - confV1, err := unmarshalConfV1(content) - if err == nil { - // do not migrate automatically when using SCW_CONFIG_PATH - logger.Warningf("loaded config V1 from %s: config V1 is deprecated, please switch your config file to the V2: %s", configPath, documentationLink) - return confV1.toV2().catchInvalidProfile() - } - confV2, err := unmarshalConfV2(content) - if err != nil { - return nil, fmt.Errorf("content of config file %s is invalid: %s", configPath, err) - } - - logger.Infof("successfully loaded config V2 from %s", configPath) - return confV2.catchInvalidProfile() - } - - // STEP 2: try to load config file V2 - v2Path, v2PathOk := GetConfigV2FilePath() - if v2PathOk && fileExist(v2Path) { - file, err := ioutil.ReadFile(v2Path) - if err != nil { - return nil, fmt.Errorf("cannot read config file: %s", err) - } - - confV2, err := unmarshalConfV2(file) - if err != nil { - return nil, fmt.Errorf("content of config file %s is invalid: %s", v2Path, err) - } - - logger.Infof("successfully loaded config V2 from %s", v2Path) - return confV2.catchInvalidProfile() - } - - // STEP 3: try to load config file V1 - logger.Debugf("no config V2 found, fall back to config V1") - v1Path, v1PathOk := GetConfigV1FilePath() - if !v1PathOk { - logger.Infof("config file not found: no home directory") - return (&configV2{}).catchInvalidProfile() - } - file, err := ioutil.ReadFile(v1Path) - if err != nil { - logger.Infof("cannot read config file: %s", err) - return (&configV2{}).catchInvalidProfile() // ignore if file doesn't exist - } - confV1, err := unmarshalConfV1(file) - if err != nil { - return nil, fmt.Errorf("content of config file %s is invalid json: %s", v1Path, err) - } - - // STEP 4: migrate V1 config to V2 config file - if v2PathOk { - err = migrateV1toV2(confV1, v2Path) - if err != nil { - return nil, err - } - } - - return confV1.toV2().catchInvalidProfile() -} - -func fileExist(name string) bool { - _, err := os.Stat(name) - return err == nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/migrate.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/migrate.go deleted file mode 100644 index 080f2741a..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/migrate.go +++ /dev/null @@ -1,47 +0,0 @@ -package scwconfig - -import ( - "io/ioutil" - "os" - "path/filepath" - - "github.com/scaleway/scaleway-sdk-go/logger" - "gopkg.in/yaml.v2" -) - -const ( - defaultConfigPermission = 0600 -) - -// migrateV1toV2 converts the V1 config to V2 config and save it in the target path -// use config.Save() when the method is public -func migrateV1toV2(configV1 *configV1, targetPath string) error { - // STEP 0: get absolute target path - - targetPath = filepath.Clean(targetPath) - - // STEP 1: create dir - err := os.MkdirAll(filepath.Dir(targetPath), 0700) - if err != nil { - logger.Debugf("mkdir did not work on %s: %s", filepath.Dir(targetPath), err) - return nil - } - - // STEP 2: marshal yaml config - newConfig := configV1.toV2() - file, err := yaml.Marshal(newConfig) - if err != nil { - return err - } - - // STEP 3: save config - err = ioutil.WriteFile(targetPath, file, defaultConfigPermission) - if err != nil { - logger.Debugf("cannot write file %s: %s", targetPath, err) - return nil - } - - // STEP 4: log success - logger.Infof("config successfully migrated to %s", targetPath) - return nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/path.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/path.go deleted file mode 100644 index feeea454e..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/scwconfig/path.go +++ /dev/null @@ -1,71 +0,0 @@ -package scwconfig - -import ( - "errors" - "os" - "path/filepath" -) - -const ( - unixHomeDirEnv = "HOME" - windowsHomeDirEnv = "USERPROFILE" - xdgConfigDirEnv = "XDG_CONFIG_HOME" - - defaultConfigFileName = "config.yaml" -) - -var ( - // ErrNoHomeDir errors when no user directory is found - ErrNoHomeDir = errors.New("user home directory not found") -) - -func inConfigFile() string { - v2path, exist := GetConfigV2FilePath() - if exist { - return "in config file " + v2path - } - return "" -} - -// GetConfigV2FilePath returns the path to the Scaleway CLI config file -func GetConfigV2FilePath() (string, bool) { - configDir, err := GetScwConfigDir() - if err != nil { - return "", false - } - return filepath.Join(configDir, defaultConfigFileName), true -} - -// GetConfigV1FilePath returns the path to the Scaleway CLI config file -func GetConfigV1FilePath() (string, bool) { - path, err := GetHomeDir() - if err != nil { - return "", false - } - return filepath.Join(path, ".scwrc"), true -} - -// GetScwConfigDir returns the path to scw config folder -func GetScwConfigDir() (string, error) { - if xdgPath := os.Getenv(xdgConfigDirEnv); xdgPath != "" { - return filepath.Join(xdgPath, "scw"), nil - } - - homeDir, err := GetHomeDir() - if err != nil { - return "", err - } - return filepath.Join(homeDir, ".config", "scw"), nil -} - -// GetHomeDir returns the path to your home directory -func GetHomeDir() (string, error) { - switch { - case os.Getenv(unixHomeDirEnv) != "": - return os.Getenv(unixHomeDirEnv), nil - case os.Getenv(windowsHomeDirEnv) != "": - return os.Getenv(windowsHomeDirEnv), nil - default: - return "", ErrNoHomeDir - } -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/convert.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/convert.go deleted file mode 100644 index eae05af32..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/convert.go +++ /dev/null @@ -1,158 +0,0 @@ -package utils - -import "time" - -// String returns a pointer to the string value passed in. -func String(v string) *string { - return &v -} - -// StringSlice converts a slice of string values into a slice of -// string pointers -func StringSlice(src []string) []*string { - dst := make([]*string, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Strings returns a pointer to the []string value passed in. -func Strings(v []string) *[]string { - return &v -} - -// StringsSlice converts a slice of []string values into a slice of -// []string pointers -func StringsSlice(src [][]string) []*[]string { - dst := make([]*[]string, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Bytes returns a pointer to the []byte value passed in. -func Bytes(v []byte) *[]byte { - return &v -} - -// BytesSlice converts a slice of []byte values into a slice of -// []byte pointers -func BytesSlice(src [][]byte) []*[]byte { - dst := make([]*[]byte, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Bool returns a pointer to the bool value passed in. -func Bool(v bool) *bool { - return &v -} - -// BoolSlice converts a slice of bool values into a slice of -// bool pointers -func BoolSlice(src []bool) []*bool { - dst := make([]*bool, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int32 returns a pointer to the int32 value passed in. -func Int32(v int32) *int32 { - return &v -} - -// Int32Slice converts a slice of int32 values into a slice of -// int32 pointers -func Int32Slice(src []int32) []*int32 { - dst := make([]*int32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int64 returns a pointer to the int64 value passed in. -func Int64(v int64) *int64 { - return &v -} - -// Int64Slice converts a slice of int64 values into a slice of -// int64 pointers -func Int64Slice(src []int64) []*int64 { - dst := make([]*int64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint32 returns a pointer to the uint32 value passed in. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint32Slice converts a slice of uint32 values into a slice of -// uint32 pointers -func Uint32Slice(src []uint32) []*uint32 { - dst := make([]*uint32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint64 returns a pointer to the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return &v -} - -// Uint64Slice converts a slice of uint64 values into a slice of -// uint64 pointers -func Uint64Slice(src []uint64) []*uint64 { - dst := make([]*uint64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Float32 returns a pointer to the float32 value passed in. -func Float32(v float32) *float32 { - return &v -} - -// Float32Slice converts a slice of float32 values into a slice of -// float32 pointers -func Float32Slice(src []float32) []*float32 { - dst := make([]*float32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Float64 returns a pointer to the float64 value passed in. -func Float64(v float64) *float64 { - return &v -} - -// Float64Slice converts a slice of float64 values into a slice of -// float64 pointers -func Float64Slice(src []float64) []*float64 { - dst := make([]*float64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Duration returns a pointer to the Duration value passed in. -func Duration(v time.Duration) *time.Duration { - return &v -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/file.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/file.go deleted file mode 100644 index 7d99c4069..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/file.go +++ /dev/null @@ -1,15 +0,0 @@ -package utils - -import "io" - -// File is the structure used to receive / send a file from / to the API -type File struct { - // Name of the file - Name string `json:"name"` - - // ContentType used in the HTTP header `Content-Type` - ContentType string `json:"content_type"` - - // Content of the file - Content io.Reader `json:"content"` -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/money.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/money.go deleted file mode 100644 index 58f3e55cb..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/money.go +++ /dev/null @@ -1,33 +0,0 @@ -package utils - -// Money represents an amount of money with its currency type. -type Money struct { - // CurrencyCode is the 3-letter currency code defined in ISO 4217. - CurrencyCode string `json:"currency_code,omitempty"` - - // Units is the whole units of the amount. - // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. - Units int64 `json:"units,omitempty"` - - // Nanos is the number of nano (10^-9) units of the amount. - // The value must be between -999,999,999 and +999,999,999 inclusive. - // If `units` is positive, `nanos` must be positive or zero. - // If `units` is zero, `nanos` can be positive, zero, or negative. - // If `units` is negative, `nanos` must be negative or zero. - // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. - Nanos int32 `json:"nanos,omitempty"` -} - -// NewMoneyFromFloat conerts a float with currency to a Money object. -func NewMoneyFromFloat(value float64, currency string) *Money { - return &Money{ - CurrencyCode: currency, - Units: int64(value), - Nanos: int32((value - float64(int64(value))) * 1000000000), - } -} - -// ToFloat converts a Money object to a float. -func (m *Money) ToFloat() float64 { - return float64(m.Units) + float64(m.Nanos)/1000000000 -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/service_info.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/service_info.go deleted file mode 100644 index 01a984be4..000000000 --- a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/utils/service_info.go +++ /dev/null @@ -1,17 +0,0 @@ -package utils - -// ServiceInfo contains API metadata -// These metadata are only here for debugging. Do not rely on these values -type ServiceInfo struct { - // Name is the name of the API - Name string `json:"name"` - - // Description is a human readable description for the API - Description string `json:"description"` - - // Version is the version of the API - Version string `json:"version"` - - // DocumentationUrl is the a web url where the documentation of the API can be found - DocumentationUrl *string `json:"documentation_url"` -} diff --git a/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/validation/is.go b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/validation/is.go new file mode 100644 index 000000000..929d88d81 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/scaleway/scaleway-sdk-go/validation/is.go @@ -0,0 +1,56 @@ +// Package validation provides format validation functions. +package validation + +import ( + "net/url" + "regexp" +) + +var ( + isUUIDRegexp = regexp.MustCompile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") + isRegionRegex = regexp.MustCompile("^[a-z]{2}-[a-z]{3}$") + isZoneRegex = regexp.MustCompile("^[a-z]{2}-[a-z]{3}-[1-9]$") + isAccessKey = regexp.MustCompile("^SCW[A-Z0-9]{17}$") + isEmailRegexp = regexp.MustCompile("^.+@.+$") +) + +// IsUUID returns true if the given string has a valid UUID format. +func IsUUID(s string) bool { + return isUUIDRegexp.MatchString(s) +} + +// IsAccessKey returns true if the given string has a valid Scaleway access key format. +func IsAccessKey(s string) bool { + return isAccessKey.MatchString(s) +} + +// IsSecretKey returns true if the given string has a valid Scaleway secret key format. +func IsSecretKey(s string) bool { + return IsUUID(s) +} + +// IsOrganizationID returns true if the given string has a valid Scaleway organization ID format. +func IsOrganizationID(s string) bool { + return IsUUID(s) +} + +// IsRegion returns true if the given string has a valid region format. +func IsRegion(s string) bool { + return isRegionRegex.MatchString(s) +} + +// IsZone returns true if the given string has a valid zone format. +func IsZone(s string) bool { + return isZoneRegex.MatchString(s) +} + +// IsURL returns true if the given string has a valid URL format. +func IsURL(s string) bool { + _, err := url.Parse(s) + return err == nil +} + +// IsEmail returns true if the given string has an email format. +func IsEmail(v string) bool { + return isEmailRegexp.MatchString(v) +}