diff --git a/ecl/sss/v1/approval_requests/testing/fixtures.go b/ecl/sss/v1/approval_requests/testing/fixtures.go index cdfc4e7..6afb8ec 100644 --- a/ecl/sss/v1/approval_requests/testing/fixtures.go +++ b/ecl/sss/v1/approval_requests/testing/fixtures.go @@ -36,7 +36,7 @@ var listResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, @@ -66,7 +66,7 @@ var listResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, @@ -113,7 +113,7 @@ var firstApprovalRequest = ar.ApprovalRequest{ Descriptions: []ar.Description{ { Lang: "en", - Text: "approval request test", + Text: "approval resquest test", }, }, RequestUser: false, @@ -144,7 +144,7 @@ var secondApprovalRequest = ar.ApprovalRequest{ Descriptions: []ar.Description{ { Lang: "en", - Text: "approval request test", + Text: "approval resquest test", }, }, RequestUser: false, @@ -181,7 +181,7 @@ var getResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, diff --git a/v2/ecl/imagestorage/v2/images/requests.go b/v2/ecl/imagestorage/v2/images/requests.go index f65e588..2f659be 100644 --- a/v2/ecl/imagestorage/v2/images/requests.go +++ b/v2/ecl/imagestorage/v2/images/requests.go @@ -173,9 +173,6 @@ type CreateOpts struct { // is required to boot the image. MinRAM int `json:"min_ram,omitempty"` - // License Switch is meant to bring your image license into ECL environment - LicenseSwitch string `json:"license_switch,omitempty"` - // protected is whether the image is not deletable. Protected *bool `json:"protected,omitempty"` diff --git a/v2/ecl/imagestorage/v2/images/results.go b/v2/ecl/imagestorage/v2/images/results.go index af2e14e..5b050fe 100644 --- a/v2/ecl/imagestorage/v2/images/results.go +++ b/v2/ecl/imagestorage/v2/images/results.go @@ -85,9 +85,6 @@ type Image struct { // VirtualSize is the virtual size of the image VirtualSize int64 `json:"virtual_size"` - - // License Switch is meant to bring your image license into ECL environment - LicenseSwitch string `json:"license_switch"` } func (r *Image) UnmarshalJSON(b []byte) error { diff --git a/v2/ecl/managed_load_balancer/v1/certificates/requests.go b/v2/ecl/managed_load_balancer/v1/certificates/requests.go index 75bc2f7..ff6d055 100644 --- a/v2/ecl/managed_load_balancer/v1/certificates/requests.go +++ b/v2/ecl/managed_load_balancer/v1/certificates/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - ID of the owner tenant of the resource @@ -77,13 +79,17 @@ Create Certificate type CreateOpts struct { // - Name of the certificate + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the certificate + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the certificate - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` } @@ -134,13 +140,17 @@ Update Certificate type UpdateOpts struct { // - Name of the certificate + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the certificate + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the certificate - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -195,9 +205,9 @@ type UploadFileOpts struct { Type string `json:"type"` // - Content of the certificate file to be uploaded - // - Size of the file before encoding by Base64 must be less than or equal to 16KB - // - Must be specified the content of the file that encoded by Base64 format - // - Format of the file before encoding by Base64 must be PEM + // - Content must be Base64 encoded + // - The file size before encoding must be less than or equal to 16KB + // - The file format before encoding must be PEM // - DER can be converted to PEM by using OpenSSL command Content string `json:"content"` } diff --git a/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go b/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go index 8af1aa2..39a33da 100644 --- a/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go +++ b/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -100,17 +102,21 @@ Create Health Monitor type CreateOpts struct { // - Name of the health monitor + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the health monitor + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the health monitor - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port int `json:"port"` // - Protocol of the health monitor for healthchecking @@ -121,20 +127,22 @@ type CreateOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` @@ -175,7 +183,7 @@ Show Health Monitor // ShowOpts represents options used to show a health monitor. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -215,13 +223,17 @@ Update Health Monitor Attributes type UpdateOpts struct { // - Name of the health monitor + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the health monitor + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the health monitor - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -272,7 +284,7 @@ Create Staged Health Monitor Configurations type CreateStagedOpts struct { // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -283,20 +295,22 @@ type CreateStagedOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` } @@ -348,7 +362,7 @@ Update Staged Health Monitor Configurations type UpdateStagedOpts struct { // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port *int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -359,20 +373,22 @@ type UpdateStagedOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry *int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout *int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path *string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode *string `json:"http_status_code,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/health_monitors/results.go b/v2/ecl/managed_load_balancer/v1/health_monitors/results.go index e2266c2..12af174 100644 --- a/v2/ecl/managed_load_balancer/v1/health_monitors/results.go +++ b/v2/ecl/managed_load_balancer/v1/health_monitors/results.go @@ -64,7 +64,7 @@ type CancelStagedResult struct { type ConfigurationInResponse struct { // - Port number of the health monitor for healthchecking - // - Returns `0` when `protocol` is `"icmp"` + // - If `protocol` is `"icmp"`, returns `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -75,18 +75,18 @@ type ConfigurationInResponse struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` } @@ -144,7 +144,7 @@ type HealthMonitor struct { TenantID string `json:"tenant_id"` // - Port number of the health monitor for healthchecking - // - Returns `0` when `protocol` is `"icmp"` + // - If `protocol` is `"icmp"`, returns `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -155,29 +155,29 @@ type HealthMonitor struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` // - Running configurations of the health monitor - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the health monitor that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/listeners/requests.go b/v2/ecl/managed_load_balancer/v1/listeners/requests.go index 5f13505..7be82b0 100644 --- a/v2/ecl/managed_load_balancer/v1/listeners/requests.go +++ b/v2/ecl/managed_load_balancer/v1/listeners/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -86,22 +88,27 @@ Create Listener type CreateOpts struct { // - Name of the listener + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the listener + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the listener - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port int `json:"port"` // - Protocol of the listener for listening @@ -144,7 +151,7 @@ Show Listener // ShowOpts represents options used to show a listener. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -184,13 +191,17 @@ Update Listener Attribute type UpdateOpts struct { // - Name of the listener + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the listener + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the listener - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -241,12 +252,13 @@ Create Staged Listener Configurations type CreateStagedOpts struct { // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address,omitempty"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port int `json:"port,omitempty"` // - Protocol of the listener for listening @@ -300,12 +312,13 @@ Update Staged Listener Configurations type UpdateStagedOpts struct { // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address,omitempty"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port *int `json:"port,omitempty"` // - Protocol of the listener for listening diff --git a/v2/ecl/managed_load_balancer/v1/listeners/results.go b/v2/ecl/managed_load_balancer/v1/listeners/results.go index 388284c..9ac1068 100644 --- a/v2/ecl/managed_load_balancer/v1/listeners/results.go +++ b/v2/ecl/managed_load_balancer/v1/listeners/results.go @@ -135,13 +135,13 @@ type Listener struct { Protocol string `json:"protocol,omitempty"` // - Running configurations of the listener - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the listener that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go b/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go index 178aecd..0c70e37 100644 --- a/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go +++ b/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -93,8 +95,9 @@ type CreateOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` } @@ -102,20 +105,19 @@ type CreateOptsReservedFixedIP struct { type CreateOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces ReservedFixedIPs *[]CreateOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -130,7 +132,7 @@ type CreateOptsSyslogServer struct { Port int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol string `json:"protocol,omitempty"` } @@ -138,25 +140,30 @@ type CreateOptsSyslogServer struct { type CreateOpts struct { // - Name of the load balancer + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the load balancer + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the load balancer - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - ID of the plan PlanID string `json:"plan_id,omitempty"` // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]CreateOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -198,7 +205,7 @@ Show Load Balancer // ShowOpts represents options used to show a load balancer. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -238,13 +245,17 @@ Update Load Balancer Attributes type UpdateOpts struct { // - Name of the load balancer + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the load balancer + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the load balancer - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -353,8 +364,9 @@ type CreateStagedOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` } @@ -362,20 +374,21 @@ type CreateStagedOptsReservedFixedIP struct { type CreateStagedOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `virtual_ip_address` value + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `reserved_fixed_ips` value ReservedFixedIPs *[]CreateStagedOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -390,7 +403,7 @@ type CreateStagedOptsSyslogServer struct { Port int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol string `json:"protocol,omitempty"` } @@ -398,12 +411,13 @@ type CreateStagedOptsSyslogServer struct { type CreateStagedOpts struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]CreateStagedOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -460,8 +474,9 @@ type UpdateStagedOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address"` } @@ -469,20 +484,21 @@ type UpdateStagedOptsReservedFixedIP struct { type UpdateStagedOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID *string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `virtual_ip_address` value + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress *string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `reserved_fixed_ips` value ReservedFixedIPs *[]UpdateStagedOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -497,7 +513,7 @@ type UpdateStagedOptsSyslogServer struct { Port *int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol *string `json:"protocol,omitempty"` } @@ -505,12 +521,13 @@ type UpdateStagedOptsSyslogServer struct { type UpdateStagedOpts struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]UpdateStagedOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer diff --git a/v2/ecl/managed_load_balancer/v1/load_balancers/results.go b/v2/ecl/managed_load_balancer/v1/load_balancers/results.go index d18894d..e3679b7 100644 --- a/v2/ecl/managed_load_balancer/v1/load_balancers/results.go +++ b/v2/ecl/managed_load_balancer/v1/load_balancers/results.go @@ -78,12 +78,13 @@ type ReservedFixedIPInResponse struct { type ConfigurationInResponse struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers []SyslogServerInResponse `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -178,7 +179,7 @@ type LoadBalancer struct { SecondaryAvailabilityZone string `json:"secondary_availability_zone,omitempty"` // - Primary or secondary availability zone where the load balancer is currently running - // - Return `"UNDEFINED"` if can not define active availability zone + // - If can not define active availability zone, returns `"UNDEFINED"` ActiveAvailabilityZone string `json:"active_availability_zone"` // - Revision of the load balancer @@ -194,25 +195,26 @@ type LoadBalancer struct { TenantID string `json:"tenant_id"` // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers []SyslogServerInResponse `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer Interfaces []InterfaceInResponse `json:"interfaces,omitempty"` // - Running configurations of the load balancer - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the load balancer that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/operations/requests.go b/v2/ecl/managed_load_balancer/v1/operations/requests.go index fcd26e9..c93f0d6 100644 --- a/v2/ecl/managed_load_balancer/v1/operations/requests.go +++ b/v2/ecl/managed_load_balancer/v1/operations/requests.go @@ -38,10 +38,10 @@ type ListOpts struct { // - ID of the owner tenant of the resource TenantID string `q:"tenant_id"` - // - When `true` is specified, operations of deleted resource is not displayed + // - If `true` is set, operations of deleted resource is not displayed NoDeleted bool `q:"no_deleted"` - // - When `true` is specified, only the latest operation of each resource is displayed + // - If `true` is set, only the latest operation of each resource is displayed Latest bool `q:"latest"` } diff --git a/v2/ecl/managed_load_balancer/v1/plans/requests.go b/v2/ecl/managed_load_balancer/v1/plans/requests.go index 0a56dd9..ef8191f 100644 --- a/v2/ecl/managed_load_balancer/v1/plans/requests.go +++ b/v2/ecl/managed_load_balancer/v1/plans/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Bandwidth of the plan diff --git a/v2/ecl/managed_load_balancer/v1/policies/doc.go b/v2/ecl/managed_load_balancer/v1/policies/doc.go index fc217d1..28e6272 100644 --- a/v2/ecl/managed_load_balancer/v1/policies/doc.go +++ b/v2/ecl/managed_load_balancer/v1/policies/doc.go @@ -37,6 +37,7 @@ Example to create a policy Tags: tags, Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -105,6 +106,7 @@ Example to create staged policy configurations createStagedOpts := policies.CreateStagedOpts{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -136,6 +138,7 @@ Example to update staged policy configurations algorithm := "round-robin" persistence := "cookie" + idleTimeout := 600 sorryPageUrl := "https://example.com/sorry" sourceNat := "enable" certificateID := "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -146,6 +149,7 @@ Example to update staged policy configurations updateStagedOpts := policies.UpdateStagedOpts{ Algorithm: &algorithm, Persistence: &persistence, + IdleTimeout: &idleTimeout, SorryPageUrl: &sorryPageUrl, SourceNat: &sourceNat, CertificateID: &certificateID, diff --git a/v2/ecl/managed_load_balancer/v1/policies/requests.go b/v2/ecl/managed_load_balancer/v1/policies/requests.go index 4e7eb74..a8e1634 100644 --- a/v2/ecl/managed_load_balancer/v1/policies/requests.go +++ b/v2/ecl/managed_load_balancer/v1/policies/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -37,8 +39,10 @@ type ListOpts struct { // - Persistence setting of the policy Persistence string `q:"persistence"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Must be specified as URL format + // - The duration (in seconds) during which a session is allowed to remain inactive + IdleTimeout int `q:"idle_timeout"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down SorryPageUrl string `q:"sorry_page_url"` // - Source NAT setting of the policy @@ -105,56 +109,69 @@ Create Policy type CreateOpts struct { // - Name of the policy + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the policy + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the policy - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Load balancing algorithm (method) of the policy Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID string `json:"health_monitor_id"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID string `json:"listener_id"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID string `json:"default_target_group_id"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` // - ID of the load balancer which the policy belongs to @@ -194,7 +211,7 @@ Show Policy // ShowOpts represents options used to show a policy. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -234,13 +251,17 @@ Update Policy Attributes type UpdateOpts struct { // - Name of the policy + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the policy + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the policy - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -294,46 +315,55 @@ type CreateStagedOpts struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"http"` or `"https"` to others + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"http"` or `"https"` to others, set `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID string `json:"health_monitor_id,omitempty"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID string `json:"listener_id,omitempty"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` } @@ -387,46 +417,55 @@ type UpdateStagedOpts struct { Algorithm *string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence *string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"http"` or `"https"` to others + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout *int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"http"` or `"https"` to others, set `""` SorryPageUrl *string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat *string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` CertificateID *string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID *string `json:"health_monitor_id,omitempty"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID *string `json:"listener_id,omitempty"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID *string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` TLSPolicyID *string `json:"tls_policy_id,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/policies/results.go b/v2/ecl/managed_load_balancer/v1/policies/results.go index a196650..7a345db 100644 --- a/v2/ecl/managed_load_balancer/v1/policies/results.go +++ b/v2/ecl/managed_load_balancer/v1/policies/results.go @@ -67,21 +67,30 @@ type ConfigurationInResponse struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Returns `""` when protocol is not `"http"` or `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If protocol is not `"http"` or `"https"`, returns `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy @@ -94,7 +103,7 @@ type ConfigurationInResponse struct { DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` } @@ -154,21 +163,30 @@ type Policy struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Returns `""` when protocol is not `"http"` or `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If protocol is not `"http"` or `"https"`, returns `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy @@ -181,17 +199,17 @@ type Policy struct { DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` // - Running configurations of the policy - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the policy that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/policies/testing/fixtures.go b/v2/ecl/managed_load_balancer/v1/policies/testing/fixtures.go index d21e388..ad4dc1d 100644 --- a/v2/ecl/managed_load_balancer/v1/policies/testing/fixtures.go +++ b/v2/ecl/managed_load_balancer/v1/policies/testing/fixtures.go @@ -28,6 +28,7 @@ var listResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -59,6 +60,7 @@ func listResult() []policies.Policy { policy1.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy1.Algorithm = "round-robin" policy1.Persistence = "cookie" + policy1.IdleTimeout = 600 policy1.SorryPageUrl = "https://example.com/sorry" policy1.SourceNat = "enable" policy1.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -80,6 +82,7 @@ var createRequest = fmt.Sprintf(` }, "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -106,6 +109,7 @@ var createResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": null, "persistence": null, + "idle_timeout": null, "sorry_page_url": null, "source_nat": null, "certificate_id": null, @@ -136,6 +140,7 @@ func createResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "" policy.Persistence = "" + policy.IdleTimeout = 0 policy.SorryPageUrl = "" policy.SourceNat = "" policy.CertificateID = "" @@ -162,6 +167,7 @@ var showResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -172,6 +178,7 @@ var showResponse = fmt.Sprintf(` "current": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -191,6 +198,7 @@ func showResult() *policies.Policy { current := policies.ConfigurationInResponse{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -217,6 +225,7 @@ func showResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -256,6 +265,7 @@ var updateResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": null, "persistence": null, + "idle_timeout": null, "sorry_page_url": null, "source_nat": null, "certificate_id": null, @@ -286,6 +296,7 @@ func updateResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "" policy.Persistence = "" + policy.IdleTimeout = 0 policy.SorryPageUrl = "" policy.SourceNat = "" policy.CertificateID = "" @@ -302,6 +313,7 @@ var createStagedRequest = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -317,6 +329,7 @@ var createStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -332,6 +345,7 @@ func createStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -348,6 +362,7 @@ var showStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -363,6 +378,7 @@ func showStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -379,6 +395,7 @@ var updateStagedRequest = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -394,6 +411,7 @@ var updateStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -409,6 +427,7 @@ func updateStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" diff --git a/v2/ecl/managed_load_balancer/v1/policies/testing/requests_test.go b/v2/ecl/managed_load_balancer/v1/policies/testing/requests_test.go index 4e61f8b..3f97b16 100644 --- a/v2/ecl/managed_load_balancer/v1/policies/testing/requests_test.go +++ b/v2/ecl/managed_load_balancer/v1/policies/testing/requests_test.go @@ -97,6 +97,7 @@ func TestCreatePolicy(t *testing.T) { Tags: tags, Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -223,6 +224,7 @@ func TestCreateStagedPolicy(t *testing.T) { createStagedOpts := policies.CreateStagedOpts{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -284,6 +286,7 @@ func TestUpdateStagedPolicy(t *testing.T) { algorithm := "round-robin" persistence := "cookie" + idleTimeout := 600 sorryPageUrl := "https://example.com/sorry" sourceNat := "enable" certificateID := "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -294,6 +297,7 @@ func TestUpdateStagedPolicy(t *testing.T) { updateStagedOpts := policies.UpdateStagedOpts{ Algorithm: &algorithm, Persistence: &persistence, + IdleTimeout: &idleTimeout, SorryPageUrl: &sorryPageUrl, SourceNat: &sourceNat, CertificateID: &certificateID, diff --git a/v2/ecl/managed_load_balancer/v1/routes/requests.go b/v2/ecl/managed_load_balancer/v1/routes/requests.go index ac0608f..9a54be1 100644 --- a/v2/ecl/managed_load_balancer/v1/routes/requests.go +++ b/v2/ecl/managed_load_balancer/v1/routes/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -83,26 +85,31 @@ Create Route type CreateOpts struct { // - Name of the (static) route + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the (static) route + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the (static) route - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - CIDR of destination for the (static) route - // - Can be specified as `0.0.0.0/0` to configure default gateway + // - If you configure `destination_cidr` as default gateway, set `0.0.0.0/0` // - `destination_cidr` can not be changed once configured - // - To change `destination_cidr` , recreating the (static) route is needed - // - Must be specified the unique CIDR in all (static) routes belongs to the same load balancer - // - Must be specified the CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - If you want to change `destination_cidr`, recreate the (static) route again + // - Set a unique CIDR for all (static) routes which belong to the same load balancer + // - Set a CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a link-local CIDR (RFC 3927) which includes Common Function Gateway DestinationCidr string `json:"destination_cidr"` // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress string `json:"next_hop_ip_address"` // - ID of the load balancer which the (static) route belongs to @@ -142,7 +149,7 @@ Show Route // ShowOpts represents options used to show a route. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -182,13 +189,17 @@ Update Route Attributes type UpdateOpts struct { // - Name of the (static) route + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the (static) route + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the (static) route - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -239,8 +250,8 @@ Create Staged Route Configurations type CreateStagedOpts struct { // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress string `json:"next_hop_ip_address,omitempty"` } @@ -291,8 +302,8 @@ Update Staged Route Configurations type UpdateStagedOpts struct { // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress *string `json:"next_hop_ip_address,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/routes/results.go b/v2/ecl/managed_load_balancer/v1/routes/results.go index 1119fad..1629b39 100644 --- a/v2/ecl/managed_load_balancer/v1/routes/results.go +++ b/v2/ecl/managed_load_balancer/v1/routes/results.go @@ -126,13 +126,13 @@ type Route struct { NextHopIPAddress string `json:"next_hop_ip_address,omitempty"` // - Running configurations of the (static) route - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the (static) route that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/rules/requests.go b/v2/ecl/managed_load_balancer/v1/rules/requests.go index 0def829..3da2422 100644 --- a/v2/ecl/managed_load_balancer/v1/rules/requests.go +++ b/v2/ecl/managed_load_balancer/v1/rules/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -86,8 +88,8 @@ Create Rule type CreateOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns []string `json:"path_patterns,omitempty"` } @@ -96,29 +98,33 @@ type CreateOptsCondition struct { type CreateOpts struct { // - Name of the rule + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the rule + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the rule - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID string `json:"target_group_id,omitempty"` // - ID of the policy which the rule belongs to - // - Must be specified a policy which has a listener of which protocol is either `"http"` or `"https"` + // - Set ID of the policy which has a listener in which protocol is either `"http"` or `"https"` PolicyID string `json:"policy_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *CreateOptsCondition `json:"conditions,omitempty"` } @@ -155,7 +161,7 @@ Show Rule // ShowOpts represents options used to show a rule. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -195,13 +201,17 @@ Update Rule Attributes type UpdateOpts struct { // - Name of the rule + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the rule + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the rule - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -252,8 +262,8 @@ Create Staged Rule Configurations type CreateStagedOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns []string `json:"path_patterns,omitempty"` } @@ -262,15 +272,15 @@ type CreateStagedOptsCondition struct { type CreateStagedOpts struct { // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID string `json:"target_group_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *CreateStagedOptsCondition `json:"conditions,omitempty"` } @@ -321,8 +331,8 @@ Update Staged Rule Configurations type UpdateStagedOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns *[]string `json:"path_patterns,omitempty"` } @@ -331,15 +341,15 @@ type UpdateStagedOptsCondition struct { type UpdateStagedOpts struct { // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority *int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID *string `json:"target_group_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *UpdateStagedOptsCondition `json:"conditions,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/rules/results.go b/v2/ecl/managed_load_balancer/v1/rules/results.go index d917a54..e151343 100644 --- a/v2/ecl/managed_load_balancer/v1/rules/results.go +++ b/v2/ecl/managed_load_balancer/v1/rules/results.go @@ -145,13 +145,13 @@ type Rule struct { Conditions ConditionInResponse `json:"conditions,omitempty"` // - Running configurations of the rule - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the rule that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/system_updates/requests.go b/v2/ecl/managed_load_balancer/v1/system_updates/requests.go index 32d5ebc..9c7174e 100644 --- a/v2/ecl/managed_load_balancer/v1/system_updates/requests.go +++ b/v2/ecl/managed_load_balancer/v1/system_updates/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - URL of announcement for the system update (for example, Knowledge Center news) @@ -37,7 +39,7 @@ type ListOpts struct { // - Whether the system update can be applied to the load balancer Applicable bool `q:"applicable"` - // - When `true` is specified, only the latest resource is displayed + // - If `true` is set, only the latest resource is displayed Latest bool `q:"latest"` } diff --git a/v2/ecl/managed_load_balancer/v1/target_groups/requests.go b/v2/ecl/managed_load_balancer/v1/target_groups/requests.go index 5f98809..4287195 100644 --- a/v2/ecl/managed_load_balancer/v1/target_groups/requests.go +++ b/v2/ecl/managed_load_balancer/v1/target_groups/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -77,16 +79,19 @@ Create Target Group type CreateOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight int `json:"weight,omitempty"` } @@ -94,13 +99,17 @@ type CreateOptsMember struct { type CreateOpts struct { // - Name of the target group + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the target group + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the target group - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - ID of the load balancer which the target group belongs to @@ -143,7 +152,7 @@ Show Target Group // ShowOpts represents options used to show a target group. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -183,13 +192,17 @@ Update Target Group Attributes type UpdateOpts struct { // - Name of the target group + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the target group + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the target group - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -240,16 +253,19 @@ Create Staged Target Group Configurations type CreateStagedOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight int `json:"weight,omitempty"` } @@ -307,16 +323,19 @@ Update Staged Target Group Configurations type UpdateStagedOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port *int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight *int `json:"weight,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/target_groups/results.go b/v2/ecl/managed_load_balancer/v1/target_groups/results.go index 5911bf4..1c964c4 100644 --- a/v2/ecl/managed_load_balancer/v1/target_groups/results.go +++ b/v2/ecl/managed_load_balancer/v1/target_groups/results.go @@ -77,7 +77,7 @@ type MemberInResponse struct { Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, uses this parameter Weight int `json:"weight"` } @@ -137,13 +137,13 @@ type TargetGroup struct { Members []MemberInResponse `json:"members,omitempty"` // - Running configurations of the target group - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the target group that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go b/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go index 51ca552..95a3125 100644 --- a/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go +++ b/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Whether the TLS policy will be set `policy.tls_policy_id` when that is not specified diff --git a/v2/ecl/sss/v1/approval_requests/testing/fixtures.go b/v2/ecl/sss/v1/approval_requests/testing/fixtures.go index 0f16a39..33c490e 100644 --- a/v2/ecl/sss/v1/approval_requests/testing/fixtures.go +++ b/v2/ecl/sss/v1/approval_requests/testing/fixtures.go @@ -36,7 +36,7 @@ var listResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, @@ -66,7 +66,7 @@ var listResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, @@ -113,7 +113,7 @@ var firstApprovalRequest = ar.ApprovalRequest{ Descriptions: []ar.Description{ { Lang: "en", - Text: "approval request test", + Text: "approval resquest test", }, }, RequestUser: false, @@ -144,7 +144,7 @@ var secondApprovalRequest = ar.ApprovalRequest{ Descriptions: []ar.Description{ { Lang: "en", - Text: "approval request test", + Text: "approval resquest test", }, }, RequestUser: false, @@ -181,7 +181,7 @@ var getResponse = fmt.Sprintf(` "descriptions": [ { "lang": "en", - "text": "approval request test" + "text": "approval resquest test" } ], "request_user": false, diff --git a/v3/auth_options.go b/v3/auth_options.go deleted file mode 100644 index 9f442bf..0000000 --- a/v3/auth_options.go +++ /dev/null @@ -1,418 +0,0 @@ -package eclcloud - -/* -AuthOptions stores information needed to authenticate to an Enterprise Cloud. -You can populate one manually, or use a provider's AuthOptionsFromEnv() function -to read relevant information from the standard environment variables. Pass one -to a provider's AuthenticatedClient function to authenticate and obtain a -ProviderClient representing an active session on that provider. - -Its fields are the union of those recognized by each identity implementation and -provider. - -An example of manually providing authentication information: - - opts := eclcloud.AuthOptions{ - IdentityEndpoint: "https://keystone-{your_region}-ecl.api.ntt.com/v3/", - Username: "{api key}", - Password: "{api secret key}", - TenantID: "{tenant id}", - } - - provider, err := ecl.AuthenticatedClient(opts) - -An example of using AuthOptionsFromEnv(), where the environment variables can -be read from a file, such as a standard openrc file: - - opts, err := ecl.AuthOptionsFromEnv() - provider, err := ecl.AuthenticatedClient(opts) -*/ -type AuthOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed by - // all of the identity services, it will often be populated by a provider-level - // function. - // - // The IdentityEndpoint is typically referred to as the "auth_url" or - // "OS_AUTH_URL" in the information provided by the cloud operator. - IdentityEndpoint string `json:"-"` - - // Username is required if using Identity V2 API. Consult with your provider's - // control panel to discover your account's username. In Identity V3, either - // UserID or a combination of Username and DomainID or DomainName are needed. - Username string `json:"username,omitempty"` - UserID string `json:"-"` - - Password string `json:"password,omitempty"` - - // At most one of DomainID and DomainName must be provided if using Username - // with Identity V3. Otherwise, either are optional. - DomainID string `json:"-"` - DomainName string `json:"name,omitempty"` - - // The TenantID and TenantName fields are optional for the Identity V2 API. - // The same fields are known as project_id and project_name in the Identity - // V3 API, but are collected as TenantID and TenantName here in both cases. - // Some providers allow you to specify a TenantName instead of the TenantId. - // Some require both. Your provider's authentication policies will determine - // how these fields influence authentication. - // If DomainID or DomainName are provided, they will also apply to TenantName. - // It is not currently possible to authenticate with Username and a Domain - // and scope to a Project in a different Domain by using TenantName. To - // accomplish that, the ProjectID will need to be provided as the TenantID - // option. - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - - // AllowReauth should be set to true if you grant permission for Eclcloud to - // cache your credentials in memory, and to allow Eclcloud to attempt to - // re-authenticate automatically if/when your token expires. If you set it to - // false, it will not cache these settings, but re-authentication will not be - // possible. This setting defaults to false. - // - // NOTE: The reauth function will try to re-authenticate endlessly if left - // unchecked. The way to limit the number of attempts is to provide a custom - // HTTP client to the provider client and provide a transport that implements - // the RoundTripper interface and stores the number of failed retries. For an - // example of this, see here: - // https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311 - AllowReauth bool `json:"-"` - - // TokenID allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenID string `json:"-"` - - // Scope determines the scoping of the authentication request. - Scope *AuthScope `json:"-"` - - // Authentication through Application Credentials requires supplying name, project and secret - // For project we can use TenantID - ApplicationCredentialID string `json:"-"` - ApplicationCredentialName string `json:"-"` - ApplicationCredentialSecret string `json:"-"` -} - -// AuthScope allows a created token to be limited to a specific domain or project. -type AuthScope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string -} - -// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder -// interface in the v2 tokens package -func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { - // Populate the request map. - authMap := make(map[string]interface{}) - - if opts.Username != "" { - if opts.Password != "" { - authMap["passwordCredentials"] = map[string]interface{}{ - "username": opts.Username, - "password": opts.Password, - } - } else { - return nil, ErrMissingInput{Argument: "Password"} - } - } else if opts.TokenID != "" { - authMap["token"] = map[string]interface{}{ - "id": opts.TokenID, - } - } else { - return nil, ErrMissingInput{Argument: "Username"} - } - - if opts.TenantID != "" { - authMap["tenantId"] = opts.TenantID - } - if opts.TenantName != "" { - authMap["tenantName"] = opts.TenantName - } - - return map[string]interface{}{"auth": authMap}, nil -} - -func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { - type domainReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - } - - type projectReq struct { - Domain *domainReq `json:"domain,omitempty"` - Name *string `json:"name,omitempty"` - ID *string `json:"id,omitempty"` - } - - type userReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Password string `json:"password,omitempty"` - Domain *domainReq `json:"domain,omitempty"` - } - - type passwordReq struct { - User userReq `json:"user"` - } - - type tokenReq struct { - ID string `json:"id"` - } - - type applicationCredentialReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - User *userReq `json:"user,omitempty"` - Secret *string `json:"secret,omitempty"` - } - - type identityReq struct { - Methods []string `json:"methods"` - Password *passwordReq `json:"password,omitempty"` - Token *tokenReq `json:"token,omitempty"` - ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"` - } - - type authReq struct { - Identity identityReq `json:"identity"` - } - - type request struct { - Auth authReq `json:"auth"` - } - - // Populate the request structure based on the provided arguments. Create and return an error - // if insufficient or incompatible information is present. - var req request - var userRequest userReq - - if opts.Password == "" { - if opts.TokenID != "" { - // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication - // parameters. - if opts.Username != "" { - return nil, ErrUsernameWithToken{} - } - if opts.UserID != "" { - return nil, ErrUserIDWithToken{} - } - if opts.DomainID != "" { - return nil, ErrDomainIDWithToken{} - } - if opts.DomainName != "" { - return nil, ErrDomainNameWithToken{} - } - - // Configure the request for Token authentication. - req.Auth.Identity.Methods = []string{"token"} - req.Auth.Identity.Token = &tokenReq{ - ID: opts.TokenID, - } - - } else if opts.ApplicationCredentialID != "" { - // Configure the request for ApplicationCredentialID authentication. - // There are three kinds of possible application_credential requests - // 1. application_credential id + secret - // 2. application_credential name + secret + user_id - // 3. application_credential name + secret + username + domain_id / domain_name - if opts.ApplicationCredentialSecret == "" { - return nil, ErrAppCredMissingSecret{} - } - req.Auth.Identity.Methods = []string{"application_credential"} - req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ - ID: &opts.ApplicationCredentialID, - Secret: &opts.ApplicationCredentialSecret, - } - } else if opts.ApplicationCredentialName != "" { - if opts.ApplicationCredentialSecret == "" { - return nil, ErrAppCredMissingSecret{} - } - // make sure that only one of DomainName or DomainID were provided - if opts.DomainID == "" && opts.DomainName == "" { - return nil, ErrDomainIDOrDomainName{} - } - req.Auth.Identity.Methods = []string{"application_credential"} - if opts.DomainID != "" { - userRequest = userReq{ - Name: &opts.Username, - Domain: &domainReq{ID: &opts.DomainID}, - } - } else if opts.DomainName != "" { - userRequest = userReq{ - Name: &opts.Username, - Domain: &domainReq{Name: &opts.DomainName}, - } - } - req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ - Name: &opts.ApplicationCredentialName, - User: &userRequest, - Secret: &opts.ApplicationCredentialSecret, - } - } else { - // If no password or token ID or ApplicationCredential are available, authentication can't continue. - return nil, ErrMissingPassword{} - } - } else { - // Password authentication. - req.Auth.Identity.Methods = []string{"password"} - - // At least one of Username and UserID must be specified. - if opts.Username == "" && opts.UserID == "" { - return nil, ErrUsernameOrUserID{} - } - - if opts.Username != "" { - // If Username is provided, UserID may not be provided. - if opts.UserID != "" { - return nil, ErrUsernameOrUserID{} - } - - // Either DomainID or DomainName must also be specified. - if opts.DomainID == "" && opts.DomainName == "" { - return nil, ErrDomainIDOrDomainName{} - } - - if opts.DomainID != "" { - if opts.DomainName != "" { - return nil, ErrDomainIDOrDomainName{} - } - - // Configure the request for Username and Password authentication with a DomainID. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: opts.Password, - Domain: &domainReq{ID: &opts.DomainID}, - }, - } - } - - if opts.DomainName != "" { - // Configure the request for Username and Password authentication with a DomainName. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: opts.Password, - Domain: &domainReq{Name: &opts.DomainName}, - }, - } - } - } - - if opts.UserID != "" { - // If UserID is specified, neither DomainID nor DomainName may be. - if opts.DomainID != "" { - return nil, ErrDomainIDWithUserID{} - } - if opts.DomainName != "" { - return nil, ErrDomainNameWithUserID{} - } - - // Configure the request for UserID and Password authentication. - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ID: &opts.UserID, Password: opts.Password}, - } - } - } - - b, err := BuildRequestBody(req, "") - if err != nil { - return nil, err - } - - if len(scope) != 0 { - b["auth"].(map[string]interface{})["scope"] = scope - } - - return b, nil -} - -func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - // For backwards compatibility. - // If AuthOptions.Scope was not set, try to determine it. - // This works well for common scenarios. - if opts.Scope == nil { - opts.Scope = new(AuthScope) - if opts.TenantID != "" { - opts.Scope.ProjectID = opts.TenantID - } else { - if opts.TenantName != "" { - opts.Scope.ProjectName = opts.TenantName - opts.Scope.DomainID = opts.DomainID - opts.Scope.DomainName = opts.DomainName - } - } - } - - if opts.Scope.ProjectName != "" { - // ProjectName provided: either DomainID or DomainName must also be supplied. - // ProjectID may not be supplied. - if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" { - return nil, ErrScopeDomainIDOrDomainName{} - } - if opts.Scope.ProjectID != "" { - return nil, ErrScopeProjectIDOrProjectName{} - } - - if opts.Scope.DomainID != "" { - // ProjectName + DomainID - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"id": &opts.Scope.DomainID}, - }, - }, nil - } - - if opts.Scope.DomainName != "" { - // ProjectName + DomainName - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"name": &opts.Scope.DomainName}, - }, - }, nil - } - } else if opts.Scope.ProjectID != "" { - // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if opts.Scope.DomainID != "" { - return nil, ErrScopeProjectIDAlone{} - } - if opts.Scope.DomainName != "" { - return nil, ErrScopeProjectIDAlone{} - } - - // ProjectID - return map[string]interface{}{ - "project": map[string]interface{}{ - "id": &opts.Scope.ProjectID, - }, - }, nil - } else if opts.Scope.DomainID != "" { - // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - if opts.Scope.DomainName != "" { - return nil, ErrScopeDomainIDOrDomainName{} - } - - // DomainID - return map[string]interface{}{ - "domain": map[string]interface{}{ - "id": &opts.Scope.DomainID, - }, - }, nil - } else if opts.Scope.DomainName != "" { - // DomainName - return map[string]interface{}{ - "domain": map[string]interface{}{ - "name": &opts.Scope.DomainName, - }, - }, nil - } - - return nil, nil -} - -func (opts AuthOptions) CanReauth() bool { - return opts.AllowReauth -} diff --git a/v3/doc.go b/v3/doc.go deleted file mode 100644 index 58918f9..0000000 --- a/v3/doc.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Package eclcloud provides interface to Enterprise Cloud. -The library has a three-level hierarchy: providers, services, and -resources. - -Authenticating with Providers - -Provider structs represent the cloud providers that offer and manage a -collection of services. You will generally want to create one Provider -client per Enterprise Cloud. - -Use your Enterprise Cloud credentials to create a Provider client. The -IdentityEndpoint is typically referred to as "auth_url" or "OS_AUTH_URL" in -information provided by the cloud operator. Additionally, the cloud may refer to -TenantID or TenantName as project_id and project_name. Credentials are -specified like so: - - opts := eclcloud.AuthOptions{ - IdentityEndpoint: "https://keystone-{region}-ecl.api.ntt.com/v3/", - Username: "{api key}", - Password: "{api secret key}", - TenantID: "{tenant_id}", - } - - provider, err := ecl.AuthenticatedClient(opts) - -You may also use the ecl.AuthOptionsFromEnv() helper function. This -function reads in standard environment variables frequently found in an -Enterprise Cloud `openrc` file. Again note that Gophercloud currently uses "tenant" -instead of "project". - - opts, err := ecl.AuthOptionsFromEnv() - provider, err := ecl.AuthenticatedClient(opts) - -Service Clients - -Service structs are specific to a provider and handle all of the logic and -operations for a particular Enterprise Cloud service. Examples of services include: -Compute, Object Storage, Block Storage. In order to define one, you need to -pass in the parent provider, like so: - - opts := eclcloud.EndpointOpts{Region: "RegionOne"} - - client := ecl.NewComputeV2(provider, opts) - -Resources - -Resource structs are the domain models that services make use of in order -to work with and represent the state of API resources: - - server, err := servers.Get(client, "{serverId}").Extract() - -Intermediate Result structs are returned for API operations, which allow -generic access to the HTTP headers, response body, and any errors associated -with the network transaction. To turn a result into a usable resource struct, -you must call the Extract method which is chained to the response, or an -Extract function from an applicable extension: - - result := servers.Get(client, "{serverId}") - - // Attempt to extract the disk configuration from the OS-DCF disk config - // extension: - config, err := diskconfig.ExtractGet(result) - -All requests that enumerate a collection return a Pager struct that is used to -iterate through the results one page at a time. Use the EachPage method on that -Pager to handle each successive Page in a closure, then use the appropriate -extraction method from that request's package to interpret that Page as a slice -of results: - - err := servers.List(client, nil).EachPage(func (page pagination.Page) (bool, error) { - s, err := servers.ExtractServers(page) - if err != nil { - return false, err - } - - // Handle the []servers.Server slice. - - // Return "false" or an error to prematurely stop fetching new pages. - return true, nil - }) - -If you want to obtain the entire collection of pages without doing any -intermediary processing on each page, you can use the AllPages method: - - allPages, err := servers.List(client, nil).AllPages() - allServers, err := servers.ExtractServers(allPages) - -This top-level package contains utility functions and data types that are used -throughout the provider and service packages. Of particular note for end users -are the AuthOptions and EndpointOpts structs. -*/ -package eclcloud diff --git a/v3/ecl/auth_env.go b/v3/ecl/auth_env.go deleted file mode 100644 index c2a7faa..0000000 --- a/v3/ecl/auth_env.go +++ /dev/null @@ -1,97 +0,0 @@ -package ecl - -import ( - "github.com/nttcom/eclcloud/v3" - "os" -) - -var nilOptions = eclcloud.AuthOptions{} - -/* -AuthOptionsFromEnv fills out an identity.AuthOptions structure with the -settings found on the various Enterprise Cloud OS_* environment variables. - -The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME, -OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME. - -Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings, -or an error will result. OS_TENANT_ID, OS_TENANT_NAME, OS_PROJECT_ID, and -OS_PROJECT_NAME are optional. - -OS_TENANT_ID and OS_TENANT_NAME are mutually exclusive to OS_PROJECT_ID and -OS_PROJECT_NAME. If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will -still be referred as "tenant" in eclcloud. - -To use this function, first set the OS_* environment variables (for example, -by sourcing an `openrc` file), then: - - opts, err := ecl.AuthOptionsFromEnv() - provider, err := ecl.AuthenticatedClient(opts) -*/ -func AuthOptionsFromEnv() (eclcloud.AuthOptions, error) { - authURL := os.Getenv("OS_AUTH_URL") - username := os.Getenv("OS_USERNAME") - userID := os.Getenv("OS_USERID") - password := os.Getenv("OS_PASSWORD") - tenantID := os.Getenv("OS_TENANT_ID") - tenantName := os.Getenv("OS_TENANT_NAME") - domainID := os.Getenv("OS_DOMAIN_ID") - domainName := os.Getenv("OS_DOMAIN_NAME") - applicationCredentialID := os.Getenv("OS_APPLICATION_CREDENTIAL_ID") - applicationCredentialName := os.Getenv("OS_APPLICATION_CREDENTIAL_NAME") - applicationCredentialSecret := os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET") - - // If OS_PROJECT_ID is set, overwrite tenantID with the value. - if v := os.Getenv("OS_PROJECT_ID"); v != "" { - tenantID = v - } - - // If OS_PROJECT_NAME is set, overwrite tenantName with the value. - if v := os.Getenv("OS_PROJECT_NAME"); v != "" { - tenantName = v - } - - if authURL == "" { - err := eclcloud.ErrMissingEnvironmentVariable{ - EnvironmentVariable: "OS_AUTH_URL", - } - return nilOptions, err - } - - if username == "" && userID == "" { - err := eclcloud.ErrMissingAnyoneOfEnvironmentVariables{ - EnvironmentVariables: []string{"OS_USERNAME", "OS_USERID"}, - } - return nilOptions, err - } - - if password == "" && applicationCredentialID == "" && applicationCredentialName == "" { - err := eclcloud.ErrMissingEnvironmentVariable{ - EnvironmentVariable: "OS_PASSWORD", - } - return nilOptions, err - } - - if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" { - err := eclcloud.ErrMissingEnvironmentVariable{ - EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET", - } - return nilOptions, err - } - - ao := eclcloud.AuthOptions{ - IdentityEndpoint: authURL, - UserID: userID, - Username: username, - Password: password, - TenantID: tenantID, - TenantName: tenantName, - DomainID: domainID, - DomainName: domainName, - ApplicationCredentialID: applicationCredentialID, - ApplicationCredentialName: applicationCredentialName, - ApplicationCredentialSecret: applicationCredentialSecret, - } - - return ao, nil -} diff --git a/v3/ecl/baremetal/v2/availabilityzones/doc.go b/v3/ecl/baremetal/v2/availabilityzones/doc.go deleted file mode 100644 index 6619157..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -Package availabilityzones provides the ability to get lists and detailed -availability zone information and to extend a server result with -availability zone information. - -Example of Get Availability Zone Information - - allPages, err := availabilityzones.List(client).AllPages() - if err != nil { - panic(err) - } - - availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages) - if err != nil { - panic(err) - } - - for _, zoneInfo := range availabilityZoneInfo { - fmt.Printf("%+v\n", zoneInfo) - } -*/ -package availabilityzones diff --git a/v3/ecl/baremetal/v2/availabilityzones/requests.go b/v3/ecl/baremetal/v2/availabilityzones/requests.go deleted file mode 100644 index 247bbd2..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/requests.go +++ /dev/null @@ -1,13 +0,0 @@ -package availabilityzones - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List will return the existing availability zones. -func List(client *eclcloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return AvailabilityZonePage{pagination.SinglePageBase(r)} - }) -} diff --git a/v3/ecl/baremetal/v2/availabilityzones/results.go b/v3/ecl/baremetal/v2/availabilityzones/results.go deleted file mode 100644 index 5f6ca32..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/results.go +++ /dev/null @@ -1,37 +0,0 @@ -package availabilityzones - -import ( - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ZoneState represents the current state of the availability zone. -type ZoneState struct { - // Returns true if the availability zone is available - Available bool `json:"available"` -} - -// AvailabilityZone contains all the information associated with an ECL -// AvailabilityZone. -type AvailabilityZone struct { - ZoneName string `json:"zoneName"` - ZoneState ZoneState `json:"zoneState"` - Hosts interface{} `json:"hosts"` -} - -// AvailabilityZonePage stores a single page of all AvailabilityZone results -// from a List call. -// Use the ExtractAvailabilityZones function to convert the results to a slice of -// AvailabilityZones. -type AvailabilityZonePage struct { - pagination.SinglePageBase -} - -// ExtractAvailabilityZones returns a slice of AvailabilityZones contained in a -// single page of results. -func ExtractAvailabilityZones(r pagination.Page) ([]AvailabilityZone, error) { - var s struct { - AvailabilityZoneInfo []AvailabilityZone `json:"availabilityZoneInfo"` - } - err := (r.(AvailabilityZonePage)).ExtractInto(&s) - return s.AvailabilityZoneInfo, err -} diff --git a/v3/ecl/baremetal/v2/availabilityzones/testing/doc.go b/v3/ecl/baremetal/v2/availabilityzones/testing/doc.go deleted file mode 100644 index 59fc76c..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains baremetal availability zone unit tests -package testing diff --git a/v3/ecl/baremetal/v2/availabilityzones/testing/fixtures.go b/v3/ecl/baremetal/v2/availabilityzones/testing/fixtures.go deleted file mode 100644 index 0677ebd..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/testing/fixtures.go +++ /dev/null @@ -1,36 +0,0 @@ -package testing - -import ( - az "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/availabilityzones" -) - -const getResponse = ` -{ - "availabilityZoneInfo": [{ - "zoneState": { - "available": true - }, - "hosts": null, - "zoneName": "zone1-groupa" - }, { - "zoneState": { - "available": true - }, - "hosts": null, - "zoneName": "zone1-groupb" - }] -} -` - -var azResult = []az.AvailabilityZone{ - { - Hosts: nil, - ZoneName: "zone1-groupa", - ZoneState: az.ZoneState{Available: true}, - }, - { - Hosts: nil, - ZoneName: "zone1-groupb", - ZoneState: az.ZoneState{Available: true}, - }, -} diff --git a/v3/ecl/baremetal/v2/availabilityzones/testing/requests_test.go b/v3/ecl/baremetal/v2/availabilityzones/testing/requests_test.go deleted file mode 100644 index df6e771..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/testing/requests_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - az "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/availabilityzones" - th "github.com/nttcom/eclcloud/v3/testhelper" - - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListAvailabilityZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - allPages, err := az.List(fakeclient.ServiceClient()).AllPages() - th.AssertNoErr(t, err) - - actual, err := az.ExtractAvailabilityZones(allPages) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, azResult, actual) -} diff --git a/v3/ecl/baremetal/v2/availabilityzones/urls.go b/v3/ecl/baremetal/v2/availabilityzones/urls.go deleted file mode 100644 index e62fdd9..0000000 --- a/v3/ecl/baremetal/v2/availabilityzones/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package availabilityzones - -import "github.com/nttcom/eclcloud/v3" - -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("os-availability-zone") -} diff --git a/v3/ecl/baremetal/v2/flavors/doc.go b/v3/ecl/baremetal/v2/flavors/doc.go deleted file mode 100644 index 23dbe2b..0000000 --- a/v3/ecl/baremetal/v2/flavors/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Package flavors contains functionality for working with -ECL Baremetal Server's flavor resources. - -Example to list flavors - - listOpts := flavors.ListOpts{ - TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", - } - - allPages, err := flavors.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allFlavors, err := flavors.ExtractFlavors(allPages) - if err != nil { - panic(err) - } - - for _, flavor := range allFlavors { - fmt.Printf("%+v", flavor) - } -*/ -package flavors diff --git a/v3/ecl/baremetal/v2/flavors/requests.go b/v3/ecl/baremetal/v2/flavors/requests.go deleted file mode 100644 index 640b476..0000000 --- a/v3/ecl/baremetal/v2/flavors/requests.go +++ /dev/null @@ -1,88 +0,0 @@ -package flavors - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Get retrieves the flavor with the provided ID. -// To extract the Flavor object from the response, -// call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToFlavorListQuery() (string, error) -} - -// ListOpts holds options for listing flavors. -// It is passed to the flavors.List function. -type ListOpts struct { - // Now there are no definition as query params in API specification - // But do not remove this struct in future specification change. -} - -// ToFlavorListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToFlavorListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns Flavor optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToFlavorListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return FlavorPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// IDFromName is a convenience function that returns a flavor's ID given its -// name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - allPages, err := List(client, nil).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractFlavors(allPages) - if err != nil { - return "", err - } - - for _, f := range all { - if f.Name == name { - count++ - id = f.ID - } - } - - switch count { - case 0: - err := &eclcloud.ErrResourceNotFound{} - err.ResourceType = "flavor" - err.Name = name - return "", err - case 1: - return id, nil - default: - err := &eclcloud.ErrMultipleResourcesFound{} - err.ResourceType = "flavor" - err.Name = name - err.Count = count - return "", err - } -} diff --git a/v3/ecl/baremetal/v2/flavors/results.go b/v3/ecl/baremetal/v2/flavors/results.go deleted file mode 100644 index 6ceda50..0000000 --- a/v3/ecl/baremetal/v2/flavors/results.go +++ /dev/null @@ -1,79 +0,0 @@ -package flavors - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the result of Get operations. Call its Extract method to -// interpret it as a Flavor. -type GetResult struct { - commonResult -} - -// Extract provides access to the individual Flavor returned by -// the Get and functions. -func (r commonResult) Extract() (*Flavor, error) { - var s struct { - Flavor *Flavor `json:"flavor"` - } - err := r.ExtractInto(&s) - return s.Flavor, err -} - -// Flavor represent (virtual) hardware configurations for server resources -// in a region. -type Flavor struct { - // ID is the flavor's unique ID. - ID string `json:"id"` - - // Name is the name of the flavor. - Name string `json:"name"` - - // Disk is the amount of root disk, measured in GB. - Disk int `json:"disk"` - - // RAM is the amount of memory, measured in MB. - RAM int `json:"ram"` - - // VCPUs indicates how many (virtual) CPUs are available for this flavor. - VCPUs int `json:"vcpus"` -} - -// FlavorPage contains a single page of all flavors from a ListDetails call. -type FlavorPage struct { - pagination.LinkedPageBase -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (page FlavorPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"flavors_links"` - } - err := page.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty determines if a FlavorPage contains any results. -func (page FlavorPage) IsEmpty() (bool, error) { - flavors, err := ExtractFlavors(page) - return len(flavors) == 0, err -} - -// ExtractFlavors provides access to the list of flavors in a page acquired -// from the ListDetail operation. -func ExtractFlavors(r pagination.Page) ([]Flavor, error) { - var s struct { - Flavors []Flavor `json:"flavors"` - } - err := (r.(FlavorPage)).ExtractInto(&s) - return s.Flavors, err -} diff --git a/v3/ecl/baremetal/v2/flavors/testing/doc.go b/v3/ecl/baremetal/v2/flavors/testing/doc.go deleted file mode 100644 index 159b3e8..0000000 --- a/v3/ecl/baremetal/v2/flavors/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains baremetal flavor unit tests -package testing diff --git a/v3/ecl/baremetal/v2/flavors/testing/fixtures.go b/v3/ecl/baremetal/v2/flavors/testing/fixtures.go deleted file mode 100644 index 90a766c..0000000 --- a/v3/ecl/baremetal/v2/flavors/testing/fixtures.go +++ /dev/null @@ -1,86 +0,0 @@ -package testing - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/flavors" -) - -var listResponse = fmt.Sprintf(` -{ - "flavors": [ - { - "id": "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "name": "General Purpose 1", - "vcpus": 4, - "ram": 32768, - "disk": 550, - "links": [ - { - "href": "https://baremetal-server.ntt/v2/1bc271e7a8af4d988ff91612f5b122f8/flavors/cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "rel": "self" - }, - { - "href": "https://baremetal-server.ntt/1bc271e7a8af4d988ff91612f5b122f8/flavors/cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "rel": "bookmark" - } - ] - }, - { - "id": "303b4993-cf29-4301-abd0-99512b5413a5", - "name": "General Purpose 2", - "vcpus": 8, - "ram": 262144, - "disk": 3950, - "links": [ - { - "href": "https://baremetal-server.ntt/v2/1bc271e7a8af4d988ff91612f5b122f8/flavors/303b4993-cf29-4301-abd0-99512b5413a5", - "rel": "self" - }, - { - "href": "https://baremetal-server.ntt/1bc271e7a8af4d988ff91612f5b122f8/flavors/303b4993-cf29-4301-abd0-99512b5413a5", - "rel": "bookmark" - } - ] - } - ] -}`) - -var getResponse = fmt.Sprintf(` -{ - "flavor": { - "id": "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "links": [ - { - "href": "https://baremetal-server.ntt/v2/1bc271e7a8af4d988ff91612f5b122f8/flavors/cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "rel": "self" - }, - { - "href": "https://baremetal-server.ntt/1bc271e7a8af4d988ff91612f5b122f8/flavors/cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - "rel": "bookmark" - } - ], - "name": "General Purpose 1", - "vcpus": 4, - "ram": 32768, - "disk": 550 - } -}`) - -var expectedFlavors = []flavors.Flavor{expectedFlavor1, expectedFlavor2} - -var expectedFlavor1 = flavors.Flavor{ - ID: "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79", - Name: "General Purpose 1", - Disk: 550, - RAM: 32768, - VCPUs: 4, -} - -var expectedFlavor2 = flavors.Flavor{ - ID: "303b4993-cf29-4301-abd0-99512b5413a5", - Name: "General Purpose 2", - Disk: 3950, - RAM: 262144, - VCPUs: 8, -} diff --git a/v3/ecl/baremetal/v2/flavors/testing/requests_test.go b/v3/ecl/baremetal/v2/flavors/testing/requests_test.go deleted file mode 100644 index 4d51e70..0000000 --- a/v3/ecl/baremetal/v2/flavors/testing/requests_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/flavors" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListFlavors(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := flavors.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := flavors.ExtractFlavors(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedFlavors, actual) - return true, nil - }) - - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListFlavorsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := flavors.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - - allFlavors, err := flavors.ExtractFlavors(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allFlavors)) -} - -func TestGetFlavor(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/flavors/%s", "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79") - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := flavors.Get(fakeclient.ServiceClient(), "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedFlavor1, actual) -} diff --git a/v3/ecl/baremetal/v2/flavors/urls.go b/v3/ecl/baremetal/v2/flavors/urls.go deleted file mode 100644 index 430a898..0000000 --- a/v3/ecl/baremetal/v2/flavors/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package flavors - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("flavors", "detail") -} diff --git a/v3/ecl/baremetal/v2/keypairs/doc.go b/v3/ecl/baremetal/v2/keypairs/doc.go deleted file mode 100644 index dd95992..0000000 --- a/v3/ecl/baremetal/v2/keypairs/doc.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Package keypairs provides the ability to manage key pairs. - -Example to List Key Pairs - - allPages, err := keypairs.List(client).AllPages() - if err != nil { - panic(err) - } - - allKeyPairs, err := keypairs.ExtractKeyPairs(allPages) - if err != nil { - panic(err) - } - - for _, kp := range allKeyPairs { - fmt.Printf("%+v\n", kp) - } - -Example to Create a Key Pair - - createOpts := keypairs.CreateOpts{ - Name: "keypair-name", - } - - keypair, err := keypairs.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v", keypair) - -Example to Import a Key Pair - - createOpts := keypairs.CreateOpts{ - Name: "keypair-name", - PublicKey: "public-key", - } - - keypair, err := keypairs.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Key Pair - - err := keypairs.Delete(client, "keypair-name").ExtractErr() - if err != nil { - panic(err) - } -*/ -package keypairs diff --git a/v3/ecl/baremetal/v2/keypairs/requests.go b/v3/ecl/baremetal/v2/keypairs/requests.go deleted file mode 100644 index 2ce786c..0000000 --- a/v3/ecl/baremetal/v2/keypairs/requests.go +++ /dev/null @@ -1,60 +0,0 @@ -package keypairs - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List returns a Pager that allows you to iterate over a collection of KeyPairs. -func List(client *eclcloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return KeyPairPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToKeyPairCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies KeyPair creation or import parameters. -type CreateOpts struct { - // Name is a friendly name to refer to this KeyPair in other services. - Name string `json:"name" required:"true"` - - // PublicKey [optional] is a pregenerated OpenSSH-formatted public key. - // If provided, this key will be imported and no new key will be created. - PublicKey string `json:"public_key,omitempty"` -} - -// ToKeyPairCreateMap constructs a request body from CreateOpts. -func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "keypair") -} - -// Create requests the creation of a new KeyPair on the server, or to import a -// pre-existing keypair. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToKeyPairCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get returns public data about a previously uploaded KeyPair. -func Get(client *eclcloud.ServiceClient, name string) (r GetResult) { - _, r.Err = client.Get(getURL(client, name), &r.Body, nil) - return -} - -// Delete requests the deletion of a previous stored KeyPair from the server. -func Delete(client *eclcloud.ServiceClient, name string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, name), nil) - return -} diff --git a/v3/ecl/baremetal/v2/keypairs/results.go b/v3/ecl/baremetal/v2/keypairs/results.go deleted file mode 100644 index d3d1804..0000000 --- a/v3/ecl/baremetal/v2/keypairs/results.go +++ /dev/null @@ -1,84 +0,0 @@ -package keypairs - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// KeyPair is an SSH key known to the Enterprise Cloud that is available to be -// injected into servers. -type KeyPair struct { - // Name is used to refer to this keypair from other services within this - // region. - Name string `json:"name"` - - // Fingerprint is a short sequence of bytes that can be used to authenticate - // or validate a longer public key. - Fingerprint string `json:"fingerprint"` - - // PublicKey is the public key from this pair, in OpenSSH format. - // "ssh-rsa AAAAB3Nz..." - PublicKey string `json:"public_key"` - - // PrivateKey is the private key from this pair, in PEM format. - // "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..." - // It is only present if this KeyPair was just returned from a Create call. - PrivateKey string `json:"private_key"` - - // UserID is the user who owns this KeyPair. - UserID string `json:"user_id"` -} - -// KeyPairPage stores a single page of all KeyPair results from a List call. -// Use the ExtractKeyPairs function to convert the results to a slice of -// KeyPairs. -type KeyPairPage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a KeyPairPage is empty. -func (page KeyPairPage) IsEmpty() (bool, error) { - ks, err := ExtractKeyPairs(page) - return len(ks) == 0, err -} - -// ExtractKeyPairs interprets a page of results as a slice of KeyPairs. -func ExtractKeyPairs(r pagination.Page) ([]KeyPair, error) { - var s struct { - KeyPairs []KeyPair `json:"keypairs"` - } - err := (r.(KeyPairPage)).ExtractInto(&s) - return s.KeyPairs, err -} - -type keyPairResult struct { - eclcloud.Result -} - -// Extract is a method that attempts to interpret any KeyPair resource response -// as a KeyPair struct. -func (r keyPairResult) Extract() (*KeyPair, error) { - var s struct { - KeyPair *KeyPair `json:"keypair"` - } - err := r.ExtractInto(&s) - return s.KeyPair, err -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a KeyPair. -type CreateResult struct { - keyPairResult -} - -// GetResult is the response from a Get operation. Call its Extract method to -// interpret it as a KeyPair. -type GetResult struct { - keyPairResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/baremetal/v2/keypairs/testing/doc.go b/v3/ecl/baremetal/v2/keypairs/testing/doc.go deleted file mode 100644 index bf23f88..0000000 --- a/v3/ecl/baremetal/v2/keypairs/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains keypairs unit tests -package testing diff --git a/v3/ecl/baremetal/v2/keypairs/testing/fixtures.go b/v3/ecl/baremetal/v2/keypairs/testing/fixtures.go deleted file mode 100644 index 2a59706..0000000 --- a/v3/ecl/baremetal/v2/keypairs/testing/fixtures.go +++ /dev/null @@ -1,92 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/keypairs" -) - -const listOutput = ` -{ - "keypairs": [ - { - "fingerprint": "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a", - "name": "firstkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n" - }, - { - "fingerprint": "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - "name": "secondkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n" - } - ] -} -` - -const createRequest = `{ "keypair": { "name": "createdkey" } }` -const createResponse = ` -{ - "keypair": { - "fingerprint": "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - "name": "createdkey", - "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7\nDUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ\n9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5QIDAQAB\nAoGAE5XO1mDhORy9COvsg+kYPUhB1GsCYxh+v88wG7HeFDKBY6KUc/Kxo6yoGn5T\nTjRjekyi2KoDZHz4VlIzyZPwFS4I1bf3oCunVoAKzgLdmnTtvRNMC5jFOGc2vUgP\n9bSyRj3S1R4ClVk2g0IDeagko/jc8zzLEYuIK+fbkds79YECQQDt3vcevgegnkga\ntF4NsDmmBPRkcSHCqrANP/7vFcBQN3czxeYYWX3DK07alu6GhH1Y4sHbdm616uU0\nll7xbDzxAkEAzAtN2IyftNygV2EGiaGgqLyo/tD9+Vui2qCQplqe4jvWh/5Sparl\nOjmKo+uAW+hLrLVMnHzRWxbWU8hirH5FNQJATO+ZxCK4etXXAnQmG41NCAqANWB2\nB+2HJbH2NcQ2QHvAHUm741JGn/KI/aBlo7KEjFRDWUVUB5ji64BbUwCsMQJBAIku\nLGcjnBf/oLk+XSPZC2eGd2Ph5G5qYmH0Q2vkTx+wtTn3DV+eNsDfgMtWAJVJ5t61\ngU1QSXyhLPVlKpnnxuUCQC+xvvWjWtsLaFtAsZywJiqLxQzHts8XLGZptYJ5tLWV\nrtmYtBcJCN48RrgQHry/xWYeA4K/AFQpXfNPgprQ96Q=\n-----END RSA PRIVATE KEY-----\n", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", - "user_id": "fake" - } -} -` - -const getResponse = ` -{ - "keypair": { - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n", - "name": "firstkey", - "fingerprint": "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a" - } -} -` - -const importRequest = ` -{ - "keypair": { - "name": "importedkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova" - } -}` -const importResponse = ` -{ - "keypair": { - "fingerprint": "1e:2c:9b:56:79:4b:45:77:f9:ca:7a:98:2c:b0:d5:3c", - "name": "importedkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - "user_id": "fake" - } -} -` - -var firstKeyPair = keypairs.KeyPair{ - Name: "firstkey", - Fingerprint: "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n", -} - -var secondKeyPair = keypairs.KeyPair{ - Name: "secondkey", - Fingerprint: "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", -} - -var expectedKeyPairSlice = []keypairs.KeyPair{firstKeyPair, secondKeyPair} - -var createdKeyPair = keypairs.KeyPair{ - Name: "createdkey", - Fingerprint: "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", - PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7\nDUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ\n9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5QIDAQAB\nAoGAE5XO1mDhORy9COvsg+kYPUhB1GsCYxh+v88wG7HeFDKBY6KUc/Kxo6yoGn5T\nTjRjekyi2KoDZHz4VlIzyZPwFS4I1bf3oCunVoAKzgLdmnTtvRNMC5jFOGc2vUgP\n9bSyRj3S1R4ClVk2g0IDeagko/jc8zzLEYuIK+fbkds79YECQQDt3vcevgegnkga\ntF4NsDmmBPRkcSHCqrANP/7vFcBQN3czxeYYWX3DK07alu6GhH1Y4sHbdm616uU0\nll7xbDzxAkEAzAtN2IyftNygV2EGiaGgqLyo/tD9+Vui2qCQplqe4jvWh/5Sparl\nOjmKo+uAW+hLrLVMnHzRWxbWU8hirH5FNQJATO+ZxCK4etXXAnQmG41NCAqANWB2\nB+2HJbH2NcQ2QHvAHUm741JGn/KI/aBlo7KEjFRDWUVUB5ji64BbUwCsMQJBAIku\nLGcjnBf/oLk+XSPZC2eGd2Ph5G5qYmH0Q2vkTx+wtTn3DV+eNsDfgMtWAJVJ5t61\ngU1QSXyhLPVlKpnnxuUCQC+xvvWjWtsLaFtAsZywJiqLxQzHts8XLGZptYJ5tLWV\nrtmYtBcJCN48RrgQHry/xWYeA4K/AFQpXfNPgprQ96Q=\n-----END RSA PRIVATE KEY-----\n", - UserID: "fake", -} - -var importedKeyPair = keypairs.KeyPair{ - Name: "importedkey", - Fingerprint: "1e:2c:9b:56:79:4b:45:77:f9:ca:7a:98:2c:b0:d5:3c", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - UserID: "fake", -} diff --git a/v3/ecl/baremetal/v2/keypairs/testing/requests_test.go b/v3/ecl/baremetal/v2/keypairs/testing/requests_test.go deleted file mode 100644 index ff3abaf..0000000 --- a/v3/ecl/baremetal/v2/keypairs/testing/requests_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/keypairs" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listOutput) - }) - - count := 0 - err := keypairs.List(fakeclient.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := keypairs.ExtractKeyPairs(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedKeyPairSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreateKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - actual, err := keypairs.Create(fakeclient.ServiceClient(), keypairs.CreateOpts{ - Name: "createdkey", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdKeyPair, actual) -} - -func TestImportKeypair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, importRequest) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, importResponse) - }) - - actual, err := keypairs.Create(fakeclient.ServiceClient(), keypairs.CreateOpts{ - Name: "importedkey", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &importedKeyPair, actual) -} - -func TestGetKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs/firstkey", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := keypairs.Get(fakeclient.ServiceClient(), "firstkey").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &firstKeyPair, actual) -} - -func TestDeleteKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusAccepted) - }) - - err := keypairs.Delete(fakeclient.ServiceClient(), "deletedkey").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/v3/ecl/baremetal/v2/keypairs/urls.go b/v3/ecl/baremetal/v2/keypairs/urls.go deleted file mode 100644 index 2637342..0000000 --- a/v3/ecl/baremetal/v2/keypairs/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package keypairs - -import "github.com/nttcom/eclcloud/v3" - -const resourcePath = "os-keypairs" - -func resourceURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL(resourcePath) -} - -func listURL(c *eclcloud.ServiceClient) string { - return resourceURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return resourceURL(c) -} - -func getURL(c *eclcloud.ServiceClient, name string) string { - return c.ServiceURL(resourcePath, name) -} - -func deleteURL(c *eclcloud.ServiceClient, name string) string { - return getURL(c, name) -} diff --git a/v3/ecl/baremetal/v2/servers/doc.go b/v3/ecl/baremetal/v2/servers/doc.go deleted file mode 100644 index 0ab1220..0000000 --- a/v3/ecl/baremetal/v2/servers/doc.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Package servers contains functionality for working with -ECL Baremetal Server resources. - -Example to create server - - createOpts := servers.CreateOpts{ - Name: "server-test-1", - Networks: []servers.CreateOptsNetwork{ - { - UUID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - FixedIP: "10.0.0.100", - }, - }, - AdminPass: "aabbccddeeff", - ImageRef: "b5660a6e-4b46-4be3-9707-6b47221b454f", - FlavorRef: "05184ba3-00ba-4fbc-b7a2-03b62b884931", - AvailabilityZone: "zone1-groupa", - UserData: "IyEvYmluL2Jhc2gKZWNobyAiS3VtYSBQb3N0IEluc3RhbGwgU2NyaXB0IiA+PiAvaG9tZS9iaWcvcG9zdC1pbnN0YWxsLXNjcmlwdA==", - RaidArrays: []servers.CreateOptsRaidArray{ - { - PrimaryStorage: true, - Partitions: []map[string]interface{}{ - { - "lvm": true, - "partition_label": "primary-part1", - }, - { - "lvm": false, - "size": "100G", - "partition_label": "var", - }, - }, - }, - { - RaidCardHardwareID: "raid_card_uuid", - DiskHardwareIDs: []string{ - "disk1_uuid", - "disk2_uuid", - "disk3_uuid", - "disk4_uuid", - }, - Partitions: []map[string]interface{}{ - { - "lvm": true, - "partition_label": "secondary-part1", - }, - }, - }, - }, - LVMVolumeGroups: []servers.CreateOptsLVMVolumeGroup{ - { - VGLabel: "VG_root", - PhysicalVolumePartitionLabels: []string{ - "primary-part1", - "secondary-part1", - }, - LogicalVolumes: []map[string]string{ - { - "size": "300G", - "lv_label": "LV_root", - }, - { - "size": "2G", - "lv_label": "LV_swap", - }, - }, - }, - }, - Filesystems: []servers.CreateOptsFilesystem{ - { - Label: "LV_root", - FSType: "xfs", - MountPoint: "/", - }, - { - Label: "var", - FSType: "xfs", - MountPoint: "/var", - }, - { - Label: "LV_swap", - FSType: "swap", - }, - }, - Metadata: map[string]string{ - "foo": "bar", - }, - } - server, err := servers.Create(client, createOpts).Extract() - -Example to list servers - - listOpts := servers.ListOpts{ - Status: "ACTIVE", - } - - allPages, err := servers.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allServers, err := servers.ExtractServers(allPages) - if err != nil { - panic(err) - } - - for _, server := range allServers { - fmt.Printf("%+v", server) - } - -Example to delete server - - err = servers.Delete(client, "server-id"").ExtractErr() - if err != nil { - panic(err) - } - -*/ -package servers diff --git a/v3/ecl/baremetal/v2/servers/requests.go b/v3/ecl/baremetal/v2/servers/requests.go deleted file mode 100644 index 35fd45c..0000000 --- a/v3/ecl/baremetal/v2/servers/requests.go +++ /dev/null @@ -1,186 +0,0 @@ -package servers - -import ( - "encoding/base64" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Get retrieves the server with the provided ID. -// To extract the Server object from the response, -// call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToServerListQuery() (string, error) -} - -// ListOpts holds options for listing servers. -// It is passed to the servers.List function. -type ListOpts struct { - // ChangesSince is a time/date stamp for when the server last changed status. - ChangesSince string `q:"changes-since"` - - // Image is the name of the image in URL format. - Image string `q:"image"` - - // Flavor is the name of the flavor in URL format. - Flavor string `q:"flavor"` - - // Name of the server as a string. - Name string `q:"name"` - - // Status is the value of the status of the server so that you can filter on - // "ACTIVE" for example. - Status string `q:"status"` - - // Marker is a UUID of the server at which you want to set a marker. - Marker string `q:"marker"` - - // Limit is an integer value for the limit of values to return. - Limit int `q:"limit"` -} - -// ToServerListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToServerListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns Server optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToServerListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToServerCreateMap() (map[string]interface{}, error) -} - -// CreateOptsNetwork represents networks information in server creation. -type CreateOptsNetwork struct { - UUID string `json:"uuid,omitempty"` - Port string `json:"port,omitempty"` - FixedIP string `json:"fixed_ip,omitempty"` - Plane string `json:"plane,omitempty"` -} - -// CreateOptsRaidArray represents raid configuration for the server resource. -type CreateOptsRaidArray struct { - PrimaryStorage bool `json:"primary_storage,omitempty"` - RaidCardHardwareID string `json:"raid_card_hardware_id,omitempty"` - DiskHardwareIDs []string `json:"disk_hardware_ids,omitempty"` - RaidLevel int `json:"raid_level,omitempty"` - Partitions []CreateOptsPartition `json:"partitions,omitempty"` -} - -// CreateOptsPartition represents partition configuration for the server resource. -type CreateOptsPartition struct { - LVM bool `json:"lvm,omitempty"` - Size string `json:"size,omitempty"` - PartitionLabel string `json:"partition_label,omitempty"` -} - -// CreateOptsLVMVolumeGroup represents LVM volume group configuration for the server resource. -type CreateOptsLVMVolumeGroup struct { - VGLabel string `json:"vg_label,omitempty"` - PhysicalVolumePartitionLabels []string `json:"physical_volume_partition_labels,omitempty"` - LogicalVolumes []CreateOptsLogicalVolume `json:"logical_volumes,omitempty"` -} - -// CreateOptsLogicalVolume represents logical volume configuration for the server resource. -type CreateOptsLogicalVolume struct { - LVLabel string `json:"lv_label,omitempty"` - Size string `json:"size,omitempty"` -} - -// CreateOptsFilesystem represents file system configuration for the server resource. -type CreateOptsFilesystem struct { - Label string `json:"label,omitempty"` - FSType string `json:"fs_type,omitempty"` - MountPoint string `json:"mount_point,omitempty"` -} - -// CreateOptsPersonality represents personal files configuration for the server resource. -type CreateOptsPersonality struct { - Path string `json:"path,omitempty"` - Contents string `json:"contents,omitempty"` -} - -// CreateOpts represents options used to create a server. -type CreateOpts struct { - Name string `json:"name" required:"true"` - Networks []CreateOptsNetwork `json:"networks" required:"true"` - AdminPass string `json:"adminPass,omitempty"` - ImageRef string `json:"imageRef,omitempty"` - FlavorRef string `json:"flavorRef" required:"true"` - AvailabilityZone string `json:"availability_zone,omitempty"` - KeyName string `json:"key_name,omitempty"` - UserData []byte `json:"-"` - RaidArrays []CreateOptsRaidArray `json:"raid_arrays,omitempty"` - LVMVolumeGroups []CreateOptsLVMVolumeGroup `json:"lvm_volume_groups,omitempty"` - Filesystems []CreateOptsFilesystem `json:"filesystems,omitempty"` - Metadata map[string]string `json:"metadata,omitempty"` - Personality []CreateOptsPersonality `json:"personality,omitempty"` -} - -// ToServerCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - if opts.UserData != nil { - var userData string - if _, err := base64.StdEncoding.DecodeString(string(opts.UserData)); err != nil { - userData = base64.StdEncoding.EncodeToString(opts.UserData) - } else { - userData = string(opts.UserData) - } - b["user_data"] = &userData - } - - return map[string]interface{}{"server": b}, nil -} - -// Create accepts a CreateOpts struct and creates a new server -// using the values provided. -// This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToServerCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete requests that a server previously provisioned be removed from your -// account. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} diff --git a/v3/ecl/baremetal/v2/servers/result.go b/v3/ecl/baremetal/v2/servers/result.go deleted file mode 100644 index 4829132..0000000 --- a/v3/ecl/baremetal/v2/servers/result.go +++ /dev/null @@ -1,208 +0,0 @@ -package servers - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the result of Get operations. Call its Extract method to -// interpret it as a Server. -type GetResult struct { - commonResult -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Server. -type CreateResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Server. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// Extract provides access to the individual Server returned by -// the Get and functions. -func (r commonResult) Extract() (*Server, error) { - var s struct { - Server *Server `json:"server"` - } - err := r.ExtractInto(&s) - return s.Server, err -} - -// RaidArray represents raid configuration for the server resource. -type RaidArray struct { - PrimaryStorage bool `json:"primary_storage"` - RaidCardHardwareID string `json:"raid_card_hardware_id"` - DiskHardwareIDs []string `json:"disk_hardware_ids"` - RaidLevel int `json:"raid_level"` - Partitions []Partition `json:"partitions"` -} - -// Partition represents partition configuration for the server resource. -type Partition struct { - LVM bool `json:"lvm"` - Size int `json:"size"` - PartitionLabel string `json:"partition_label"` -} - -// LVMVolumeGroup represents LVM volume group configuration for the server resource. -type LVMVolumeGroup struct { - VGLabel string `json:"vg_label"` - PhysicalVolumePartitionLabels []string `json:"physical_volume_partition_labels"` - LogicalVolumes []LogicalVolume `json:"logical_volumes"` -} - -// LogicalVolume represents logical volume configuration for the server resource. -type LogicalVolume struct { - LVLabel string `json:"lv_label"` - Size int `json:"size"` -} - -// Filesystem represents file system configuration for the server resource. -type Filesystem struct { - Label string `json:"label"` - FSType string `json:"fs_type"` - MountPoint string `json:"mount_point"` -} - -// NICPhysicalPort represents port configuraion for the server resource. -type NICPhysicalPort struct { - ID string `json:"id"` - MacAddr string `json:"mac_addr"` - NetworkPhysicalPortID string `json:"network_physical_port_id"` - Plane string `json:"plane"` - AttachedPorts []AttachedPort `json:"attached_ports"` - HardwareID string `json:"hardware_id"` -} - -// AttachedPort represents attached port configuration for the server resource. -type AttachedPort struct { - PortID string `json:"port_id"` - NetworkID string `json:"network_id"` - FixedIPs []FixedIP `json:"fixed_ips"` -} - -// FixedIP represents fixed IP configuration for the server resource. -type FixedIP struct { - SubnetID string `json:"subnet_id"` - IPAddress string `json:"ip_address"` -} - -// ChassisStatus represents chassis status for the server resource -type ChassisStatus struct { - ChassisPower bool `json:"chassis-power"` - PowerSupply bool `json:"power-supply"` - CPU bool `json:"cpu"` - Memory bool `json:"memory"` - Fan bool `json:"fan"` - Disk int `json:"disk"` - NIC bool `json:"nic"` - SystemBoard bool `json:"system-board"` - Etc bool `json:"etc"` -} - -// Personality represents personal files configuration for the server resource. -type Personality struct { - Path string `json:"path"` - Contents string `json:"contents"` -} - -// Server represents hardware configurations for server resources -// in a region. -type Server struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - UserID string `json:"user_id"` - Name string `json:"name"` - Updated time.Time `json:"-"` - Created time.Time `json:"-"` - Status string `json:"status"` - AdminPass string `json:"adminPass"` - PowerState string `json:"OS-EXT-STS:power_state"` - TaskState string `json:"OS-EXT-STS:task_state"` - VMState string `json:"OS-EXT-STS:vm_state"` - AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"` - Progress int `json:"progress"` - Image map[string]interface{} `json:"image"` - Flavor map[string]interface{} `json:"flavor"` - Metadata map[string]string `json:"metadata"` - Links []eclcloud.Link `json:"links"` - RaidArrays []RaidArray `json:"raid_arrays"` - LVMVolumeGroups []LVMVolumeGroup `json:"lvm_volume_groups"` - Filesystems []Filesystem `json:"filesystems"` - NICPhysicalPorts []NICPhysicalPort `json:"nic_physical_ports"` - ChassisStatus ChassisStatus `json:"chassis-status"` - MediaAttachments []map[string]interface{} `json:"media_attachments"` - Personality []Personality `json:"personality"` -} - -// UnmarshalJSON to override default -func (r *Server) UnmarshalJSON(b []byte) error { - type tmp Server - var s struct { - tmp - Created eclcloud.JSONRFC3339Milli `json:"created"` - Updated eclcloud.JSONRFC3339Milli `json:"updated"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Server(s.tmp) - - r.Created = time.Time(s.Created) - r.Updated = time.Time(s.Updated) - - return err -} - -// ServerPage contains a single page of all servers from a ListDetails call. -type ServerPage struct { - pagination.LinkedPageBase -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (page ServerPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"servers_links"` - } - err := page.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty determines if a FlavorPage contains any results. -func (page ServerPage) IsEmpty() (bool, error) { - flavors, err := ExtractServers(page) - return len(flavors) == 0, err -} - -// ExtractServers provides access to the list of flavors in a page acquired -// from the ListDetail operation. -func ExtractServers(r pagination.Page) ([]Server, error) { - var s struct { - Servers []Server `json:"servers"` - } - err := (r.(ServerPage)).ExtractInto(&s) - return s.Servers, err -} diff --git a/v3/ecl/baremetal/v2/servers/testing/doc.go b/v3/ecl/baremetal/v2/servers/testing/doc.go deleted file mode 100644 index d255096..0000000 --- a/v3/ecl/baremetal/v2/servers/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains baremetal server unit tests -package testing diff --git a/v3/ecl/baremetal/v2/servers/testing/fixtures.go b/v3/ecl/baremetal/v2/servers/testing/fixtures.go deleted file mode 100644 index 72b3e48..0000000 --- a/v3/ecl/baremetal/v2/servers/testing/fixtures.go +++ /dev/null @@ -1,898 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/servers" -) - -var listResponse = fmt.Sprintf(` -{ - "servers": [ - { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "zone1-groupa", - "created": "2012-09-07T16:56:37Z", - "flavor": { - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "links": [ - { - "href": "http://openstack.example.com/openstack/flavors/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ] - }, - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "image": { - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - { - "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "self" - }, - { - "href": "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ], - "metadata": { - "My Server Name": "Apache1" - }, - "name": "Test Server1", - "progress": 0, - "status": "ACTIVE", - "tenant_id": "openstack", - "updated": "2012-09-07T16:56:37Z", - "user_id": "fake", - "raid_arrays": [ - { - "primary_storage": true, - "raid_card_hardware_id": "raid_card_uuid", - "disk_hardware_ids": [ - "disk0_uuid", - "disk1_uuid", - "disk2_uuid", - "disk3_uuid" - ], - "partitions": [ - { - "lvm": true, - "partition_label": "primary-part1" - }, - { - "lvm": false, - "size": 100, - "partition_label": "var" - } - ] - }, - { - "primary_storage": false, - "raid_card_hardware_id": "raid_card_uuid", - "internal_disk_ids": [ - "disk4_uuid", - "disk5_uuid", - "disk6_uuid", - "disk7_uuid" - ], - "raid_level": 10, - "partitions": [ - { - "lvm": true, - "partition_label": "secondary-part1" - } - ] - } - ], - "lvm_volume_groups": [ - { - "vg_label": "VG_root", - "physical_volume_partition_labels": [ - "primary-part1", - "secondary-part1" - ], - "logical_volumes": [ - { - "lv_label": "LV_root" - }, - { - "size": 2, - "lv_label": "LV_swap" - } - ] - } - ], - "filesystems": [ - { - "label": "LV_root", - "mount_point": "/", - "fs_type": "xfs" - }, - { - "label": "var", - "mount_point": "/var", - "fs_type": "xfs" - }, - { - "label": "LV_swap", - "fs_type": "swap" - } - ], - "nic_physical_ports": [ - { - "id": "39285bf9-12fb-4064-b98b-a552efc51cfc", - "mac_addr": "0a:31:c1:d5:6d:9c", - "network_physical_port_id": "38268d94-584a-4f14-96ff-732a68aa7301", - "plane": "data", - "attached_ports": [ - { - "port_id": "61b7da1e-9571-4d63-b779-e003a56b8105", - "network_id": "9aa93722-1ec4-4912-b813-b975c21460a5", - "fixed_ips": [ - { - "subnet_id": "0419bbde-2b82-4107-9d8a-6bba76e364af", - "ip_address": "192.168.10.2" - } - ] - } - ], - "hardware_id": "063468e8-61ab-4afd-be38-c937254aeb9a" - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true - }, - "media_attachments": [], - "personality": [ - { - "path": "/home/big/banner.txt", - "contents": "ZWNobyAiS3VtYSBQZXJzb25hbGl0eSIgPj4gL2hvbWUvYmlnL3BlcnNvbmFsaXR5" - } - ] - }, - { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "zone1-groupa", - "created": "2012-09-07T16:56:37Z", - "flavor": { - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884932", - "links": [ - { - "href": "http://openstack.example.com/openstack/flavors/1", - "rel": "bookmark" - } - ] - }, - "hostId": "16d193736a5cfdb60c697ca27ad071d6126fa13baeb670fc9d10645e", - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884932", - "image": { - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - { - "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "self" - }, - { - "href": "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ], - "metadata": { - "My Server Name": "Apache1" - }, - "name": "Test Server2", - "progress": 0, - "status": "ACTIVE", - "tenant_id": "openstack", - "updated": "2012-09-07T16:56:37Z", - "user_id": "fake", - "raid_arrays": [ - { - "primary_storage": true, - "raid_card_hardware_id": "raid_card_uuid", - "disk_hardware_ids": [ - "disk0_uuid", - "disk1_uuid", - "disk2_uuid", - "disk3_uuid" - ], - "partitions": [ - { - "lvm": true, - "partition_label": "primary-part1" - }, - { - "lvm": false, - "size": 100, - "partition_label": "var" - } - ] - }, - { - "primary_storage": false, - "raid_card_hardware_id": "raid_card_uuid", - "internal_disk_ids": [ - "disk4_uuid", - "disk5_uuid", - "disk6_uuid", - "disk7_uuid" - ], - "raid_level": 10, - "partitions": [ - { - "lvm": true, - "partition_label": "secondary-part1" - } - ] - } - ], - "lvm_volume_groups": [ - { - "vg_label": "VG_root", - "physical_volume_partition_labels": [ - "primary-part1", - "secondary-part1" - ], - "logical_volumes": [ - { - "lv_label": "LV_root" - }, - { - "size": 2, - "lv_label": "LV_swap" - } - ] - } - ], - "filesystems": [ - { - "label": "LV_root", - "mount_point": "/", - "fs_type": "xfs" - }, - { - "label": "var", - "mount_point": "/var", - "fs_type": "xfs" - }, - { - "label": "LV_swap", - "fs_type": "swap" - } - ], - "nic_physical_ports": [ - { - "id": "f4732cd9-31f7-408e-9f27-cc9b0ee17457", - "mac_addr": "0a:31:c1:d5:6d:9d", - "network_physical_port_id": "ab17a82d-e9a5-4e95-9b18-de3f8a47670f", - "plane": "storage", - "attached_ports": [ - { - "port_id": "6fb0d979-f05b-466c-b50c-64d5ae4c4ef6", - "network_id": "99babdfc-79eb-470a-b0d4-df02482cc509", - "fixed_ips": [ - { - "subnet_id": "9632ce5d-8750-40bf-871d-968aa3324367", - "ip_address": "192.168.10.8" - } - ] - } - ], - "hardware_id": "ab36f541-b854-46c3-8891-e9484a1ba1ac" - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true - }, - "media_attachments": [ - { - "image": { - "id": "3339fd5f-ec06-4ef8-9337-c1c70218a748", - "links": [ - { - "href": "http://openstack.example.com/openstack/images/3339fd5f-ec06-4ef8-9337-c1c70218a748", - "rel": "bookmark" - } - ] - } - } - ] - } - ] -}`) - -var getResponse = fmt.Sprintf(` -{ - "server": { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "zone1-groupa", - "created": "2012-09-07T16:56:37Z", - "flavor": { - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "links": [ - { - "href": "http://openstack.example.com/openstack/flavors/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ] - }, - "hostId": "16d193736a5cfdb60c697ca27ad071d6126fa13baeb670fc9d10645e", - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "image": { - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - { - "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "self" - }, - { - "href": "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ], - "metadata": { - "My Server Name": "Apache1" - }, - "name": "Test Server1", - "progress": 0, - "status": "ACTIVE", - "tenant_id": "openstack", - "updated": "2012-09-07T16:56:37Z", - "user_id": "fake", - "raid_arrays": [ - { - "primary_storage": true, - "raid_card_hardware_id": "raid_card_uuid", - "disk_hardware_ids": [ - "disk0_uuid", - "disk1_uuid", - "disk2_uuid", - "disk3_uuid" - ], - "partitions": [ - { - "lvm": true, - "partition_label": "primary-part1" - }, - { - "lvm": false, - "size": 100, - "partition_label": "var" - } - ] - }, - { - "primary_storage": false, - "raid_card_hardware_id": "raid_card_uuid", - "internal_disk_ids": [ - "disk4_uuid", - "disk5_uuid", - "disk6_uuid", - "disk7_uuid" - ], - "raid_level": 10, - "partitions": [ - { - "lvm": true, - "partition_label": "secondary-part1" - } - ] - } - ], - "lvm_volume_groups": [ - { - "vg_label": "VG_root", - "physical_volume_partition_labels": [ - "primary-part1", - "secondary-part1" - ], - "logical_volumes": [ - { - "lv_label": "LV_root" - }, - { - "size": 2, - "lv_label": "LV_swap" - } - ] - } - ], - "filesystems": [ - { - "label": "LV_root", - "mount_point": "/", - "fs_type": "xfs" - }, - { - "label": "var", - "mount_point": "/var", - "fs_type": "xfs" - }, - { - "label": "LV_swap", - "fs_type": "swap" - } - ], - "nic_physical_ports": [ - { - "id": "39285bf9-12fb-4064-b98b-a552efc51cfc", - "mac_addr": "0a:31:c1:d5:6d:9c", - "network_physical_port_id": "38268d94-584a-4f14-96ff-732a68aa7301", - "plane": "data", - "attached_ports": [ - { - "port_id": "61b7da1e-9571-4d63-b779-e003a56b8105", - "network_id": "9aa93722-1ec4-4912-b813-b975c21460a5", - "fixed_ips": [ - { - "subnet_id": "0419bbde-2b82-4107-9d8a-6bba76e364af", - "ip_address": "192.168.10.2" - } - ] - } - ], - "hardware_id": "063468e8-61ab-4afd-be38-c937254aeb9a" - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true - }, - "media_attachments": [ - { - "image": { - "id": "3339fd5f-ec06-4ef8-9337-c1c70218a748", - "links": [ - { - "href": "http://openstack.example.com/openstack/images/3339fd5f-ec06-4ef8-9337-c1c70218a748", - "rel": "bookmark" - } - ] - } - } - ], - "personality": [ - { - "path": "/home/big/banner.txt", - "contents": "ZWNobyAiS3VtYSBQZXJzb25hbGl0eSIgPj4gL2hvbWUvYmlnL3BlcnNvbmFsaXR5" - } - ] - } -}`) - -var createRequest = fmt.Sprintf(` - { - "server": { - "name": "server-test-1", - "adminPass": "aabbccddeeff", - "imageRef": "b5660a6e-4b46-4be3-9707-6b47221b454f", - "flavorRef": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "availability_zone": "zone1-groupa", - "networks": [ - { - "uuid": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "fixed_ip": "10.0.0.100" - } - ], - "raid_arrays": [ - { - "primary_storage": true, - "partitions": [ - { - "lvm": true, - "partition_label": "primary-part1" - }, - { - "size": "100G", - "partition_label": "var" - } - ] - }, - { - "raid_card_hardware_id": "raid_card_uuid", - "disk_hardware_ids": [ - "disk1_uuid", "disk2_uuid", "disk3_uuid", "disk4_uuid" - ], - "partitions": [ - { - "lvm": true, - "partition_label": "secondary-part1" - } - ], - "raid_level": 10 - } - ], - "lvm_volume_groups": [ - { - "vg_label": "VG_root", - "physical_volume_partition_labels": [ - "primary-part1", "secondary-part1" - ], - "logical_volumes": [ - { - "size": "300G", - "lv_label": "LV_root" - }, - { - "size": "2G", - "lv_label": "LV_swap" - } - ] - } - ], - "filesystems": [ - { - "label": "LV_root", - "mount_point": "/", - "fs_type": "xfs" - }, - { - "label": "var", - "mount_point": "/var", - "fs_type": "xfs" - }, - { - "label": "LV_swap", - "fs_type": "swap" - } - ], - "user_data": "dXNlcl9kYXRh", - "metadata": { - "foo": "bar" - } - } -}`) - -var createResponse = fmt.Sprintf(` -{ - "server": { - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "links": [ - { - "href": "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "self" - }, - { - "href": "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark" - } - ], - "adminPass": "aabbccddeeff" - } -}`) - -var expectedServers = []servers.Server{expectedServer1, expectedServer2} - -var expectedCreated, _ = time.Parse(eclcloud.RFC3339Milli, "2012-09-07T16:56:37Z") -var expectedUpdated, _ = time.Parse(eclcloud.RFC3339Milli, "2012-09-07T16:56:37Z") - -var expectedServer1 = servers.Server{ - ID: "05184ba3-00ba-4fbc-b7a2-03b62b884931", - TenantID: "openstack", - UserID: "fake", - Name: "Test Server1", - Updated: expectedUpdated, - Created: expectedCreated, - Status: "ACTIVE", - PowerState: "RUNNING", - TaskState: "None", - VMState: "ACTIVE", - AvailabilityZone: "zone1-groupa", - Progress: 0, - Image: map[string]interface{}{ - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": []map[string]interface{}{ - { - "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884931", - "links": []map[string]interface{}{ - { - "href": "http://openstack.example.com/openstack/flavors/05184ba3-00ba-4fbc-b7a2-03b62b884931", - "rel": "bookmark", - }, - }, - }, - Metadata: map[string]string{ - "My Server Name": "Apache1", - }, - Links: []eclcloud.Link{ - { - Href: "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - Rel: "self", - }, - { - Href: "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - Rel: "bookmark", - }, - }, - RaidArrays: []servers.RaidArray{ - { - PrimaryStorage: true, - RaidCardHardwareID: "raid_card_uuid", - DiskHardwareIDs: []string{ - "disk0_uuid", - "disk1_uuid", - "disk2_uuid", - "disk3_uuid", - }, - Partitions: []servers.Partition{ - { - LVM: true, - PartitionLabel: "primary-part1", - }, - { - LVM: false, - Size: 100, - PartitionLabel: "var", - }, - }, - }, - }, - LVMVolumeGroups: []servers.LVMVolumeGroup{ - { - VGLabel: "VG_root", - PhysicalVolumePartitionLabels: []string{ - "primary-part1", - "secondary-part1", - }, - LogicalVolumes: []servers.LogicalVolume{ - { - LVLabel: "LV_root", - }, - { - Size: 2, - LVLabel: "LV_swap", - }, - }, - }, - }, - Filesystems: []servers.Filesystem{ - { - Label: "LV_root", - FSType: "xfs", - MountPoint: "/", - }, - { - Label: "var", - FSType: "xfs", - MountPoint: "/var", - }, - { - Label: "LV_swap", - FSType: "swap", - }, - }, - NICPhysicalPorts: []servers.NICPhysicalPort{ - { - ID: "39285bf9-12fb-4064-b98b-a552efc51cfc", - MacAddr: "0a:31:c1:d5:6d:9c", - NetworkPhysicalPortID: "38268d94-584a-4f14-96ff-732a68aa7301", - Plane: "data", - AttachedPorts: []servers.AttachedPort{ - { - PortID: "61b7da1e-9571-4d63-b779-e003a56b8105", - NetworkID: "9aa93722-1ec4-4912-b813-b975c21460a5", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "0419bbde-2b82-4107-9d8a-6bba76e364af", - IPAddress: "192.168.10.2", - }, - }, - }, - }, - HardwareID: "063468e8-61ab-4afd-be38-c937254aeb9a", - }, - }, - ChassisStatus: servers.ChassisStatus{ - ChassisPower: true, - PowerSupply: true, - CPU: true, - Memory: true, - Fan: true, - Disk: 0, - NIC: true, - SystemBoard: true, - Etc: true, - }, - MediaAttachments: []map[string]interface{}{}, - Personality: []servers.Personality{ - { - Path: "/home/big/banner.txt", - Contents: "ZWNobyAiS3VtYSBQZXJzb25hbGl0eSIgPj4gL2hvbWUvYmlnL3BlcnNvbmFsaXR5", - }, - }, -} - -var expectedServer2 = servers.Server{ - ID: "05184ba3-00ba-4fbc-b7a2-03b62b884932", - TenantID: "openstack", - UserID: "fake", - Name: "Test Server2", - Updated: expectedUpdated, - Created: expectedCreated, - Status: "ACTIVE", - PowerState: "RUNNING", - TaskState: "None", - VMState: "ACTIVE", - AvailabilityZone: "zone1-groupa", - Progress: 0, - Image: map[string]interface{}{ - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": []map[string]interface{}{ - { - "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "05184ba3-00ba-4fbc-b7a2-03b62b884932", - "links": []map[string]interface{}{ - { - "href": "http://openstack.example.com/openstack/flavors/1", - "rel": "bookmark", - }, - }, - }, - Metadata: map[string]string{ - "My Server Name": "Apache1", - }, - Links: []eclcloud.Link{ - { - Href: "http://openstack.example.com/v2/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - Rel: "self", - }, - { - Href: "http://openstack.example.com/openstack/servers/05184ba3-00ba-4fbc-b7a2-03b62b884931", - Rel: "bookmark", - }, - }, - RaidArrays: []servers.RaidArray{ - { - PrimaryStorage: true, - RaidCardHardwareID: "raid_card_uuid", - DiskHardwareIDs: []string{ - "disk0_uuid", - "disk1_uuid", - "disk2_uuid", - "disk3_uuid", - }, - Partitions: []servers.Partition{ - { - LVM: true, - PartitionLabel: "primary-part1", - }, - { - LVM: false, - Size: 100, - PartitionLabel: "var", - }, - }, - }, - }, - LVMVolumeGroups: []servers.LVMVolumeGroup{ - { - VGLabel: "VG_root", - PhysicalVolumePartitionLabels: []string{ - "primary-part1", - "secondary-part1", - }, - LogicalVolumes: []servers.LogicalVolume{ - { - LVLabel: "LV_root", - }, - { - Size: 2, - LVLabel: "LV_swap", - }, - }, - }, - }, - Filesystems: []servers.Filesystem{ - { - Label: "LV_root", - FSType: "xfs", - MountPoint: "/", - }, - { - Label: "var", - FSType: "xfs", - MountPoint: "/var", - }, - { - Label: "LV_swap", - FSType: "swap", - }, - }, - NICPhysicalPorts: []servers.NICPhysicalPort{ - { - ID: "f4732cd9-31f7-408e-9f27-cc9b0ee17457", - MacAddr: "0a:31:c1:d5:6d:9d", - NetworkPhysicalPortID: "ab17a82d-e9a5-4e95-9b18-de3f8a47670f", - Plane: "storage", - AttachedPorts: []servers.AttachedPort{ - { - PortID: "6fb0d979-f05b-466c-b50c-64d5ae4c4ef6", - NetworkID: "99babdfc-79eb-470a-b0d4-df02482cc509", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "9632ce5d-8750-40bf-871d-968aa3324367", - IPAddress: "192.168.10.8", - }, - }, - }, - }, - HardwareID: "ab36f541-b854-46c3-8891-e9484a1ba1ac", - }, - }, - ChassisStatus: servers.ChassisStatus{ - ChassisPower: true, - PowerSupply: true, - CPU: true, - Memory: true, - Fan: true, - Disk: 0, - NIC: true, - SystemBoard: true, - Etc: true, - }, - MediaAttachments: []map[string]interface{}{}, - Personality: []servers.Personality(nil), -} diff --git a/v3/ecl/baremetal/v2/servers/testing/requests_test.go b/v3/ecl/baremetal/v2/servers/testing/requests_test.go deleted file mode 100644 index 7c49142..0000000 --- a/v3/ecl/baremetal/v2/servers/testing/requests_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/baremetal/v2/servers" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := servers.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - fmt.Printf("person[%%#v] -> %#v\n", actual) - th.CheckDeepEquals(t, expectedServers, actual) - return true, nil - }) - - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s", "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79") - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := servers.Get(fakeclient.ServiceClient(), "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedServer1, actual) -} - -func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, createRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, createResponse) - }) - - createOpts := servers.CreateOpts{ - Name: "server-test-1", - Networks: []servers.CreateOptsNetwork{ - { - UUID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - FixedIP: "10.0.0.100", - }, - }, - AdminPass: "aabbccddeeff", - ImageRef: "b5660a6e-4b46-4be3-9707-6b47221b454f", - FlavorRef: "05184ba3-00ba-4fbc-b7a2-03b62b884931", - AvailabilityZone: "zone1-groupa", - UserData: []byte("user_data"), - RaidArrays: []servers.CreateOptsRaidArray{ - { - PrimaryStorage: true, - Partitions: []servers.CreateOptsPartition{ - { - LVM: true, - PartitionLabel: "primary-part1", - }, - { - Size: "100G", - PartitionLabel: "var", - }, - }, - }, - { - RaidCardHardwareID: "raid_card_uuid", - DiskHardwareIDs: []string{ - "disk1_uuid", - "disk2_uuid", - "disk3_uuid", - "disk4_uuid", - }, - Partitions: []servers.CreateOptsPartition{ - { - LVM: true, - PartitionLabel: "secondary-part1", - }, - }, - RaidLevel: 10, - }, - }, - LVMVolumeGroups: []servers.CreateOptsLVMVolumeGroup{ - { - VGLabel: "VG_root", - PhysicalVolumePartitionLabels: []string{ - "primary-part1", - "secondary-part1", - }, - LogicalVolumes: []servers.CreateOptsLogicalVolume{ - { - Size: "300G", - LVLabel: "LV_root", - }, - { - Size: "2G", - LVLabel: "LV_swap", - }, - }, - }, - }, - Filesystems: []servers.CreateOptsFilesystem{ - { - Label: "LV_root", - FSType: "xfs", - MountPoint: "/", - }, - { - Label: "var", - FSType: "xfs", - MountPoint: "/var", - }, - { - Label: "LV_swap", - FSType: "swap", - }, - }, - Metadata: map[string]string{ - "foo": "bar", - }, - } - server, err := servers.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, server.AdminPass, "aabbccddeeff") -} - -func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s", "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79") - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := servers.Delete(fakeclient.ServiceClient(), "cebf8bb5-74cf-4a53-bca5-b90d4bbe8d79") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/baremetal/v2/servers/urls.go b/v3/ecl/baremetal/v2/servers/urls.go deleted file mode 100644 index 07a5733..0000000 --- a/v3/ecl/baremetal/v2/servers/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package servers - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers", "detail") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/doc.go b/v3/ecl/compute/v2/extensions/availabilityzones/doc.go deleted file mode 100644 index 6fbc22f..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/doc.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Package availabilityzones provides the ability to get lists and detailed -availability zone information and to extend a server result with -availability zone information. - -Example of Extend server result with Availability Zone Information: - - type ServerWithAZ struct { - servers.Server - availabilityzones.ServerAvailabilityZoneExt - } - - var allServers []ServerWithAZ - - allPages, err := servers.List(client, nil).AllPages() - if err != nil { - panic("Unable to retrieve servers: %s", err) - } - - err = servers.ExtractServersInto(allPages, &allServers) - if err != nil { - panic("Unable to extract servers: %s", err) - } - - for _, server := range allServers { - fmt.Println(server.AvailabilityZone) - } - -Example of Get Availability Zone Information - - allPages, err := availabilityzones.List(computeClient).AllPages() - if err != nil { - panic(err) - } - - availabilityZoneInfo, err := availabilityzones.ExtractAvailabilityZones(allPages) - if err != nil { - panic(err) - } - - for _, zoneInfo := range availabilityZoneInfo { - fmt.Printf("%+v\n", zoneInfo) - } - -*/ -package availabilityzones diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/requests.go b/v3/ecl/compute/v2/extensions/availabilityzones/requests.go deleted file mode 100644 index 247bbd2..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/requests.go +++ /dev/null @@ -1,13 +0,0 @@ -package availabilityzones - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List will return the existing availability zones. -func List(client *eclcloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return AvailabilityZonePage{pagination.SinglePageBase(r)} - }) -} diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/results.go b/v3/ecl/compute/v2/extensions/availabilityzones/results.go deleted file mode 100644 index c66f396..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/results.go +++ /dev/null @@ -1,80 +0,0 @@ -package availabilityzones - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ServerAvailabilityZoneExt is an extension to the base Server object. -type ServerAvailabilityZoneExt struct { - // AvailabilityZone is the availability zone the server is in. - AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"` -} - -// ServiceState represents the state of a service in an AvailabilityZone. -type ServiceState struct { - Active bool `json:"active"` - Available bool `json:"available"` - UpdatedAt time.Time `json:"-"` -} - -// UnmarshalJSON to override default -func (r *ServiceState) UnmarshalJSON(b []byte) error { - type tmp ServiceState - var s struct { - tmp - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = ServiceState(s.tmp) - - r.UpdatedAt = time.Time(s.UpdatedAt) - - return nil -} - -// Services is a map of services contained in an AvailabilityZone. -type Services map[string]ServiceState - -// Hosts is map of hosts/nodes contained in an AvailabilityZone. -// Each host can have multiple services. -type Hosts map[string]Services - -// ZoneState represents the current state of the availability zone. -type ZoneState struct { - // Returns true if the availability zone is available - Available bool `json:"available"` -} - -// AvailabilityZone contains all the information associated with an ECL -// AvailabilityZone. -type AvailabilityZone struct { - Hosts Hosts `json:"hosts"` - // The availability zone name - ZoneName string `json:"zoneName"` - ZoneState ZoneState `json:"zoneState"` -} - -// AvailabilityZonePage stores a single page of all AvailabilityZone results -// from a List call. -// Use the ExtractKeyPairs function to convert the results to a slice of -// KeyPairs. -type AvailabilityZonePage struct { - pagination.SinglePageBase -} - -// ExtractAvailabilityZones returns a slice of AvailabilityZones contained in a -// single page of results. -func ExtractAvailabilityZones(r pagination.Page) ([]AvailabilityZone, error) { - var s struct { - AvailabilityZoneInfo []AvailabilityZone `json:"availabilityZoneInfo"` - } - err := (r.(AvailabilityZonePage)).ExtractInto(&s) - return s.AvailabilityZoneInfo, err -} diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/testing/doc.go b/v3/ecl/compute/v2/extensions/availabilityzones/testing/doc.go deleted file mode 100644 index a4408d7..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// availabilityzones unittests -package testing diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/testing/fixtures.go b/v3/ecl/compute/v2/extensions/availabilityzones/testing/fixtures.go deleted file mode 100644 index 921cad3..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/testing/fixtures.go +++ /dev/null @@ -1,31 +0,0 @@ -package testing - -import ( - az "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/availabilityzones" -) - -const getResponse = ` -{ - "availabilityZoneInfo": [{ - "zoneState": { - "available": true - }, - "hosts": null, - "zoneName": "zone1-groupa" - }, { - "zoneState": { - "available": true - }, - "hosts": null, - "zoneName": "zone1-groupb" - }] -} -` - -var azResult = []az.AvailabilityZone{ - { - Hosts: nil, - ZoneName: "zone1-groupa", - ZoneState: az.ZoneState{Available: true}, - }, -} diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/testing/requests_test.go b/v3/ecl/compute/v2/extensions/availabilityzones/testing/requests_test.go deleted file mode 100644 index 64ef836..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/testing/requests_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - az "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/availabilityzones" - th "github.com/nttcom/eclcloud/v3/testhelper" - - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListAvailabilityZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-availability-zone", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - allPages, err := az.List(fakeclient.ServiceClient()).AllPages() - th.AssertNoErr(t, err) - - actual, err := az.ExtractAvailabilityZones(allPages) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, azResult, actual) -} diff --git a/v3/ecl/compute/v2/extensions/availabilityzones/urls.go b/v3/ecl/compute/v2/extensions/availabilityzones/urls.go deleted file mode 100644 index e62fdd9..0000000 --- a/v3/ecl/compute/v2/extensions/availabilityzones/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package availabilityzones - -import "github.com/nttcom/eclcloud/v3" - -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("os-availability-zone") -} diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/doc.go b/v3/ecl/compute/v2/extensions/bootfromvolume/doc.go deleted file mode 100644 index 3f16cda..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/doc.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Package bootfromvolume extends a server create request with the ability to -specify block device options. This can be used to boot a server from a block -storage volume as well as specify multiple ephemeral disks upon creation. - -Example of Creating a Server From an Image - -This example will boot a server from an image and use a standard ephemeral -disk as the server's root disk. This is virtually no different than creating -a server without using block device mappings. - - blockDevices := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ - BootIndex: 0, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - SourceType: bootfromvolume.SourceImage, - UUID: "image-uuid", - }, - } - - serverCreateOpts := servers.CreateOpts{ - Name: "server_name", - FlavorRef: "flavor-uuid", - ImageRef: "image-uuid", - } - - createOpts := bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: serverCreateOpts, - BlockDevice: blockDevices, - } - - server, err := bootfromvolume.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - -Example of Creating a Server From a New Volume - -This example will create a block storage volume based on the given Image. The -server will use this volume as its root disk. - - blockDevices := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationVolume, - SourceType: bootfromvolume.SourceImage, - UUID: "image-uuid", - VolumeSize: 2, - }, - } - - serverCreateOpts := servers.CreateOpts{ - Name: "server_name", - FlavorRef: "flavor-uuid", - } - - createOpts := bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: serverCreateOpts, - BlockDevice: blockDevices, - } - - server, err := bootfromvolume.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - -Example of Creating a Server From an Existing Volume - -This example will create a server with an existing volume as its root disk. - - blockDevices := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationVolume, - SourceType: bootfromvolume.SourceVolume, - UUID: "volume-uuid", - }, - } - - serverCreateOpts := servers.CreateOpts{ - Name: "server_name", - FlavorRef: "flavor-uuid", - } - - createOpts := bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: serverCreateOpts, - BlockDevice: blockDevices, - } - - server, err := bootfromvolume.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - -Example of Creating a Server with Multiple Ephemeral Disks - -This example will create a server with multiple ephemeral disks. The first -block device will be based off of an existing Image. Each additional -ephemeral disks must have an index of -1. - - blockDevices := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ - BootIndex: 0, - DestinationType: bootfromvolume.DestinationLocal, - DeleteOnTermination: true, - SourceType: bootfromvolume.SourceImage, - UUID: "image-uuid", - VolumeSize: 5, - }, - bootfromvolume.BlockDevice{ - BootIndex: -1, - DestinationType: bootfromvolume.DestinationLocal, - DeleteOnTermination: true, - GuestFormat: "ext4", - SourceType: bootfromvolume.SourceBlank, - VolumeSize: 1, - }, - bootfromvolume.BlockDevice{ - BootIndex: -1, - DestinationType: bootfromvolume.DestinationLocal, - DeleteOnTermination: true, - GuestFormat: "ext4", - SourceType: bootfromvolume.SourceBlank, - VolumeSize: 1, - }, - } - - serverCreateOpts := servers.CreateOpts{ - Name: "server_name", - FlavorRef: "flavor-uuid", - ImageRef: "image-uuid", - } - - createOpts := bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: serverCreateOpts, - BlockDevice: blockDevices, - } - - server, err := bootfromvolume.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } -*/ -package bootfromvolume diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/requests.go b/v3/ecl/compute/v2/extensions/bootfromvolume/requests.go deleted file mode 100644 index 2ba88e9..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/requests.go +++ /dev/null @@ -1,129 +0,0 @@ -package bootfromvolume - -import ( - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" - - "github.com/nttcom/eclcloud/v3" -) - -type ( - // DestinationType represents the type of medium being used as the - // destination of the bootable device. - DestinationType string - - // SourceType represents the type of medium being used as the source of the - // bootable device. - SourceType string -) - -const ( - // DestinationLocal DestinationType is for using an ephemeral disk as the - // destination. - DestinationLocal DestinationType = "local" - - // DestinationVolume DestinationType is for using a volume as the destination. - DestinationVolume DestinationType = "volume" - - // SourceBlank SourceType is for a "blank" or empty source. - SourceBlank SourceType = "blank" - - // SourceImage SourceType is for using images as the source of a block device. - SourceImage SourceType = "image" - - // SourceSnapshot SourceType is for using a volume snapshot as the source of - // a block device. - SourceSnapshot SourceType = "snapshot" - - // SourceVolume SourceType is for using a volume as the source of block - // device. - SourceVolume SourceType = "volume" -) - -// BlockDevice is a structure with options for creating block devices in a -// server. The block device may be created from an image, snapshot, new volume, -// or existing volume. The destination may be a new volume, existing volume -// which will be attached to the instance, ephemeral disk, or boot device. -type BlockDevice struct { - // SourceType must be one of: "volume", "snapshot", "image", or "blank". - SourceType SourceType `json:"source_type" required:"true"` - - // UUID is the unique identifier for the existing volume, snapshot, or - // image (see above). - UUID string `json:"uuid,omitempty"` - - // BootIndex is the boot index. It defaults to 0. - BootIndex int `json:"boot_index"` - - // DeleteOnTermination specifies whether or not to delete the attached volume - // when the server is deleted. Defaults to `false`. - DeleteOnTermination bool `json:"delete_on_termination"` - - // DestinationType is the type that gets created. Possible values are "volume" - // and "local". - DestinationType DestinationType `json:"destination_type,omitempty"` - - // GuestFormat specifies the format of the block device. - GuestFormat string `json:"guest_format,omitempty"` - - // VolumeSize is the size of the volume to create (in gigabytes). This can be - // omitted for existing volumes. - VolumeSize int `json:"volume_size,omitempty"` - - // DeviceType specifies the device type of the block devices. - // Examples of this are disk, cdrom, floppy, lun, etc. - DeviceType string `json:"device_type,omitempty"` - - // DiskBus is the bus type of the block devices. - // Examples of this are ide, usb, virtio, scsi, etc. - DiskBus string `json:"disk_bus,omitempty"` -} - -// CreateOptsExt is a structure that extends the server `CreateOpts` structure -// by allowing for a block device mapping. -type CreateOptsExt struct { - servers.CreateOptsBuilder - BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"` -} - -// ToServerCreateMap adds the block device mapping option to the base server -// creation options. -func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { - base, err := opts.CreateOptsBuilder.ToServerCreateMap() - if err != nil { - return nil, err - } - - if len(opts.BlockDevice) == 0 { - err := eclcloud.ErrMissingInput{} - err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice" - return nil, err - } - - serverMap := base["server"].(map[string]interface{}) - - blockDevice := make([]map[string]interface{}, len(opts.BlockDevice)) - - for i, bd := range opts.BlockDevice { - b, err := eclcloud.BuildRequestBody(bd, "") - if err != nil { - return nil, err - } - blockDevice[i] = b - } - serverMap["block_device_mapping_v2"] = blockDevice - - return base, nil -} - -// Create requests the creation of a server from the given block device mapping. -func Create(client *eclcloud.ServiceClient, opts servers.CreateOptsBuilder) (r servers.CreateResult) { - b, err := opts.ToServerCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 202}, - }) - return -} diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/results.go b/v3/ecl/compute/v2/extensions/bootfromvolume/results.go deleted file mode 100644 index 8630187..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/results.go +++ /dev/null @@ -1,12 +0,0 @@ -package bootfromvolume - -import ( - os "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" -) - -// CreateResult temporarily contains the response from a Create call. -// It embeds the standard servers.CreateResults type and so can be used the -// same way as a standard server request result. -type CreateResult struct { - os.CreateResult -} diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/doc.go b/v3/ecl/compute/v2/extensions/bootfromvolume/testing/doc.go deleted file mode 100644 index 2b6699f..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains bootfromvolume unit tests -package testing diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/fixtures.go b/v3/ecl/compute/v2/extensions/bootfromvolume/testing/fixtures.go deleted file mode 100644 index 98199d6..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/fixtures.go +++ /dev/null @@ -1,275 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/bootfromvolume" - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" -) - -var baseCreateOpts = servers.CreateOpts{ - Name: "createdserver", - FlavorRef: "performance1-1", -} - -var baseCreateOptsWithImageRef = servers.CreateOpts{ - Name: "createdserver", - FlavorRef: "performance1-1", - ImageRef: "asdfasdfasdf", -} - -const expectedNewVolumeRequest = ` -{ - "server": { - "name":"createdserver", - "flavorRef":"performance1-1", - "imageRef":"", - "block_device_mapping_v2":[ - { - "uuid":"123456", - "source_type":"image", - "destination_type":"volume", - "boot_index": 0, - "delete_on_termination": true, - "volume_size": 10 - } - ] - } -} -` - -var newVolumeRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOpts, - BlockDevice: []bootfromvolume.BlockDevice{ - { - UUID: "123456", - SourceType: bootfromvolume.SourceImage, - DestinationType: bootfromvolume.DestinationVolume, - VolumeSize: 10, - DeleteOnTermination: true, - }, - }, -} - -const expectedExistingVolumeRequest = ` -{ - "server": { - "name":"createdserver", - "flavorRef":"performance1-1", - "imageRef":"", - "block_device_mapping_v2":[ - { - "uuid":"123456", - "source_type":"volume", - "destination_type":"volume", - "boot_index": 0, - "delete_on_termination": true - } - ] - } -} -` - -var existingVolumeRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOpts, - BlockDevice: []bootfromvolume.BlockDevice{ - { - UUID: "123456", - SourceType: bootfromvolume.SourceVolume, - DestinationType: bootfromvolume.DestinationVolume, - DeleteOnTermination: true, - }, - }, -} - -const expectedImageRequest = ` -{ - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "boot_index": 0, - "delete_on_termination": true, - "destination_type":"local", - "source_type":"image", - "uuid":"asdfasdfasdf" - } - ] - } -} -` - -var imageRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOptsWithImageRef, - BlockDevice: []bootfromvolume.BlockDevice{ - { - BootIndex: 0, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - SourceType: bootfromvolume.SourceImage, - UUID: "asdfasdfasdf", - }, - }, -} - -const expectedMultiEphemeralRequest = ` -{ - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "boot_index": 0, - "delete_on_termination": true, - "destination_type":"local", - "source_type":"image", - "uuid":"asdfasdfasdf" - }, - { - "boot_index": -1, - "delete_on_termination": true, - "destination_type":"local", - "guest_format":"ext4", - "source_type":"blank", - "volume_size": 1 - }, - { - "boot_index": -1, - "delete_on_termination": true, - "destination_type":"local", - "guest_format":"ext4", - "source_type":"blank", - "volume_size": 1 - } - ] - } -} -` - -var multiEphemeralRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOptsWithImageRef, - BlockDevice: []bootfromvolume.BlockDevice{ - { - BootIndex: 0, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - SourceType: bootfromvolume.SourceImage, - UUID: "asdfasdfasdf", - }, - { - BootIndex: -1, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - GuestFormat: "ext4", - SourceType: bootfromvolume.SourceBlank, - VolumeSize: 1, - }, - { - BootIndex: -1, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - GuestFormat: "ext4", - SourceType: bootfromvolume.SourceBlank, - VolumeSize: 1, - }, - }, -} - -const expectedImageAndNewVolumeRequest = ` -{ - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "boot_index": 0, - "delete_on_termination": true, - "destination_type":"local", - "source_type":"image", - "uuid":"asdfasdfasdf" - }, - { - "boot_index": 1, - "delete_on_termination": true, - "destination_type":"volume", - "source_type":"blank", - "volume_size": 1, - "device_type": "disk", - "disk_bus": "scsi" - } - ] - } -} -` - -var imageAndNewVolumeRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOptsWithImageRef, - BlockDevice: []bootfromvolume.BlockDevice{ - { - BootIndex: 0, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - SourceType: bootfromvolume.SourceImage, - UUID: "asdfasdfasdf", - }, - { - BootIndex: 1, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationVolume, - SourceType: bootfromvolume.SourceBlank, - VolumeSize: 1, - DeviceType: "disk", - DiskBus: "scsi", - }, - }, -} - -const expectedImageAndExistingVolumeRequest = ` -{ - "server": { - "name": "createdserver", - "imageRef": "asdfasdfasdf", - "flavorRef": "performance1-1", - "block_device_mapping_v2":[ - { - "boot_index": 0, - "delete_on_termination": true, - "destination_type":"local", - "source_type":"image", - "uuid":"asdfasdfasdf" - }, - { - "boot_index": 1, - "delete_on_termination": true, - "destination_type":"volume", - "source_type":"volume", - "uuid":"123456", - "volume_size": 1 - } - ] - } -} -` - -var imageAndExistingVolumeRequest = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: baseCreateOptsWithImageRef, - BlockDevice: []bootfromvolume.BlockDevice{ - { - BootIndex: 0, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationLocal, - SourceType: bootfromvolume.SourceImage, - UUID: "asdfasdfasdf", - }, - { - BootIndex: 1, - DeleteOnTermination: true, - DestinationType: bootfromvolume.DestinationVolume, - SourceType: bootfromvolume.SourceVolume, - UUID: "123456", - VolumeSize: 1, - }, - }, -} diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/requests_test.go b/v3/ecl/compute/v2/extensions/bootfromvolume/testing/requests_test.go deleted file mode 100644 index 3178a5e..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/testing/requests_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package testing - -import ( - "testing" - - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestBootFromNewVolume(t *testing.T) { - - actual, err := newVolumeRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedNewVolumeRequest, actual) -} - -func TestBootFromExistingVolume(t *testing.T) { - actual, err := existingVolumeRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedExistingVolumeRequest, actual) -} - -func TestBootFromImage(t *testing.T) { - actual, err := imageRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedImageRequest, actual) -} - -func TestCreateMultiEphemeralOpts(t *testing.T) { - actual, err := multiEphemeralRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedMultiEphemeralRequest, actual) -} - -func TestAttachNewVolume(t *testing.T) { - actual, err := imageAndNewVolumeRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedImageAndNewVolumeRequest, actual) -} - -func TestAttachExistingVolume(t *testing.T) { - actual, err := imageAndExistingVolumeRequest.ToServerCreateMap() - th.AssertNoErr(t, err) - th.CheckJSONEquals(t, expectedImageAndExistingVolumeRequest, actual) -} diff --git a/v3/ecl/compute/v2/extensions/bootfromvolume/urls.go b/v3/ecl/compute/v2/extensions/bootfromvolume/urls.go deleted file mode 100644 index 69c85ab..0000000 --- a/v3/ecl/compute/v2/extensions/bootfromvolume/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package bootfromvolume - -import "github.com/nttcom/eclcloud/v3" - -func createURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("os-volumes_boot") -} diff --git a/v3/ecl/compute/v2/extensions/keypairs/doc.go b/v3/ecl/compute/v2/extensions/keypairs/doc.go deleted file mode 100644 index 24c4607..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/doc.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Package keypairs provides the ability to manage key pairs as well as create -servers with a specified key pair. - -Example to List Key Pairs - - allPages, err := keypairs.List(computeClient).AllPages() - if err != nil { - panic(err) - } - - allKeyPairs, err := keypairs.ExtractKeyPairs(allPages) - if err != nil { - panic(err) - } - - for _, kp := range allKeyPairs { - fmt.Printf("%+v\n", kp) - } - -Example to Create a Key Pair - - createOpts := keypairs.CreateOpts{ - Name: "keypair-name", - } - - keypair, err := keypairs.Create(computeClient, createOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v", keypair) - -Example to Import a Key Pair - - createOpts := keypairs.CreateOpts{ - Name: "keypair-name", - PublicKey: "public-key", - } - - keypair, err := keypairs.Create(computeClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Key Pair - - err := keypairs.Delete(computeClient, "keypair-name").ExtractErr() - if err != nil { - panic(err) - } - -Example to Create a Server With a Key Pair - - serverCreateOpts := servers.CreateOpts{ - Name: "server_name", - ImageRef: "image-uuid", - FlavorRef: "flavor-uuid", - } - - createOpts := keypairs.CreateOptsExt{ - CreateOptsBuilder: serverCreateOpts, - KeyName: "keypair-name", - } - - server, err := servers.Create(computeClient, createOpts).Extract() - if err != nil { - panic(err) - } -*/ -package keypairs diff --git a/v3/ecl/compute/v2/extensions/keypairs/requests.go b/v3/ecl/compute/v2/extensions/keypairs/requests.go deleted file mode 100644 index e7c3b33..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/requests.go +++ /dev/null @@ -1,86 +0,0 @@ -package keypairs - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CreateOptsExt adds a KeyPair option to the base CreateOpts. -type CreateOptsExt struct { - servers.CreateOptsBuilder - - // KeyName is the name of the key pair. - KeyName string `json:"key_name,omitempty"` -} - -// ToServerCreateMap adds the key_name to the base server creation options. -func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { - base, err := opts.CreateOptsBuilder.ToServerCreateMap() - if err != nil { - return nil, err - } - - if opts.KeyName == "" { - return base, nil - } - - serverMap := base["server"].(map[string]interface{}) - serverMap["key_name"] = opts.KeyName - - return base, nil -} - -// List returns a Pager that allows you to iterate over a collection of KeyPairs. -func List(client *eclcloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return KeyPairPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToKeyPairCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies KeyPair creation or import parameters. -type CreateOpts struct { - // Name is a friendly name to refer to this KeyPair in other services. - Name string `json:"name" required:"true"` - - // PublicKey [optional] is a pregenerated OpenSSH-formatted public key. - // If provided, this key will be imported and no new key will be created. - PublicKey string `json:"public_key,omitempty"` -} - -// ToKeyPairCreateMap constructs a request body from CreateOpts. -func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "keypair") -} - -// Create requests the creation of a new KeyPair on the server, or to import a -// pre-existing keypair. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToKeyPairCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get returns public data about a previously uploaded KeyPair. -func Get(client *eclcloud.ServiceClient, name string) (r GetResult) { - _, r.Err = client.Get(getURL(client, name), &r.Body, nil) - return -} - -// Delete requests the deletion of a previous stored KeyPair from the server. -func Delete(client *eclcloud.ServiceClient, name string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, name), nil) - return -} diff --git a/v3/ecl/compute/v2/extensions/keypairs/results.go b/v3/ecl/compute/v2/extensions/keypairs/results.go deleted file mode 100644 index 596f973..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/results.go +++ /dev/null @@ -1,91 +0,0 @@ -package keypairs - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// KeyPair is an SSH key known to the Enterprise Cloud that is available to be -// injected into servers. -type KeyPair struct { - // Name is used to refer to this keypair from other services within this - // region. - Name string `json:"name"` - - // Fingerprint is a short sequence of bytes that can be used to authenticate - // or validate a longer public key. - Fingerprint string `json:"fingerprint"` - - // PublicKey is the public key from this pair, in OpenSSH format. - // "ssh-rsa AAAAB3Nz..." - PublicKey string `json:"public_key"` - - // PrivateKey is the private key from this pair, in PEM format. - // "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..." - // It is only present if this KeyPair was just returned from a Create call. - PrivateKey string `json:"private_key"` - - // UserID is the user who owns this KeyPair. - UserID string `json:"user_id"` -} - -// KeyPairPage stores a single page of all KeyPair results from a List call. -// Use the ExtractKeyPairs function to convert the results to a slice of -// KeyPairs. -type KeyPairPage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a KeyPairPage is empty. -func (page KeyPairPage) IsEmpty() (bool, error) { - ks, err := ExtractKeyPairs(page) - return len(ks) == 0, err -} - -// ExtractKeyPairs interprets a page of results as a slice of KeyPairs. -func ExtractKeyPairs(r pagination.Page) ([]KeyPair, error) { - type pair struct { - KeyPair KeyPair `json:"keypair"` - } - var s struct { - KeyPairs []pair `json:"keypairs"` - } - err := (r.(KeyPairPage)).ExtractInto(&s) - results := make([]KeyPair, len(s.KeyPairs)) - for i, pair := range s.KeyPairs { - results[i] = pair.KeyPair - } - return results, err -} - -type keyPairResult struct { - eclcloud.Result -} - -// Extract is a method that attempts to interpret any KeyPair resource response -// as a KeyPair struct. -func (r keyPairResult) Extract() (*KeyPair, error) { - var s struct { - KeyPair *KeyPair `json:"keypair"` - } - err := r.ExtractInto(&s) - return s.KeyPair, err -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a KeyPair. -type CreateResult struct { - keyPairResult -} - -// GetResult is the response from a Get operation. Call its Extract method to -// interpret it as a KeyPair. -type GetResult struct { - keyPairResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/compute/v2/extensions/keypairs/testing/doc.go b/v3/ecl/compute/v2/extensions/keypairs/testing/doc.go deleted file mode 100644 index bf23f88..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains keypairs unit tests -package testing diff --git a/v3/ecl/compute/v2/extensions/keypairs/testing/fixtures.go b/v3/ecl/compute/v2/extensions/keypairs/testing/fixtures.go deleted file mode 100644 index 17776b1..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/testing/fixtures.go +++ /dev/null @@ -1,96 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/keypairs" -) - -const listOutput = ` -{ - "keypairs": [ - { - "keypair": { - "fingerprint": "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a", - "name": "firstkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n" - } - }, - { - "keypair": { - "fingerprint": "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - "name": "secondkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n" - } - } - ] -} -` - -const createRequest = `{ "keypair": { "name": "createdkey" } }` -const createResponse = ` -{ - "keypair": { - "fingerprint": "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - "name": "createdkey", - "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7\nDUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ\n9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5QIDAQAB\nAoGAE5XO1mDhORy9COvsg+kYPUhB1GsCYxh+v88wG7HeFDKBY6KUc/Kxo6yoGn5T\nTjRjekyi2KoDZHz4VlIzyZPwFS4I1bf3oCunVoAKzgLdmnTtvRNMC5jFOGc2vUgP\n9bSyRj3S1R4ClVk2g0IDeagko/jc8zzLEYuIK+fbkds79YECQQDt3vcevgegnkga\ntF4NsDmmBPRkcSHCqrANP/7vFcBQN3czxeYYWX3DK07alu6GhH1Y4sHbdm616uU0\nll7xbDzxAkEAzAtN2IyftNygV2EGiaGgqLyo/tD9+Vui2qCQplqe4jvWh/5Sparl\nOjmKo+uAW+hLrLVMnHzRWxbWU8hirH5FNQJATO+ZxCK4etXXAnQmG41NCAqANWB2\nB+2HJbH2NcQ2QHvAHUm741JGn/KI/aBlo7KEjFRDWUVUB5ji64BbUwCsMQJBAIku\nLGcjnBf/oLk+XSPZC2eGd2Ph5G5qYmH0Q2vkTx+wtTn3DV+eNsDfgMtWAJVJ5t61\ngU1QSXyhLPVlKpnnxuUCQC+xvvWjWtsLaFtAsZywJiqLxQzHts8XLGZptYJ5tLWV\nrtmYtBcJCN48RrgQHry/xWYeA4K/AFQpXfNPgprQ96Q=\n-----END RSA PRIVATE KEY-----\n", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", - "user_id": "fake" - } -} -` - -const getResponse = ` -{ - "keypair": { - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n", - "name": "firstkey", - "fingerprint": "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a" - } -} -` - -const importRequest = ` -{ - "keypair": { - "name": "importedkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova" - } -}` -const importResponse = ` -{ - "keypair": { - "fingerprint": "1e:2c:9b:56:79:4b:45:77:f9:ca:7a:98:2c:b0:d5:3c", - "name": "importedkey", - "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - "user_id": "fake" - } -} -` - -var firstKeyPair = keypairs.KeyPair{ - Name: "firstkey", - Fingerprint: "15:b0:f8:b3:f9:48:63:71:cf:7b:5b:38:6d:44:2d:4a", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+Eo/RZRngaGTkFs7I62ZjsIlO79KklKbMXi8F+KITD4bVQHHn+kV+4gRgkgCRbdoDqoGfpaDFs877DYX9n4z6FrAIZ4PES8TNKhatifpn9NdQYWA+IkU8CuvlEKGuFpKRi/k7JLos/gHi2hy7QUwgtRvcefvD/vgQZOVw/mGR9Q== Generated by Nova\n", -} - -var secondKeyPair = keypairs.KeyPair{ - Name: "secondkey", - Fingerprint: "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", -} - -var expectedKeyPairSlice = []keypairs.KeyPair{firstKeyPair, secondKeyPair} - -var createdKeyPair = keypairs.KeyPair{ - Name: "createdkey", - Fingerprint: "35:9d:d0:c3:4a:80:d3:d8:86:f1:ca:f7:df:c4:f9:d8", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7DUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5Q== Generated by Nova\n", - PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQC9mC3WZN9UGLxgPBpP7H5jZMc6pKwOoSgre8yun6REFktn/Kz7\nDUt9jaR1UJyRzHxITfCfAIgSxPdGqB/oF1suMyWgu5i0625vavLB5z5kC8Hq3qZJ\n9zJO1poE1kyD+htiTtPWJ88e12xuH2XB/CZN9OpEiF98hAagiOE0EnOS5QIDAQAB\nAoGAE5XO1mDhORy9COvsg+kYPUhB1GsCYxh+v88wG7HeFDKBY6KUc/Kxo6yoGn5T\nTjRjekyi2KoDZHz4VlIzyZPwFS4I1bf3oCunVoAKzgLdmnTtvRNMC5jFOGc2vUgP\n9bSyRj3S1R4ClVk2g0IDeagko/jc8zzLEYuIK+fbkds79YECQQDt3vcevgegnkga\ntF4NsDmmBPRkcSHCqrANP/7vFcBQN3czxeYYWX3DK07alu6GhH1Y4sHbdm616uU0\nll7xbDzxAkEAzAtN2IyftNygV2EGiaGgqLyo/tD9+Vui2qCQplqe4jvWh/5Sparl\nOjmKo+uAW+hLrLVMnHzRWxbWU8hirH5FNQJATO+ZxCK4etXXAnQmG41NCAqANWB2\nB+2HJbH2NcQ2QHvAHUm741JGn/KI/aBlo7KEjFRDWUVUB5ji64BbUwCsMQJBAIku\nLGcjnBf/oLk+XSPZC2eGd2Ph5G5qYmH0Q2vkTx+wtTn3DV+eNsDfgMtWAJVJ5t61\ngU1QSXyhLPVlKpnnxuUCQC+xvvWjWtsLaFtAsZywJiqLxQzHts8XLGZptYJ5tLWV\nrtmYtBcJCN48RrgQHry/xWYeA4K/AFQpXfNPgprQ96Q=\n-----END RSA PRIVATE KEY-----\n", - UserID: "fake", -} - -var importedKeyPair = keypairs.KeyPair{ - Name: "importedkey", - Fingerprint: "1e:2c:9b:56:79:4b:45:77:f9:ca:7a:98:2c:b0:d5:3c", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - UserID: "fake", -} diff --git a/v3/ecl/compute/v2/extensions/keypairs/testing/requests_test.go b/v3/ecl/compute/v2/extensions/keypairs/testing/requests_test.go deleted file mode 100644 index 7e4bda6..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/testing/requests_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/keypairs" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listOutput) - }) - - count := 0 - err := keypairs.List(fakeclient.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := keypairs.ExtractKeyPairs(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedKeyPairSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreateKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - actual, err := keypairs.Create(fakeclient.ServiceClient(), keypairs.CreateOpts{ - Name: "createdkey", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdKeyPair, actual) -} - -func TestImportKeypair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, importRequest) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, importResponse) - }) - - actual, err := keypairs.Create(fakeclient.ServiceClient(), keypairs.CreateOpts{ - Name: "importedkey", - PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &importedKeyPair, actual) -} - -func TestGetKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs/firstkey", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := keypairs.Get(fakeclient.ServiceClient(), "firstkey").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &firstKeyPair, actual) -} - -func TestDeleteKeyPair(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/os-keypairs/deletedkey", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusAccepted) - }) - - err := keypairs.Delete(fakeclient.ServiceClient(), "deletedkey").ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/v3/ecl/compute/v2/extensions/keypairs/urls.go b/v3/ecl/compute/v2/extensions/keypairs/urls.go deleted file mode 100644 index 2637342..0000000 --- a/v3/ecl/compute/v2/extensions/keypairs/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package keypairs - -import "github.com/nttcom/eclcloud/v3" - -const resourcePath = "os-keypairs" - -func resourceURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL(resourcePath) -} - -func listURL(c *eclcloud.ServiceClient) string { - return resourceURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return resourceURL(c) -} - -func getURL(c *eclcloud.ServiceClient, name string) string { - return c.ServiceURL(resourcePath, name) -} - -func deleteURL(c *eclcloud.ServiceClient, name string) string { - return getURL(c, name) -} diff --git a/v3/ecl/compute/v2/extensions/startstop/doc.go b/v3/ecl/compute/v2/extensions/startstop/doc.go deleted file mode 100644 index 65c4c5a..0000000 --- a/v3/ecl/compute/v2/extensions/startstop/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Package startstop provides functionality to start and stop servers that have -been provisioned by the Enterprise Cloud Compute service. - -Example to Stop and Start a Server - - serverID := "47b6b7b7-568d-40e4-868c-d5c41735532e" - - err := startstop.Stop(computeClient, serverID).ExtractErr() - if err != nil { - panic(err) - } - - err := startstop.Start(computeClient, serverID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package startstop diff --git a/v3/ecl/compute/v2/extensions/startstop/requests.go b/v3/ecl/compute/v2/extensions/startstop/requests.go deleted file mode 100644 index dc11573..0000000 --- a/v3/ecl/compute/v2/extensions/startstop/requests.go +++ /dev/null @@ -1,19 +0,0 @@ -package startstop - -import "github.com/nttcom/eclcloud/v3" - -func actionURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "action") -} - -// Start is the operation responsible for starting a Compute server. -func Start(client *eclcloud.ServiceClient, id string) (r StartResult) { - _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-start": nil}, nil, nil) - return -} - -// Stop is the operation responsible for stopping a Compute server. -func Stop(client *eclcloud.ServiceClient, id string) (r StopResult) { - _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-stop": nil}, nil, nil) - return -} diff --git a/v3/ecl/compute/v2/extensions/startstop/results.go b/v3/ecl/compute/v2/extensions/startstop/results.go deleted file mode 100644 index 5eec687..0000000 --- a/v3/ecl/compute/v2/extensions/startstop/results.go +++ /dev/null @@ -1,15 +0,0 @@ -package startstop - -import "github.com/nttcom/eclcloud/v3" - -// StartResult is the response from a Start operation. Call its ExtractErr -// method to determine if the request succeeded or failed. -type StartResult struct { - eclcloud.ErrResult -} - -// StopResult is the response from Stop operation. Call its ExtractErr -// method to determine if the request succeeded or failed. -type StopResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/compute/v2/extensions/startstop/testing/doc.go b/v3/ecl/compute/v2/extensions/startstop/testing/doc.go deleted file mode 100644 index ee45964..0000000 --- a/v3/ecl/compute/v2/extensions/startstop/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains startstop unit tests -package testing diff --git a/v3/ecl/compute/v2/extensions/startstop/testing/requests_test.go b/v3/ecl/compute/v2/extensions/startstop/testing/requests_test.go deleted file mode 100644 index 1bea2fc..0000000 --- a/v3/ecl/compute/v2/extensions/startstop/testing/requests_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package testing - -import ( - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/startstop" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -const serverID = "645b787e-7fbb-4111-a217-63a2882930f2" - -func TestServerStart(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/servers/" + serverID + "/action" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{"os-start": null}`) - w.WriteHeader(http.StatusAccepted) - }) - - err := startstop.Start(client.ServiceClient(), serverID).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestServerStop(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/servers/" + serverID + "/action" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, `{"os-stop": null}`) - w.WriteHeader(http.StatusAccepted) - }) - - err := startstop.Stop(client.ServiceClient(), serverID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/v3/ecl/compute/v2/extensions/volumeattach/doc.go b/v3/ecl/compute/v2/extensions/volumeattach/doc.go deleted file mode 100644 index 484eb20..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/doc.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Package volumeattach provides the ability to attach and detach volumes -from servers. - -Example to Attach a Volume - - serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d" - volumeID := "87463836-f0e2-4029-abf6-20c8892a3103" - - createOpts := volumeattach.CreateOpts{ - Device: "/dev/vdc", - VolumeID: volumeID, - } - - result, err := volumeattach.Create(computeClient, serverID, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Detach a Volume - - serverID := "7ac8686c-de71-4acb-9600-ec18b1a1ed6d" - attachmentID := "ed081613-1c9b-4231-aa5e-ebfd4d87f983" - - err := volumeattach.Delete(computeClient, serverID, attachmentID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package volumeattach diff --git a/v3/ecl/compute/v2/extensions/volumeattach/requests.go b/v3/ecl/compute/v2/extensions/volumeattach/requests.go deleted file mode 100644 index bd07d35..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/requests.go +++ /dev/null @@ -1,60 +0,0 @@ -package volumeattach - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List returns a Pager that allows you to iterate over a collection of -// VolumeAttachments. -func List(client *eclcloud.ServiceClient, serverID string) pagination.Pager { - return pagination.NewPager(client, listURL(client, serverID), func(r pagination.PageResult) pagination.Page { - return VolumeAttachmentPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder allows extensions to add parameters to the Create request. -type CreateOptsBuilder interface { - ToVolumeAttachmentCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies volume attachment creation or import parameters. -type CreateOpts struct { - // Device is the device that the volume will attach to the instance as. - // Omit for "auto". - Device string `json:"device,omitempty"` - - // VolumeID is the ID of the volume to attach to the instance. - VolumeID string `json:"volumeId" required:"true"` -} - -// ToVolumeAttachmentCreateMap constructs a request body from CreateOpts. -func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "volumeAttachment") -} - -// Create requests the creation of a new volume attachment on the server. -func Create(client *eclcloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToVolumeAttachmentCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client, serverID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get returns public data about a previously created VolumeAttachment. -func Get(client *eclcloud.ServiceClient, serverID, attachmentID string) (r GetResult) { - _, r.Err = client.Get(getURL(client, serverID, attachmentID), &r.Body, nil) - return -} - -// Delete requests the deletion of a previous stored VolumeAttachment from -// the server. -func Delete(client *eclcloud.ServiceClient, serverID, attachmentID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, serverID, attachmentID), nil) - return -} diff --git a/v3/ecl/compute/v2/extensions/volumeattach/results.go b/v3/ecl/compute/v2/extensions/volumeattach/results.go deleted file mode 100644 index 0b7e355..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/results.go +++ /dev/null @@ -1,77 +0,0 @@ -package volumeattach - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// VolumeAttachment contains attachment information between a volume -// and server. -type VolumeAttachment struct { - // ID is a unique id of the attachment. - ID string `json:"id"` - - // Device is what device the volume is attached as. - Device string `json:"device"` - - // VolumeID is the ID of the attached volume. - VolumeID string `json:"volumeId"` - - // ServerID is the ID of the instance that has the volume attached. - ServerID string `json:"serverId"` -} - -// VolumeAttachmentPage stores a single page all of VolumeAttachment -// results from a List call. -type VolumeAttachmentPage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a VolumeAttachmentPage is empty. -func (page VolumeAttachmentPage) IsEmpty() (bool, error) { - va, err := ExtractVolumeAttachments(page) - return len(va) == 0, err -} - -// ExtractVolumeAttachments interprets a page of results as a slice of -// VolumeAttachment. -func ExtractVolumeAttachments(r pagination.Page) ([]VolumeAttachment, error) { - var s struct { - VolumeAttachments []VolumeAttachment `json:"volumeAttachments"` - } - err := (r.(VolumeAttachmentPage)).ExtractInto(&s) - return s.VolumeAttachments, err -} - -// VolumeAttachmentResult is the result from a volume attachment operation. -type VolumeAttachmentResult struct { - eclcloud.Result -} - -// Extract is a method that attempts to interpret any VolumeAttachment resource -// response as a VolumeAttachment struct. -func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) { - var s struct { - VolumeAttachment *VolumeAttachment `json:"volumeAttachment"` - } - err := r.ExtractInto(&s) - return s.VolumeAttachment, err -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a VolumeAttachment. -type CreateResult struct { - VolumeAttachmentResult -} - -// GetResult is the response from a Get operation. Call its Extract method to -// interpret it as a VolumeAttachment. -type GetResult struct { - VolumeAttachmentResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/compute/v2/extensions/volumeattach/testing/doc.go b/v3/ecl/compute/v2/extensions/volumeattach/testing/doc.go deleted file mode 100644 index 7d35174..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains volumeattach unit tests -package testing diff --git a/v3/ecl/compute/v2/extensions/volumeattach/testing/fixtures.go b/v3/ecl/compute/v2/extensions/volumeattach/testing/fixtures.go deleted file mode 100644 index 4790c94..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/testing/fixtures.go +++ /dev/null @@ -1,86 +0,0 @@ -package testing - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/volumeattach" -) - -const serverID = "4d8c3732-a248-40ed-bebc-539a6ffd25c0" -const volumeID = "a26887c6-c47b-4654-abb5-dfadf7d3f803" -const attachID = volumeID - -var listResponse = fmt.Sprintf(` -{ - "volumeAttachments": [ - { - "device": "/dev/vdd", - "id": "%s", - "serverId": "%s", - "volumeId": "%s" - }, - { - "device": "/dev/vdc", - "id": "%s", - "serverId": "%s", - "volumeId": "%s" - } - ] -}`, - volumeID, serverID, volumeID, - volumeID, serverID, volumeID, -) - -var expectedVolumeAttachmentSlice = []volumeattach.VolumeAttachment{ - firstVolumeAttachment, - secondVolumeAttachment, -} - -var firstVolumeAttachment = volumeattach.VolumeAttachment{ - Device: "/dev/vdd", - ID: volumeID, - ServerID: serverID, - VolumeID: volumeID, -} - -var secondVolumeAttachment = volumeattach.VolumeAttachment{ - Device: "/dev/vdc", - ID: volumeID, - ServerID: serverID, - VolumeID: volumeID, -} - -var getResponse = fmt.Sprintf(` -{ - "volumeAttachment": { - "device": "/dev/vdc", - "id": "%s", - "serverId": "%s", - "volumeId": "%s" - } -}`, volumeID, serverID, volumeID) - -var createRequest = fmt.Sprintf(` -{ - "volumeAttachment": { - "volumeId": "%s", - "device": "/dev/vdc" - } -}`, volumeID) - -var createResponse = fmt.Sprintf(` -{ - "volumeAttachment": { - "device": "/dev/vdc", - "id": "%s", - "serverId": "%s", - "volumeId": "%s" - } -}`, volumeID, serverID, volumeID) - -var createdVolumeAttachment = volumeattach.VolumeAttachment{ - Device: "/dev/vdc", - ID: volumeID, - ServerID: serverID, - VolumeID: volumeID, -} diff --git a/v3/ecl/compute/v2/extensions/volumeattach/testing/requests_test.go b/v3/ecl/compute/v2/extensions/volumeattach/testing/requests_test.go deleted file mode 100644 index 54fcd59..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/testing/requests_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/extensions/volumeattach" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListVolumeAttachment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s/os-volume_attachments", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := volumeattach.List(fakeclient.ServiceClient(), serverID).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := volumeattach.ExtractVolumeAttachments(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedVolumeAttachmentSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestCreateVolumeAttachment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s/os-volume_attachments", serverID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - actual, err := volumeattach.Create(fakeclient.ServiceClient(), serverID, volumeattach.CreateOpts{ - Device: "/dev/vdc", - VolumeID: volumeID, - }).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdVolumeAttachment, actual) -} - -func TestGetVolumeAttachment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s/os-volume_attachments/%s", serverID, volumeID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := volumeattach.Get(fakeclient.ServiceClient(), serverID, attachID).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &secondVolumeAttachment, actual) -} - -func TestDeleteVolumeAttachment(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/servers/%s/os-volume_attachments/%s", serverID, volumeID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusAccepted) - }) - - err := volumeattach.Delete(fakeclient.ServiceClient(), serverID, attachID).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/v3/ecl/compute/v2/extensions/volumeattach/urls.go b/v3/ecl/compute/v2/extensions/volumeattach/urls.go deleted file mode 100644 index ff959a0..0000000 --- a/v3/ecl/compute/v2/extensions/volumeattach/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package volumeattach - -import "github.com/nttcom/eclcloud/v3" - -const resourcePath = "os-volume_attachments" - -func resourceURL(c *eclcloud.ServiceClient, serverID string) string { - return c.ServiceURL("servers", serverID, resourcePath) -} - -func listURL(c *eclcloud.ServiceClient, serverID string) string { - return resourceURL(c, serverID) -} - -func createURL(c *eclcloud.ServiceClient, serverID string) string { - return resourceURL(c, serverID) -} - -func getURL(c *eclcloud.ServiceClient, serverID, aID string) string { - return c.ServiceURL("servers", serverID, resourcePath, aID) -} - -func deleteURL(c *eclcloud.ServiceClient, serverID, aID string) string { - return getURL(c, serverID, aID) -} diff --git a/v3/ecl/compute/v2/flavors/doc.go b/v3/ecl/compute/v2/flavors/doc.go deleted file mode 100644 index e4e2959..0000000 --- a/v3/ecl/compute/v2/flavors/doc.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Package flavors provides information and interaction with the flavor API -in the Enterprise Cloud Compute service. - -A flavor is an available hardware configuration for a server. Each flavor -has a unique combination of disk space, memory capacity and priority for CPU -time. - -Example to List Flavors - - listOpts := flavors.ListOpts{ - AccessType: flavors.PublicAccess, - } - - allPages, err := flavors.ListDetail(computeClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allFlavors, err := flavors.ExtractFlavors(allPages) - if err != nil { - panic(err) - } - - for _, flavor := range allFlavors { - fmt.Printf("%+v\n", flavor) - } - -Example to Create a Flavor - - createOpts := flavors.CreateOpts{ - ID: "1", - Name: "m1.tiny", - Disk: eclcloud.IntToPointer(1), - RAM: 512, - VCPUs: 1, - RxTxFactor: 1.0, - } - - flavor, err := flavors.Create(computeClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to List Flavor Access - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - allPages, err := flavors.ListAccesses(computeClient, flavorID).AllPages() - if err != nil { - panic(err) - } - - allAccesses, err := flavors.ExtractAccesses(allPages) - if err != nil { - panic(err) - } - - for _, access := range allAccesses { - fmt.Printf("%+v", access) - } - -Example to Grant Access to a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - accessOpts := flavors.AddAccessOpts{ - Tenant: "15153a0979884b59b0592248ef947921", - } - - accessList, err := flavors.AddAccess(computeClient, flavor.ID, accessOpts).Extract() - if err != nil { - panic(err) - } - -Example to Remove/Revoke Access to a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - accessOpts := flavors.RemoveAccessOpts{ - Tenant: "15153a0979884b59b0592248ef947921", - } - - accessList, err := flavors.RemoveAccess(computeClient, flavor.ID, accessOpts).Extract() - if err != nil { - panic(err) - } - -Example to Create Extra Specs for a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - createOpts := flavors.ExtraSpecsOpts{ - "hw:cpu_policy": "CPU-POLICY", - "hw:cpu_thread_policy": "CPU-THREAD-POLICY", - } - createdExtraSpecs, err := flavors.CreateExtraSpecs(computeClient, flavorID, createOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v", createdExtraSpecs) - -Example to Get Extra Specs for a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - extraSpecs, err := flavors.ListExtraSpecs(computeClient, flavorID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v", extraSpecs) - -Example to Update Extra Specs for a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - - updateOpts := flavors.ExtraSpecsOpts{ - "hw:cpu_thread_policy": "CPU-THREAD-POLICY-UPDATED", - } - updatedExtraSpec, err := flavors.UpdateExtraSpec(computeClient, flavorID, updateOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v", updatedExtraSpec) - -Example to Delete an Extra Spec for a Flavor - - flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b" - err := flavors.DeleteExtraSpec(computeClient, flavorID, "hw:cpu_thread_policy").ExtractErr() - if err != nil { - panic(err) - } -*/ -package flavors diff --git a/v3/ecl/compute/v2/flavors/requests.go b/v3/ecl/compute/v2/flavors/requests.go deleted file mode 100644 index 6803866..0000000 --- a/v3/ecl/compute/v2/flavors/requests.go +++ /dev/null @@ -1,357 +0,0 @@ -package flavors - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToFlavorListQuery() (string, error) -} - -/* - AccessType maps to Enterprise Cloud's Flavor.is_public field. Although the is_public - field is boolean, the request options are ternary, which is why AccessType is - a string. The following values are allowed: - - The AccessType arguement is optional, and if it is not supplied, Enterprise Cloud - returns the PublicAccess flavors. -*/ -type AccessType string - -const ( - // PublicAccess returns public flavors and private flavors associated with - // that project. - PublicAccess AccessType = "true" - - // PrivateAccess (admin only) returns private flavors, across all projects. - PrivateAccess AccessType = "false" - - // AllAccess (admin only) returns public and private flavors across all - // projects. - AllAccess AccessType = "None" -) - -/* - ListOpts filters the results returned by the List() function. - For example, a flavor with a minDisk field of 10 will not be returned if you - specify MinDisk set to 20. - - Typically, software will use the last ID of the previous call to List to set - the Marker for the current call. -*/ -type ListOpts struct { - // ChangesSince, if provided, instructs List to return only those things which - // have changed since the timestamp provided. - ChangesSince string `q:"changes-since"` - - // MinDisk and MinRAM, if provided, elides flavors which do not meet your - // criteria. - MinDisk int `q:"minDisk"` - MinRAM int `q:"minRam"` - - // SortDir allows to select sort direction. - // It can be "asc" or "desc" (default). - SortDir string `q:"sort_dir"` - - // SortKey allows to sort by one of the flavors attributes. - // Default is flavorid. - SortKey string `q:"sort_key"` - - // Marker and Limit control paging. - // Marker instructs List where to start listing from. - Marker string `q:"marker"` - - // Limit instructs List to refrain from sending excessively large lists of - // flavors. - Limit int `q:"limit"` - - // AccessType, if provided, instructs List which set of flavors to return. - // If IsPublic not provided, flavors for the current project are returned. - AccessType AccessType `q:"is_public"` -} - -// ToFlavorListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToFlavorListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// ListDetail instructs Enterprise Cloud to provide a list of flavors. -// You may provide criteria by which List curtails its results for easier -// processing. -func ListDetail(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToFlavorListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return FlavorPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// type CreateOptsBuilder interface { -// ToFlavorCreateMap() (map[string]interface{}, error) -// } - -// // CreateOpts specifies parameters used for creating a flavor. -// type CreateOpts struct { -// // Name is the name of the flavor. -// Name string `json:"name" required:"true"` - -// // RAM is the memory of the flavor, measured in MB. -// RAM int `json:"ram" required:"true"` - -// // VCPUs is the number of vcpus for the flavor. -// VCPUs int `json:"vcpus" required:"true"` - -// // Disk the amount of root disk space, measured in GB. -// Disk *int `json:"disk" required:"true"` - -// // ID is a unique ID for the flavor. -// ID string `json:"id,omitempty"` - -// // Swap is the amount of swap space for the flavor, measured in MB. -// Swap *int `json:"swap,omitempty"` - -// // RxTxFactor alters the network bandwidth of a flavor. -// RxTxFactor float64 `json:"rxtx_factor,omitempty"` - -// // IsPublic flags a flavor as being available to all projects or not. -// IsPublic *bool `json:"os-flavor-access:is_public,omitempty"` - -// // Ephemeral is the amount of ephemeral disk space, measured in GB. -// Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"` -// } - -// // ToFlavorCreateMap constructs a request body from CreateOpts. -// func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) { -// return eclcloud.BuildRequestBody(opts, "flavor") -// } - -// // Create requests the creation of a new flavor. -// func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { -// b, err := opts.ToFlavorCreateMap() -// if err != nil { -// r.Err = err -// return -// } -// _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ -// OkCodes: []int{200, 201}, -// }) -// return -// } - -// Get retrieves details of a single flavor. Use ExtractFlavor to convert its -// result into a Flavor. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// // Delete deletes the specified flavor ID. -// func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { -// _, r.Err = client.Delete(deleteURL(client, id), nil) -// return -// } - -// // ListAccesses retrieves the tenants which have access to a flavor. -// func ListAccesses(client *eclcloud.ServiceClient, id string) pagination.Pager { -// url := accessURL(client, id) - -// return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { -// return AccessPage{pagination.SinglePageBase(r)} -// }) -// } - -// // AddAccessOptsBuilder allows extensions to add additional parameters to the -// // AddAccess requests. -// type AddAccessOptsBuilder interface { -// ToFlavorAddAccessMap() (map[string]interface{}, error) -// } - -// // AddAccessOpts represents options for adding access to a flavor. -// type AddAccessOpts struct { -// // Tenant is the project/tenant ID to grant access. -// Tenant string `json:"tenant"` -// } - -// // ToFlavorAddAccessMap constructs a request body from AddAccessOpts. -// func (opts AddAccessOpts) ToFlavorAddAccessMap() (map[string]interface{}, error) { -// return eclcloud.BuildRequestBody(opts, "addTenantAccess") -// } - -// // AddAccess grants a tenant/project access to a flavor. -// func AddAccess(client *eclcloud.ServiceClient, id string, opts AddAccessOptsBuilder) (r AddAccessResult) { -// b, err := opts.ToFlavorAddAccessMap() -// if err != nil { -// r.Err = err -// return -// } -// _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ -// OkCodes: []int{200}, -// }) -// return -// } - -// // RemoveAccessOptsBuilder allows extensions to add additional parameters to the -// // RemoveAccess requests. -// type RemoveAccessOptsBuilder interface { -// ToFlavorRemoveAccessMap() (map[string]interface{}, error) -// } - -// // RemoveAccessOpts represents options for removing access to a flavor. -// type RemoveAccessOpts struct { -// // Tenant is the project/tenant ID to grant access. -// Tenant string `json:"tenant"` -// } - -// // ToFlavorRemoveAccessMap constructs a request body from RemoveAccessOpts. -// func (opts RemoveAccessOpts) ToFlavorRemoveAccessMap() (map[string]interface{}, error) { -// return eclcloud.BuildRequestBody(opts, "removeTenantAccess") -// } - -// // RemoveAccess removes/revokes a tenant/project access to a flavor. -// func RemoveAccess(client *eclcloud.ServiceClient, id string, opts RemoveAccessOptsBuilder) (r RemoveAccessResult) { -// b, err := opts.ToFlavorRemoveAccessMap() -// if err != nil { -// r.Err = err -// return -// } -// _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ -// OkCodes: []int{200}, -// }) -// return -// } - -// // ExtraSpecs requests all the extra-specs for the given flavor ID. -// func ListExtraSpecs(client *eclcloud.ServiceClient, flavorID string) (r ListExtraSpecsResult) { -// _, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil) -// return -// } - -// func GetExtraSpec(client *eclcloud.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) { -// _, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil) -// return -// } - -// // CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the -// // CreateExtraSpecs requests. -// type CreateExtraSpecsOptsBuilder interface { -// ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) -// } - -// // ExtraSpecsOpts is a map that contains key-value pairs. -// type ExtraSpecsOpts map[string]string - -// // ToFlavorExtraSpecsCreateMap assembles a body for a Create request based on -// // the contents of ExtraSpecsOpts. -// func (opts ExtraSpecsOpts) ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) { -// return map[string]interface{}{"extra_specs": opts}, nil -// } - -// // CreateExtraSpecs will create or update the extra-specs key-value pairs for -// // the specified Flavor. -// func CreateExtraSpecs(client *eclcloud.ServiceClient, flavorID string, opts CreateExtraSpecsOptsBuilder) (r CreateExtraSpecsResult) { -// b, err := opts.ToFlavorExtraSpecsCreateMap() -// if err != nil { -// r.Err = err -// return -// } -// _, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &eclcloud.RequestOpts{ -// OkCodes: []int{200}, -// }) -// return -// } - -// // UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to -// // the Update request. -// type UpdateExtraSpecOptsBuilder interface { -// ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) -// } - -// ToFlavorExtraSpecUpdateMap assembles a body for an Update request based on -// the contents of a ExtraSpecOpts. -// func (opts ExtraSpecsOpts) ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) { -// if len(opts) != 1 { -// err := eclcloud.ErrInvalidInput{} -// err.Argument = "flavors.ExtraSpecOpts" -// err.Info = "Must have 1 and only one key-value pair" -// return nil, "", err -// } - -// var key string -// for k := range opts { -// key = k -// } - -// return opts, key, nil -// } - -// // UpdateExtraSpec will updates the value of the specified flavor's extra spec -// // for the key in opts. -// func UpdateExtraSpec(client *eclcloud.ServiceClient, flavorID string, opts UpdateExtraSpecOptsBuilder) (r UpdateExtraSpecResult) { -// b, key, err := opts.ToFlavorExtraSpecUpdateMap() -// if err != nil { -// r.Err = err -// return -// } -// _, r.Err = client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &eclcloud.RequestOpts{ -// OkCodes: []int{200}, -// }) -// return -// } - -// DeleteExtraSpec will delete the key-value pair with the given key for the given -// flavor ID. -// func DeleteExtraSpec(client *eclcloud.ServiceClient, flavorID, key string) (r DeleteExtraSpecResult) { -// _, r.Err = client.Delete(extraSpecDeleteURL(client, flavorID, key), &eclcloud.RequestOpts{ -// OkCodes: []int{200}, -// }) -// return -// } - -// IDFromName is a convienience function that returns a flavor's ID given its -// name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - allPages, err := ListDetail(client, nil).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractFlavors(allPages) - if err != nil { - return "", err - } - - for _, f := range all { - if f.Name == name { - count++ - id = f.ID - } - } - - switch count { - case 0: - err := &eclcloud.ErrResourceNotFound{} - err.ResourceType = "flavor" - err.Name = name - return "", err - case 1: - return id, nil - default: - err := &eclcloud.ErrMultipleResourcesFound{} - err.ResourceType = "flavor" - err.Name = name - err.Count = count - return "", err - } -} diff --git a/v3/ecl/compute/v2/flavors/results.go b/v3/ecl/compute/v2/flavors/results.go deleted file mode 100644 index 9bb77b0..0000000 --- a/v3/ecl/compute/v2/flavors/results.go +++ /dev/null @@ -1,252 +0,0 @@ -package flavors - -import ( - "encoding/json" - "strconv" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// // CreateResult is the response of a Get operations. Call its Extract method to -// // interpret it as a Flavor. -// type CreateResult struct { -// commonResult -// } - -// GetResult is the response of a Get operations. Call its Extract method to -// interpret it as a Flavor. -type GetResult struct { - commonResult -} - -// // DeleteResult is the result from a Delete operation. Call its ExtractErr -// // method to determine if the call succeeded or failed. -// type DeleteResult struct { -// eclcloud.ErrResult -// } - -// Extract provides access to the individual Flavor returned by the Get and -// Create functions. -func (r commonResult) Extract() (*Flavor, error) { - var s struct { - Flavor *Flavor `json:"flavor"` - } - err := r.ExtractInto(&s) - return s.Flavor, err -} - -// Flavor represent (virtual) hardware configurations for server resources -// in a region. -type Flavor struct { - // ID is the flavor's unique ID. - ID string `json:"id"` - - // Disk is the amount of root disk, measured in GB. - Disk int `json:"disk"` - - // RAM is the amount of memory, measured in MB. - RAM int `json:"ram"` - - // Name is the name of the flavor. - Name string `json:"name"` - - // RxTxFactor describes bandwidth alterations of the flavor. - RxTxFactor float64 `json:"rxtx_factor"` - - // Swap is the amount of swap space, measured in MB. - Swap int `json:"-"` - - // VCPUs indicates how many (virtual) CPUs are available for this flavor. - VCPUs int `json:"vcpus"` - - // IsPublic indicates whether the flavor is public. - IsPublic bool `json:"os-flavor-access:is_public"` - - // Ephemeral is the amount of ephemeral disk space, measured in GB. - Ephemeral int `json:"OS-FLV-EXT-DATA:ephemeral"` -} - -func (r *Flavor) UnmarshalJSON(b []byte) error { - type tmp Flavor - var s struct { - tmp - Swap interface{} `json:"swap"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - - *r = Flavor(s.tmp) - - switch t := s.Swap.(type) { - case float64: - r.Swap = int(t) - case string: - switch t { - case "": - r.Swap = 0 - default: - swap, err := strconv.ParseFloat(t, 64) - if err != nil { - return err - } - r.Swap = int(swap) - } - } - - return nil -} - -// FlavorPage contains a single page of all flavors from a ListDetails call. -type FlavorPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines if a FlavorPage contains any results. -func (page FlavorPage) IsEmpty() (bool, error) { - flavors, err := ExtractFlavors(page) - return len(flavors) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (page FlavorPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"flavors_links"` - } - err := page.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// ExtractFlavors provides access to the list of flavors in a page acquired -// from the ListDetail operation. -func ExtractFlavors(r pagination.Page) ([]Flavor, error) { - var s struct { - Flavors []Flavor `json:"flavors"` - } - err := (r.(FlavorPage)).ExtractInto(&s) - return s.Flavors, err -} - -// // AccessPage contains a single page of all FlavorAccess entries for a flavor. -// type AccessPage struct { -// pagination.SinglePageBase -// } - -// // IsEmpty indicates whether an AccessPage is empty. -// func (page AccessPage) IsEmpty() (bool, error) { -// v, err := ExtractAccesses(page) -// return len(v) == 0, err -// } - -// // ExtractAccesses interprets a page of results as a slice of FlavorAccess. -// func ExtractAccesses(r pagination.Page) ([]FlavorAccess, error) { -// var s struct { -// FlavorAccesses []FlavorAccess `json:"flavor_access"` -// } -// err := (r.(AccessPage)).ExtractInto(&s) -// return s.FlavorAccesses, err -// } - -// type accessResult struct { -// eclcloud.Result -// } - -// // AddAccessResult is the response of an AddAccess operation. Call its -// // Extract method to interpret it as a slice of FlavorAccess. -// type AddAccessResult struct { -// accessResult -// } - -// // RemoveAccessResult is the response of a RemoveAccess operation. Call its -// // Extract method to interpret it as a slice of FlavorAccess. -// type RemoveAccessResult struct { -// accessResult -// } - -// // Extract provides access to the result of an access create or delete. -// // The result will be all accesses that the flavor has. -// func (r accessResult) Extract() ([]FlavorAccess, error) { -// var s struct { -// FlavorAccesses []FlavorAccess `json:"flavor_access"` -// } -// err := r.ExtractInto(&s) -// return s.FlavorAccesses, err -// } - -// // FlavorAccess represents an ACL of tenant access to a specific Flavor. -// type FlavorAccess struct { -// // FlavorID is the unique ID of the flavor. -// FlavorID string `json:"flavor_id"` - -// // TenantID is the unique ID of the tenant. -// TenantID string `json:"tenant_id"` -// } - -// // Extract interprets any extraSpecsResult as ExtraSpecs, if possible. -// func (r extraSpecsResult) Extract() (map[string]string, error) { -// var s struct { -// ExtraSpecs map[string]string `json:"extra_specs"` -// } -// err := r.ExtractInto(&s) -// return s.ExtraSpecs, err -// } - -// // extraSpecsResult contains the result of a call for (potentially) multiple -// // key-value pairs. Call its Extract method to interpret it as a -// // map[string]interface. -// type extraSpecsResult struct { -// eclcloud.Result -// } - -// // ListExtraSpecsResult contains the result of a Get operation. Call its Extract -// // method to interpret it as a map[string]interface. -// type ListExtraSpecsResult struct { -// extraSpecsResult -// } - -// // // CreateExtraSpecResult contains the result of a Create operation. Call its -// // // Extract method to interpret it as a map[string]interface. -// // type CreateExtraSpecsResult struct { -// // extraSpecsResult -// // } - -// // extraSpecResult contains the result of a call for individual a single -// // key-value pair. -// type extraSpecResult struct { -// eclcloud.Result -// } - -// // GetExtraSpecResult contains the result of a Get operation. Call its Extract -// // method to interpret it as a map[string]interface. -// type GetExtraSpecResult struct { -// extraSpecResult -// } - -// // // UpdateExtraSpecResult contains the result of an Update operation. Call its -// // // Extract method to interpret it as a map[string]interface. -// // type UpdateExtraSpecResult struct { -// // extraSpecResult -// // } - -// // // DeleteExtraSpecResult contains the result of a Delete operation. Call its -// // // ExtractErr method to determine if the call succeeded or failed. -// // type DeleteExtraSpecResult struct { -// // eclcloud.ErrResult -// // } - -// // Extract interprets any extraSpecResult as an ExtraSpec, if possible. -// func (r extraSpecResult) Extract() (map[string]string, error) { -// var s map[string]string -// err := r.ExtractInto(&s) -// return s, err -// } diff --git a/v3/ecl/compute/v2/flavors/urls.go b/v3/ecl/compute/v2/flavors/urls.go deleted file mode 100644 index 079d7ce..0000000 --- a/v3/ecl/compute/v2/flavors/urls.go +++ /dev/null @@ -1,49 +0,0 @@ -package flavors - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("flavors", "detail") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("flavors") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id) -} - -func accessURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id, "os-flavor-access") -} - -func accessActionURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id, "action") -} - -func extraSpecsListURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id, "os-extra_specs") -} - -func extraSpecsGetURL(client *eclcloud.ServiceClient, id, key string) string { - return client.ServiceURL("flavors", id, "os-extra_specs", key) -} - -func extraSpecsCreateURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("flavors", id, "os-extra_specs") -} - -func extraSpecUpdateURL(client *eclcloud.ServiceClient, id, key string) string { - return client.ServiceURL("flavors", id, "os-extra_specs", key) -} - -func extraSpecDeleteURL(client *eclcloud.ServiceClient, id, key string) string { - return client.ServiceURL("flavors", id, "os-extra_specs", key) -} diff --git a/v3/ecl/compute/v2/images/doc.go b/v3/ecl/compute/v2/images/doc.go deleted file mode 100644 index 1ebc445..0000000 --- a/v3/ecl/compute/v2/images/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Package images provides information and interaction with the images through -the Enterprise Cloud Compute service. - -This API is deprecated and will be removed from a future version of the Nova -API service. - -An image is a collection of files used to create or rebuild a server. -Operators provide a number of pre-built OS images by default. You may also -create custom images from cloud servers you have launched. - -Example to List Images - - listOpts := images.ListOpts{ - Limit: 2, - } - - allPages, err := images.ListDetail(computeClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allImages, err := images.ExtractImages(allPages) - if err != nil { - panic(err) - } - - for _, image := range allImages { - fmt.Printf("%+v\n", image) - } -*/ -package images diff --git a/v3/ecl/compute/v2/images/requests.go b/v3/ecl/compute/v2/images/requests.go deleted file mode 100644 index 2e4f446..0000000 --- a/v3/ecl/compute/v2/images/requests.go +++ /dev/null @@ -1,109 +0,0 @@ -package images - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// ListDetail request. -type ListOptsBuilder interface { - ToImageListQuery() (string, error) -} - -// ListOpts contain options filtering Images returned from a call to ListDetail. -type ListOpts struct { - // ChangesSince filters Images based on the last changed status (in date-time - // format). - ChangesSince string `q:"changes-since"` - - // Limit limits the number of Images to return. - Limit int `q:"limit"` - - // Mark is an Image UUID at which to set a marker. - Marker string `q:"marker"` - - // Name is the name of the Image. - Name string `q:"name"` - - // Server is the name of the Server (in URL format). - Server string `q:"server"` - - // Status is the current status of the Image. - Status string `q:"status"` - - // Type is the type of image (e.g. BASE, SERVER, ALL). - Type string `q:"type"` -} - -// ToImageListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToImageListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// ListDetail enumerates the available images. -func ListDetail(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listDetailURL(client) - if opts != nil { - query, err := opts.ToImageListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ImagePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get returns data about a specific image by its ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// Delete deletes the specified image ID. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// IDFromName is a convienience function that returns an image's ID given its -// name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - allPages, err := ListDetail(client, nil).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractImages(allPages) - if err != nil { - return "", err - } - - for _, f := range all { - if f.Name == name { - count++ - id = f.ID - } - } - - switch count { - case 0: - err := &eclcloud.ErrResourceNotFound{} - err.ResourceType = "image" - err.Name = name - return "", err - case 1: - return id, nil - default: - err := &eclcloud.ErrMultipleResourcesFound{} - err.ResourceType = "image" - err.Name = name - err.Count = count - return "", err - } -} diff --git a/v3/ecl/compute/v2/images/results.go b/v3/ecl/compute/v2/images/results.go deleted file mode 100644 index 346225f..0000000 --- a/v3/ecl/compute/v2/images/results.go +++ /dev/null @@ -1,95 +0,0 @@ -package images - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// GetResult is the response from a Get operation. Call its Extract method to -// interpret it as an Image. -type GetResult struct { - eclcloud.Result -} - -// DeleteResult is the result from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// Extract interprets a GetResult as an Image. -func (r GetResult) Extract() (*Image, error) { - var s struct { - Image *Image `json:"image"` - } - err := r.ExtractInto(&s) - return s.Image, err -} - -// Image represents an Image returned by the Compute API. -type Image struct { - // ID is the unique ID of an image. - ID string - - // Created is the date when the image was created. - Created string - - // MinDisk is the minimum amount of disk a flavor must have to be able - // to create a server based on the image, measured in GB. - MinDisk int - - // MinRAM is the minimum amount of RAM a flavor must have to be able - // to create a server based on the image, measured in MB. - MinRAM int - - // Name provides a human-readable moniker for the OS image. - Name string - - // The Progress and Status fields indicate image-creation status. - Progress int - - // Status is the current status of the image. - Status string - - // Update is the date when the image was updated. - Updated string - - // Metadata provides free-form key/value pairs that further describe the - // image. - Metadata map[string]interface{} -} - -// ImagePage contains a single page of all Images returne from a ListDetail -// operation. Use ExtractImages to convert it into a slice of usable structs. -type ImagePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if an ImagePage contains no Image results. -func (page ImagePage) IsEmpty() (bool, error) { - images, err := ExtractImages(page) - return len(images) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (page ImagePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"images_links"` - } - err := page.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// ExtractImages converts a page of List results into a slice of usable Image -// structs. -func ExtractImages(r pagination.Page) ([]Image, error) { - var s struct { - Images []Image `json:"images"` - } - err := (r.(ImagePage)).ExtractInto(&s) - return s.Images, err -} diff --git a/v3/ecl/compute/v2/images/urls.go b/v3/ecl/compute/v2/images/urls.go deleted file mode 100644 index 876ded5..0000000 --- a/v3/ecl/compute/v2/images/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package images - -import "github.com/nttcom/eclcloud/v3" - -func listDetailURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("images", "detail") -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("images", id) -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("images", id) -} diff --git a/v3/ecl/compute/v2/servers/doc.go b/v3/ecl/compute/v2/servers/doc.go deleted file mode 100644 index c68acb6..0000000 --- a/v3/ecl/compute/v2/servers/doc.go +++ /dev/null @@ -1,168 +0,0 @@ -/* -Package servers provides information and interaction with the server API -resource in the Enterprise Cloud Compute service. - -A server is a virtual machine instance in the compute system. In order for -one to be provisioned, a valid flavor and image are required. - -Example to List Servers - - listOpts := servers.ListOpts{ - AllTenants: true, - } - - allPages, err := servers.List(computeClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allServers, err := servers.ExtractServers(allPages) - if err != nil { - panic(err) - } - - for _, server := range allServers { - fmt.Printf("%+v\n", server) - } - -Example to Get a Server - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - server, err := servers.Get(client, serverID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", server) - -Example to Create a Server - - createOpts := servers.CreateOpts{ - Name: "server_name", - ImageRef: "image-uuid", - FlavorRef: "flavor-uuid", - } - - result := servers.Create(computeClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Update a Server - - name := "update_name" - updateOpts := servers.UpdateOpts{Name: &name} - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.Update(client, serverID, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a Server - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.Delete(computeClient, serverID) - if result.Err != nil { - panic(err) - } - -Example to Show Metadata a server - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - metadata, err := servers.Metadata(client, serverID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", metadata) - -Example to Show details for a Metadata item by key for a Server - - key := "key" - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - metadatum, err := servers.Metadatum(client, serverID, key).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", metadatum) - -Example to Create Metadata a Server - - createMetadatumOpts := servers.MetadatumOpts{"key": "value"} - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.CreateMetadatum(client, serverID, createMetadatumOpts) - if err != nil { - panic(result.Err) - } - -Example to Update Metadata a Server - - updateMetadataOpts := servers.MetadataOpts{"key": "update"} - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.UpdateMetadata(client, serverID, updateMetadataOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete Metadata a Server - - key := "key" - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.DeleteMetadatum(client, serverID, key) - if result.Err != nil { - panic(result.Err) - } - -Example to Reset Metadata a Server - - resetMetadataOpts := servers.MetadataOpts{"key2": "val2"} - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.ResetMetadata(client, serverID, resetMetadataOpts) - if result.Err != nil { - panic(nil) - } - -Example to Resize a Server - - resizeOpts := servers.ResizeOpts{ - FlavorRef: "flavor-uuid", - } - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.Resize(computeClient, serverID, resizeOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Snapshot a Server - - snapshotOpts := servers.CreateImageOpts{ - Name: "snapshot_name", - } - - serverID := "d9072956-1560-487c-97f2-18bdf65ec749" - - result := servers.CreateImage(computeClient, serverID, snapshotOpts) - if result.Err != nil { - panic(result.Err) - } - -*/ -package servers diff --git a/v3/ecl/compute/v2/servers/errors.go b/v3/ecl/compute/v2/servers/errors.go deleted file mode 100644 index b513aeb..0000000 --- a/v3/ecl/compute/v2/servers/errors.go +++ /dev/null @@ -1,71 +0,0 @@ -package servers - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -// ErrNeitherImageIDNorImageNameProvided is the error when neither the image -// ID nor the image name is provided for a server operation -type ErrNeitherImageIDNorImageNameProvided struct{ eclcloud.ErrMissingInput } - -func (e ErrNeitherImageIDNorImageNameProvided) Error() string { - return "One and only one of the image ID and the image name must be provided." -} - -// ErrNeitherFlavorIDNorFlavorNameProvided is the error when neither the flavor -// ID nor the flavor name is provided for a server operation -type ErrNeitherFlavorIDNorFlavorNameProvided struct{ eclcloud.ErrMissingInput } - -func (e ErrNeitherFlavorIDNorFlavorNameProvided) Error() string { - return "One and only one of the flavor ID and the flavor name must be provided." -} - -type ErrNoClientProvidedForIDByName struct{ eclcloud.ErrMissingInput } - -func (e ErrNoClientProvidedForIDByName) Error() string { - return "A service client must be provided to find a resource ID by name." -} - -// ErrInvalidHowParameterProvided is the error when an unknown value is given -// for the `how` argument -type ErrInvalidHowParameterProvided struct{ eclcloud.ErrInvalidInput } - -// ErrNoAdminPassProvided is the error when an administrative password isn't -// provided for a server operation -type ErrNoAdminPassProvided struct{ eclcloud.ErrMissingInput } - -// ErrNoImageIDProvided is the error when an image ID isn't provided for a server -// operation -type ErrNoImageIDProvided struct{ eclcloud.ErrMissingInput } - -// ErrNoIDProvided is the error when a server ID isn't provided for a server -// operation -type ErrNoIDProvided struct{ eclcloud.ErrMissingInput } - -// ErrServer is a generic error type for servers HTTP operations. -type ErrServer struct { - eclcloud.ErrUnexpectedResponseCode - ID string -} - -func (se ErrServer) Error() string { - return fmt.Sprintf("Error while executing HTTP request for server [%s]", se.ID) -} - -// Error404 overrides the generic 404 error message. -func (se ErrServer) Error404(e eclcloud.ErrUnexpectedResponseCode) error { - se.ErrUnexpectedResponseCode = e - return &ErrServerNotFound{se} -} - -// ErrServerNotFound is the error when a 404 is received during server HTTP -// operations. -type ErrServerNotFound struct { - ErrServer -} - -func (e ErrServerNotFound) Error() string { - return fmt.Sprintf("I couldn't find server [%s]", e.ID) -} diff --git a/v3/ecl/compute/v2/servers/requests.go b/v3/ecl/compute/v2/servers/requests.go deleted file mode 100644 index dee6836..0000000 --- a/v3/ecl/compute/v2/servers/requests.go +++ /dev/null @@ -1,573 +0,0 @@ -package servers - -import ( - "encoding/base64" - // "encoding/json" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/flavors" - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/images" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToServerListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // ChangesSince is a time/date stamp for when the server last changed status. - ChangesSince string `q:"changes-since"` - - // Image is the name of the image in URL format. - Image string `q:"image"` - - // Flavor is the name of the flavor in URL format. - Flavor string `q:"flavor"` - - // Name of the server as a string; can be queried with regular expressions. - // Realize that ?name=bob returns both bob and bobb. If you need to match bob - // only, you can use a regular expression matching the syntax of the - // underlying database server implemented for Compute. - Name string `q:"name"` - - // Status is the value of the status of the server so that you can filter on - // "ACTIVE" for example. - Status string `q:"status"` - - // Host is the name of the host as a string. - Host string `q:"host"` - - // Marker is a UUID of the server at which you want to set a marker. - Marker string `q:"marker"` - - // Limit is an integer value for the limit of values to return. - Limit int `q:"limit"` - - // AllTenants is a bool to show all tenants. - AllTenants bool `q:"all_tenants"` - - // TenantID lists servers for a particular tenant. - // Setting "AllTenants = true" is required. - TenantID string `q:"tenant_id"` -} - -// ToServerListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToServerListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List makes a request against the API to list servers accessible to you. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listDetailURL(client) - if opts != nil { - query, err := opts.ToServerListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToServerCreateMap() (map[string]interface{}, error) -} - -// Network is used within CreateOpts to control a new server's network -// attachments. -type Network struct { - // UUID of a network to attach to the newly provisioned server. - // Required unless Port is provided. - UUID string - - // Port of a neutron network to attach to the newly provisioned server. - // Required unless UUID is provided. - Port string - - // FixedIP specifies a fixed IPv4 address to be used on this network. - FixedIP string -} - -// Personality is an array of files that are injected into the server at launch. -// type Personality []*File - -// File is used within CreateOpts and RebuildOpts to inject a file into the -// server at launch. -// File implements the json.Marshaler interface, so when a Create or Rebuild -// operation is requested, json.Marshal will call File's MarshalJSON method. -// type File struct { -// // Path of the file. -// Path string - -// // Contents of the file. Maximum content size is 255 bytes. -// Contents []byte -// } - -// MarshalJSON marshals the escaped file, base64 encoding the contents. -// func (f *File) MarshalJSON() ([]byte, error) { -// file := struct { -// Path string `json:"path"` -// Contents string `json:"contents"` -// }{ -// Path: f.Path, -// Contents: base64.StdEncoding.EncodeToString(f.Contents), -// } -// return json.Marshal(file) -// } - -// CreateOpts specifies server creation parameters. -type CreateOpts struct { - // Name is the name to assign to the newly launched server. - Name string `json:"name" required:"true"` - - // ImageRef [optional; required if ImageName is not provided] is the ID or - // full URL to the image that contains the server's OS and initial state. - // Also optional if using the boot-from-volume extension. - ImageRef string `json:"imageRef"` - - // ImageName [optional; required if ImageRef is not provided] is the name of - // the image that contains the server's OS and initial state. - // Also optional if using the boot-from-volume extension. - ImageName string `json:"-"` - - // FlavorRef [optional; required if FlavorName is not provided] is the ID or - // full URL to the flavor that describes the server's specs. - FlavorRef string `json:"flavorRef"` - - // FlavorName [optional; required if FlavorRef is not provided] is the name of - // the flavor that describes the server's specs. - FlavorName string `json:"-"` - - // SecurityGroups lists the names of the security groups to which this server - // should belong. - // SecurityGroups []string `json:"-"` - - // UserData contains configuration information or scripts to use upon launch. - // Create will base64-encode it for you, if it isn't already. - UserData []byte `json:"-"` - - // AvailabilityZone in which to launch the server. - AvailabilityZone string `json:"availability_zone,omitempty"` - - // Networks dictates how this server will be attached to available networks. - // By default, the server will be attached to all isolated networks for the - // tenant. - Networks []Network `json:"-"` - - // Metadata contains key-value pairs (up to 255 bytes each) to attach to the - // server. - Metadata map[string]string `json:"metadata,omitempty"` - - // Personality includes files to inject into the server at launch. - // Create will base64-encode file contents for you. - // Personality Personality `json:"personality,omitempty"` - - // ConfigDrive enables metadata injection through a configuration drive. - ConfigDrive *bool `json:"config_drive,omitempty"` - - // AdminPass sets the root user password. If not set, a randomly-generated - // password will be created and returned in the response. - // AdminPass string `json:"adminPass,omitempty"` - - // AccessIPv4 specifies an IPv4 address for the instance. - AccessIPv4 string `json:"accessIPv4,omitempty"` - - // AccessIPv6 pecifies an IPv6 address for the instance. - // AccessIPv6 string `json:"accessIPv6,omitempty"` - - // ServiceClient will allow calls to be made to retrieve an image or - // flavor ID by name. - ServiceClient *eclcloud.ServiceClient `json:"-"` -} - -// ToServerCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { - sc := opts.ServiceClient - opts.ServiceClient = nil - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - if opts.UserData != nil { - var userData string - if _, err := base64.StdEncoding.DecodeString(string(opts.UserData)); err != nil { - userData = base64.StdEncoding.EncodeToString(opts.UserData) - } else { - userData = string(opts.UserData) - } - b["user_data"] = &userData - } - - // if len(opts.SecurityGroups) > 0 { - // securityGroups := make([]map[string]interface{}, len(opts.SecurityGroups)) - // for i, groupName := range opts.SecurityGroups { - // securityGroups[i] = map[string]interface{}{"name": groupName} - // } - // b["security_groups"] = securityGroups - // } - - if len(opts.Networks) > 0 { - networks := make([]map[string]interface{}, len(opts.Networks)) - for i, net := range opts.Networks { - networks[i] = make(map[string]interface{}) - if net.UUID != "" { - networks[i]["uuid"] = net.UUID - } - if net.Port != "" { - networks[i]["port"] = net.Port - } - if net.FixedIP != "" { - networks[i]["fixed_ip"] = net.FixedIP - } - } - b["networks"] = networks - } - - // If ImageRef isn't provided, check if ImageName was provided to ascertain - // the image ID. - if opts.ImageRef == "" { - if opts.ImageName != "" { - if sc == nil { - err := ErrNoClientProvidedForIDByName{} - err.Argument = "ServiceClient" - return nil, err - } - imageID, err := images.IDFromName(sc, opts.ImageName) - if err != nil { - return nil, err - } - b["imageRef"] = imageID - } - } - - // If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID. - if opts.FlavorRef == "" { - if opts.FlavorName == "" { - err := ErrNeitherFlavorIDNorFlavorNameProvided{} - err.Argument = "FlavorRef/FlavorName" - return nil, err - } - if sc == nil { - err := ErrNoClientProvidedForIDByName{} - err.Argument = "ServiceClient" - return nil, err - } - flavorID, err := flavors.IDFromName(sc, opts.FlavorName) - if err != nil { - return nil, err - } - b["flavorRef"] = flavorID - } - - return map[string]interface{}{"server": b}, nil -} - -// Create requests a server to be provisioned to the user in the current tenant. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - reqBody, err := opts.ToServerCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(listURL(client), reqBody, &r.Body, nil) - return -} - -// Delete requests that a server previously provisioned be removed from your -// account. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// Get requests details on a single server, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 203}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the -// Update request. -type UpdateOptsBuilder interface { - ToServerUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts specifies the base attributes that may be updated on an existing -// server. -type UpdateOpts struct { - // Name changes the displayed name of the server. - // The server host name will *not* change. - // Server names are not constrained to be unique, even within the same tenant. - Name *string `json:"name,omitempty"` - - // AccessIPv4 provides a new IPv4 address for the instance. - // AccessIPv4 *string `json:"accessIPv4,omitempty"` - - // AccessIPv6 provides a new IPv6 address for the instance. - // AccessIPv6 string `json:"accessIPv6,omitempty"` -} - -// ToServerUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToServerUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "server") -} - -// Update requests that various attributes of the indicated server be changed. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToServerUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// ResizeOptsBuilder allows extensions to add additional parameters to the -// resize request. -type ResizeOptsBuilder interface { - ToServerResizeMap() (map[string]interface{}, error) -} - -// ResizeOpts represents the configuration options used to control a Resize -// operation. -type ResizeOpts struct { - // FlavorRef is the ID of the flavor you wish your server to become. - FlavorRef string `json:"flavorRef" required:"true"` -} - -// ToServerResizeMap formats a ResizeOpts as a map that can be used as a JSON -// request body for the Resize request. -func (opts ResizeOpts) ToServerResizeMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "resize") -} - -// Resize instructs the provider to change the flavor of the server. -// -// Note that this implies rebuilding it. -// -// Unfortunately, one cannot pass rebuild parameters to the resize function. -// When the resize completes, the server will be in VERIFY_RESIZE state. -// While in this state, you can explore the use of the new server's -// configuration. If you like it, call ConfirmResize() to commit the resize -// permanently. Otherwise, call RevertResize() to restore the old configuration. -func Resize(client *eclcloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ActionResult) { - b, err := opts.ToServerResizeMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(actionURL(client, id), b, nil, nil) - return -} - -// ResetMetadataOptsBuilder allows extensions to add additional parameters to -// the Reset request. -type ResetMetadataOptsBuilder interface { - ToMetadataResetMap() (map[string]interface{}, error) -} - -// MetadataOpts is a map that contains key-value pairs. -type MetadataOpts map[string]string - -// ToMetadataResetMap assembles a body for a Reset request based on the contents -// of a MetadataOpts. -func (opts MetadataOpts) ToMetadataResetMap() (map[string]interface{}, error) { - return map[string]interface{}{"metadata": opts}, nil -} - -// ToMetadataUpdateMap assembles a body for an Update request based on the -// contents of a MetadataOpts. -func (opts MetadataOpts) ToMetadataUpdateMap() (map[string]interface{}, error) { - return map[string]interface{}{"metadata": opts}, nil -} - -// ResetMetadata will create multiple new key-value pairs for the given server -// ID. -// Note: Using this operation will erase any already-existing metadata and -// create the new metadata provided. To keep any already-existing metadata, -// use the UpdateMetadatas or UpdateMetadata function. -func ResetMetadata(client *eclcloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) (r ResetMetadataResult) { - b, err := opts.ToMetadataResetMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(metadataURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Metadata requests all the metadata for the given server ID. -func Metadata(client *eclcloud.ServiceClient, id string) (r GetMetadataResult) { - _, r.Err = client.Get(metadataURL(client, id), &r.Body, nil) - return -} - -// UpdateMetadataOptsBuilder allows extensions to add additional parameters to -// the Create request. -type UpdateMetadataOptsBuilder interface { - ToMetadataUpdateMap() (map[string]interface{}, error) -} - -// UpdateMetadata updates (or creates) all the metadata specified by opts for -// the given server ID. This operation does not affect already-existing metadata -// that is not specified by opts. -func UpdateMetadata(client *eclcloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) (r UpdateMetadataResult) { - b, err := opts.ToMetadataUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(metadataURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// MetadatumOptsBuilder allows extensions to add additional parameters to the -// Create request. -type MetadatumOptsBuilder interface { - ToMetadatumCreateMap() (map[string]interface{}, string, error) -} - -// MetadatumOpts is a map of length one that contains a key-value pair. -type MetadatumOpts map[string]string - -// ToMetadatumCreateMap assembles a body for a Create request based on the -// contents of a MetadataumOpts. -func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, string, error) { - if len(opts) != 1 { - err := eclcloud.ErrInvalidInput{} - err.Argument = "servers.MetadatumOpts" - err.Info = "Must have 1 and only 1 key-value pair" - return nil, "", err - } - metadatum := map[string]interface{}{"meta": opts} - var key string - for k := range metadatum["meta"].(MetadatumOpts) { - key = k - } - return metadatum, key, nil -} - -// CreateMetadatum will create or update the key-value pair with the given key -// for the given server ID. -func CreateMetadatum(client *eclcloud.ServiceClient, id string, opts MetadatumOptsBuilder) (r CreateMetadatumResult) { - b, key, err := opts.ToMetadatumCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(metadatumURL(client, id, key), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Metadatum requests the key-value pair with the given key for the given -// server ID. -func Metadatum(client *eclcloud.ServiceClient, id, key string) (r GetMetadatumResult) { - _, r.Err = client.Get(metadatumURL(client, id, key), &r.Body, nil) - return -} - -// DeleteMetadatum will delete the key-value pair with the given key for the -// given server ID. -func DeleteMetadatum(client *eclcloud.ServiceClient, id, key string) (r DeleteMetadatumResult) { - _, r.Err = client.Delete(metadatumURL(client, id, key), nil) - return -} - -// CreateImageOptsBuilder allows extensions to add additional parameters to the -// CreateImage request. -type CreateImageOptsBuilder interface { - ToServerCreateImageMap() (map[string]interface{}, error) -} - -// CreateImageOpts provides options to pass to the CreateImage request. -type CreateImageOpts struct { - // Name of the image/snapshot. - Name string `json:"name" required:"true"` - - // Metadata contains key-value pairs (up to 255 bytes each) to attach to - // the created image. - Metadata map[string]string `json:"metadata,omitempty"` -} - -// ToServerCreateImageMap formats a CreateImageOpts structure into a request -// body. -func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "createImage") -} - -// CreateImage makes a request against the nova API to schedule an image to be -// created of the server -func CreateImage(client *eclcloud.ServiceClient, id string, opts CreateImageOptsBuilder) (r CreateImageResult) { - b, err := opts.ToServerCreateImageMap() - if err != nil { - r.Err = err - return - } - resp, err := client.Post(actionURL(client, id), b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - r.Err = err - r.Header = resp.Header - return -} - -// IDFromName is a convienience function that returns a server's ID given its -// name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - allPages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractServers(allPages) - if err != nil { - return "", err - } - - for _, f := range all { - if f.Name == name { - count++ - id = f.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "server"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "server"} - } -} diff --git a/v3/ecl/compute/v2/servers/results.go b/v3/ecl/compute/v2/servers/results.go deleted file mode 100644 index 087f197..0000000 --- a/v3/ecl/compute/v2/servers/results.go +++ /dev/null @@ -1,295 +0,0 @@ -package servers - -import ( - "encoding/json" - "fmt" - "net/url" - "path" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type serverResult struct { - eclcloud.Result -} - -// Extract interprets any serverResult as a Server, if possible. -func (r serverResult) Extract() (*Server, error) { - var s Server - err := r.ExtractInto(&s) - return &s, err -} - -func (r serverResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "server") -} - -func ExtractServersInto(r pagination.Page, v interface{}) error { - return r.(ServerPage).Result.ExtractIntoSlicePtr(v, "servers") -} - -// CreateResult is the response from a Create operation. Call its Extract -// method to interpret it as a Server. -type CreateResult struct { - serverResult -} - -// GetResult is the response from a Get operation. Call its Extract -// method to interpret it as a Server. -type GetResult struct { - serverResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as a Server. -type UpdateResult struct { - serverResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// ActionResult represents the result of server action operations, like reboot. -// Call its ExtractErr method to determine if the action succeeded or failed. -type ActionResult struct { - eclcloud.ErrResult -} - -// CreateImageResult is the response from a CreateImage operation. Call its -// ExtractImageID method to retrieve the ID of the newly created image. -type CreateImageResult struct { - eclcloud.Result -} - -// ExtractImageID gets the ID of the newly created server image from the header. -func (r CreateImageResult) ExtractImageID() (string, error) { - if r.Err != nil { - return "", r.Err - } - // Get the image id from the header - u, err := url.ParseRequestURI(r.Header.Get("Location")) - if err != nil { - return "", err - } - imageID := path.Base(u.Path) - if imageID == "." || imageID == "/" { - return "", fmt.Errorf("failed to parse the ID of newly created image: %s", u) - } - return imageID, nil -} - -// Server represents a server/instance in the Enterprise Cloud. -type Server struct { - // ID uniquely identifies this server amongst all other servers, - // including those not accessible to the current tenant. - ID string `json:"id"` - - // TenantID identifies the tenant owning this server resource. - TenantID string `json:"tenant_id"` - - // UserID uniquely identifies the user account owning the tenant. - UserID string `json:"user_id"` - - // Name contains the human-readable name for the server. - Name string `json:"name"` - - // Updated and Created contain ISO-8601 timestamps of when the state of the - // server last changed, and when it was created. - Updated time.Time `json:"updated"` - Created time.Time `json:"created"` - - // HostID is the host where the server is located in the cloud. - HostID string `json:"hostid"` - - // Status contains the current operational status of the server, - // such as IN_PROGRESS or ACTIVE. - Status string `json:"status"` - - // Progress ranges from 0..100. - // A request made against the server completes only once Progress reaches 100. - Progress int `json:"progress"` - - // AccessIPv4 and AccessIPv6 contain the IP addresses of the server, - // suitable for remote access for administration. - AccessIPv4 string `json:"accessIPv4"` - // AccessIPv6 string `json:"accessIPv6"` - - // Image refers to a JSON object, which itself indicates the OS image used to - // deploy the server. - Image map[string]interface{} `json:"-"` - - // Flavor refers to a JSON object, which itself indicates the hardware - // configuration of the deployed server. - Flavor map[string]interface{} `json:"flavor"` - - // Addresses includes a list of all IP addresses assigned to the server, - // keyed by pool. - Addresses map[string]interface{} `json:"addresses"` - - // Metadata includes a list of all user-specified key-value pairs attached - // to the server. - Metadata map[string]string `json:"metadata"` - - // Links includes HTTP references to the itself, useful for passing along to - // other APIs that might want a server reference. - Links []interface{} `json:"links"` - - // KeyName indicates which public key was injected into the server on launch. - KeyName string `json:"key_name"` - - // AdminPass will generally be empty (""). However, it will contain the - // administrative password chosen when provisioning a new server without a - // set AdminPass setting in the first place. - // Note that this is the ONLY time this field will be valid. - AdminPass string `json:"adminPass"` - - // SecurityGroups includes the security groups that this instance has applied - // to it. - SecurityGroups []map[string]interface{} `json:"security_groups"` - - // Fault contains failure information about a server. - Fault Fault `json:"fault"` - - // ConfigDrive is the name of the server's config drive. - ConfigDrive string `json:"config_drive"` -} - -type Fault struct { - Code int `json:"code"` - Created time.Time `json:"created"` - Details string `json:"details"` - Message string `json:"message"` -} - -func (r *Server) UnmarshalJSON(b []byte) error { - type tmp Server - var s struct { - tmp - Image interface{} `json:"image"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - - *r = Server(s.tmp) - - switch t := s.Image.(type) { - case map[string]interface{}: - r.Image = t - case string: - switch t { - case "": - r.Image = nil - } - } - - return err -} - -// ServerPage abstracts the raw results of making a List() request against -// the API. As Enterprise Cloud extensions may freely alter the response bodies of -// structures returned to the client, you may only safely access the data -// provided through the ExtractServers call. -type ServerPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a page contains no Server results. -func (r ServerPage) IsEmpty() (bool, error) { - s, err := ExtractServers(r) - return len(s) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (r ServerPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"servers_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// ExtractServers interprets the results of a single page from a List() call, -// producing a slice of Server entities. -func ExtractServers(r pagination.Page) ([]Server, error) { - var s []Server - err := ExtractServersInto(r, &s) - return s, err -} - -// MetadataResult contains the result of a call for (potentially) multiple -// key-value pairs. Call its Extract method to interpret it as a -// map[string]interface. -type MetadataResult struct { - eclcloud.Result -} - -// GetMetadataResult contains the result of a Get operation. Call its Extract -// method to interpret it as a map[string]interface. -type GetMetadataResult struct { - MetadataResult -} - -// ResetMetadataResult contains the result of a Reset operation. Call its -// Extract method to interpret it as a map[string]interface. -type ResetMetadataResult struct { - MetadataResult -} - -// UpdateMetadataResult contains the result of an Update operation. Call its -// Extract method to interpret it as a map[string]interface. -type UpdateMetadataResult struct { - MetadataResult -} - -// MetadatumResult contains the result of a call for individual a single -// key-value pair. -type MetadatumResult struct { - eclcloud.Result -} - -// GetMetadatumResult contains the result of a Get operation. Call its Extract -// method to interpret it as a map[string]interface. -type GetMetadatumResult struct { - MetadatumResult -} - -// CreateMetadatumResult contains the result of a Create operation. Call its -// Extract method to interpret it as a map[string]interface. -type CreateMetadatumResult struct { - MetadatumResult -} - -// DeleteMetadatumResult contains the result of a Delete operation. Call its -// ExtractErr method to determine if the call succeeded or failed. -type DeleteMetadatumResult struct { - eclcloud.ErrResult -} - -// Extract interprets any MetadataResult as a Metadata, if possible. -func (r MetadataResult) Extract() (map[string]string, error) { - var s struct { - Metadata map[string]string `json:"metadata"` - } - err := r.ExtractInto(&s) - return s.Metadata, err -} - -// Extract interprets any MetadatumResult as a Metadatum, if possible. -func (r MetadatumResult) Extract() (map[string]string, error) { - var s struct { - Metadatum map[string]string `json:"meta"` - } - err := r.ExtractInto(&s) - return s.Metadatum, err -} diff --git a/v3/ecl/compute/v2/servers/testing/doc.go b/v3/ecl/compute/v2/servers/testing/doc.go deleted file mode 100644 index 29b7613..0000000 --- a/v3/ecl/compute/v2/servers/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Compute Server unit tests -package testing diff --git a/v3/ecl/compute/v2/servers/testing/fixtures.go b/v3/ecl/compute/v2/servers/testing/fixtures.go deleted file mode 100644 index 20b59c8..0000000 --- a/v3/ecl/compute/v2/servers/testing/fixtures.go +++ /dev/null @@ -1,836 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" - - "time" -) - -// ListResult provides a single page of Server results. -const ListResult = ` -{ - "servers": [ - { - "id": "707dbd55-b6bf-439d-804c-3002f49ac898", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/707dbd55-b6bf-439d-804c-3002f49ac898", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/707dbd55-b6bf-439d-804c-3002f49ac898", - "rel": "bookmark" - } - ], - "name": "Test Server2" - }, - { - "id": "8e69a092-53f9-4225-bae6-57cfbb5d6857", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "bookmark" - } - ], - "name": "Test Server1" - } - ] -} -` - -// ListDetailsResult provides a single page of Server results in details. -const ListDetailsResult = ` -{ - "servers": [ - { - "status": "ACTIVE", - "updated": "2020-05-18T01:51:41Z", - "hostId": "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - "addresses": { - "IF-4831": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:f3:ed:05", - "version": 4, - "addr": "192.168.1.103", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/707dbd55-b6bf-439d-804c-3002f49ac898", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/707dbd55-b6bf-439d-804c-3002f49ac898", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-SRV-USG:launched_at": "2020-05-11T06:25:56.000000", - "flavor": { - "id": "1CPU-4GB", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark" - } - ] - }, - "id": "707dbd55-b6bf-439d-804c-3002f49ac898", - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "zone1_groupa", - "user_id": "5e86848fbc63403daaeffc1b76b3a784", - "name": "Test Server2", - "created": "2020-05-11T06:25:53Z", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "True", - "metadata": { - "vmha": "false", - "HA_Enabled": "false" - } - }, - { - "status": "ACTIVE", - "updated": "2020-05-18T01:51:41Z", - "hostId": "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - "addresses": { - "IF-4831": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:49:78:28", - "version": 4, - "addr": "192.168.1.101", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-SRV-USG:launched_at": "2020-05-11T03:36:27.000000", - "flavor": { - "id": "1CPU-4GB", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark" - } - ] - }, - "id": "8e69a092-53f9-4225-bae6-57cfbb5d6857", - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "zone1_groupa", - "user_id": "5e86848fbc63403daaeffc1b76b3a784", - "name": "Test Server1", - "created": "2020-05-11T06:25:53Z", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "", - "metadata": { - "vmha": "false", - "HA_Enabled": "false" - } - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "server": { - "status": "ACTIVE", - "updated": "2020-05-18T01:51:41Z", - "hostId": "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - "addresses": { - "IF-4831": [ - { - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:49:78:28", - "version": 4, - "addr": "192.168.1.101", - "OS-EXT-IPS:type": "fixed" - } - ] - }, - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "bookmark" - } - ], - "key_name": null, - "image": { - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark" - } - ] - }, - "OS-EXT-STS:task_state": null, - "OS-EXT-STS:vm_state": "active", - "OS-SRV-USG:launched_at": "2020-05-11T03:36:27.000000", - "flavor": { - "id": "1CPU-4GB", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark" - } - ] - }, - "id": "8e69a092-53f9-4225-bae6-57cfbb5d6857", - "OS-SRV-USG:terminated_at": null, - "OS-EXT-AZ:availability_zone": "zone1_groupa", - "user_id": "5e86848fbc63403daaeffc1b76b3a784", - "name": "Test Server1", - "created": "2020-05-11T06:25:53Z", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "OS-DCF:diskConfig": "MANUAL", - "os-extended-volumes:volumes_attached": [], - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "OS-EXT-STS:power_state": 1, - "config_drive": "", - "metadata": { - "vmha": "false", - "HA_Enabled": "false" - } - } -} -` - -// CreateRequest provides the input to a Create request. -const CreateRequest = ` -{ - "server": { - "flavorRef": "1CPU-4GB", - "imageRef": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "name": "Test Server1", - "availability_zone": "zone1-groupa", - "config_drive": true, - "user_data": "dXNlcl9kYXRh", - "metadata": { - "foo": "bar" - }, - "networks": [ - { - "uuid": "4d98b876-b5d1-4861-8650-b5a53024486a" - } - ] - } -} -` - -const CreateResponse = ` -{ - "server": { - "security_groups": [ - { - "name": "default" - } - ], - "OS-DCF:diskConfig": "MANUAL", - "id": "8e69a092-53f9-4225-bae6-57cfbb5d6857", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "bookmark" - } - ], - "adminPass": "aabbccddeeff" - } -} -` - -const UpdateRequest = ` -{ - "server": { - "name": "Update Name" - } -} -` - -const UpdateResponse = ` -{ - "server": { - "status": "ACTIVE", - "updated": "2020-05-18T01:51:41Z", - "hostId": "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - "addresses": { - "IF-4831": [ - { - "version": 4, - "addr": "192.168.1.101" - } - ] - }, - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self" - }, - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "bookmark" - } - ], - "image": { - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark" - } - ] - }, - "flavor": { - "id": "1CPU-4GB", - "links": [ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark" - } - ] - }, - "id": "8e69a092-53f9-4225-bae6-57cfbb5d6857", - "user_id": "5e86848fbc63403daaeffc1b76b3a784", - "name": "Update Name", - "created": "2020-05-11T06:25:53Z", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "OS-DCF:diskConfig": "MANUAL", - "accessIPv4": "", - "accessIPv6": "", - "progress": 0, - "metadata": { - "vmha": "false", - "HA_Enabled": "false" - } - } -} -` - -var MetadataResult = ` -{ - "metadata": { - "vmha": "false", - "HA_Enabled": "false" - } -} -` - -var MetadatumResult = ` -{ - "meta": { - "vmha": "false" - } -} -` - -var CreateMetadatumRequest = ` -{ - "meta": { - "key1": "val1" - } -} -` - -var CreateMetadatumResponse = CreateMetadatumRequest - -var UpdateMetadataRequest = ` -{ - "metadata": { - "key1": "update_val" - } -} -` - -var UpdateMetadataResponse = UpdateMetadataRequest - -var ResetMetadataRequest = ` -{ - "metadata": { - "key1": "val1", - "key2": "val2" - } -} -` - -var ResetMetadataResponse = ResetMetadataRequest - -var ResizeRequest = ` -{ - "resize": { - "flavorRef": "2CPU-8GB" - } -} -` - -var CreateImageRequest = ` -{ - "createImage": { - "metadata": { - "key": "create_image" - }, - "name": "Test Create Image" - } -} -` - -var expectedServers = []servers.Server{expectedServer1, expectedServer2} - -var expectedCreated, _ = time.Parse(eclcloud.RFC3339Milli, "2020-05-11T06:25:53Z") -var expectedUpdated, _ = time.Parse(eclcloud.RFC3339Milli, "2020-05-18T01:51:41Z") - -var expectedServer1 = servers.Server{ - ID: "707dbd55-b6bf-439d-804c-3002f49ac898", - TenantID: "1bc271e7a8af4d988ff91612f5b122f8", - UserID: "5e86848fbc63403daaeffc1b76b3a784", - Name: "Test Server2", - Updated: expectedUpdated, - Created: expectedCreated, - HostID: "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - Status: "ACTIVE", - Progress: 0, - AccessIPv4: "", - Image: map[string]interface{}{ - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "1CPU-4GB", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "IF-4831": []interface{}{ - map[string]interface{}{ - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:f3:ed:05", - "OS-EXT-IPS:type": "fixed", - "addr": "192.168.1.103", - "version": float64(4), - }, - }, - }, - Metadata: map[string]string{ - "vmha": "false", - "HA_Enabled": "false", - }, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/707dbd55-b6bf-439d-804c-3002f49ac898", - "rel": "self", - }, - }, - AdminPass: "", - SecurityGroups: nil, - Fault: servers.Fault{}, - ConfigDrive: "True", -} - -var expectedServer2 = servers.Server{ - ID: "8e69a092-53f9-4225-bae6-57cfbb5d6857", - TenantID: "1bc271e7a8af4d988ff91612f5b122f8", - UserID: "5e86848fbc63403daaeffc1b76b3a784", - Name: "Test Server1", - Updated: expectedUpdated, - Created: expectedCreated, - HostID: "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - Status: "ACTIVE", - Progress: 0, - AccessIPv4: "", - Image: map[string]interface{}{ - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "1CPU-4GB", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "IF-4831": []interface{}{ - map[string]interface{}{ - "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:49:78:28", - "OS-EXT-IPS:type": "fixed", - "addr": "192.168.1.101", - "version": float64(4), - }, - }, - }, - Metadata: map[string]string{ - "vmha": "false", - "HA_Enabled": "false", - }, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self", - }, - }, - //KeyName: nil, - AdminPass: "", - SecurityGroups: nil, - Fault: servers.Fault{}, - ConfigDrive: "", -} - -var serverNameUpdated = servers.Server{ - ID: "8e69a092-53f9-4225-bae6-57cfbb5d6857", - TenantID: "1bc271e7a8af4d988ff91612f5b122f8", - UserID: "5e86848fbc63403daaeffc1b76b3a784", - Name: "Update Name", - Updated: expectedUpdated, - Created: expectedCreated, - HostID: "d7961f8a2cde3e49a3f5d3a0a95c6c1d9ce28a342285d4118a936247", - Status: "ACTIVE", - Progress: 0, - AccessIPv4: "", - Image: map[string]interface{}{ - "id": "c11a6d55-70e9-4d04-a086-4451f07da0d7", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/c11a6d55-70e9-4d04-a086-4451f07da0d7", - "rel": "bookmark", - }, - }, - }, - Flavor: map[string]interface{}{ - "id": "1CPU-4GB", - "links": []map[string]interface{}{ - { - "href": "https://nova-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/1CPU-4GB", - "rel": "bookmark", - }, - }, - }, - Addresses: map[string]interface{}{ - "IF-4831": []interface{}{ - map[string]interface{}{ - "addr": "192.168.1.101", - "version": float64(4), - }, - }, - }, - Metadata: map[string]string{ - "vmha": "false", - "HA_Enabled": "false", - }, - Links: []interface{}{ - map[string]interface{}{ - "href": "https://nova-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/8e69a092-53f9-4225-bae6-57cfbb5d6857", - "rel": "self", - }, - }, - AdminPass: "", - SecurityGroups: nil, - Fault: servers.Fault{}, - ConfigDrive: "", -} - -var expectMetadata = map[string]string{ - "vmha": "false", - "HA_Enabled": "false", -} - -var expectMetadatum = map[string]string{ - "vmha": "false", -} - -var expectCreateMetadatum = map[string]string{ - "key1": "val1", -} - -var ecpectUpdateMetadata = map[string]string{ - "key1": "update_val", -} - -var expectResetMetadata = map[string]string{ - "key1": "val1", - "key2": "val2", -} - -// HandleListServersSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a list of two servers. -func HandleListServersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} - -// HandleListServersDetailsSuccessfully creates an HTTP handler at `/servers/detail` on the -// test handler mux that responds with a list of two servers. -func HandleListServersDetailsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListDetailsResult) - }) -} - -// HandleGetServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a single server. -func HandleGetServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResult) - }) -} - -// HandleCreateServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server creation. -func HandleCreateServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - fmt.Fprintf(w, CreateResponse) - }) -} - -// HandleDeleteServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server deletion. -func HandleDeleteServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s", expectedServer1.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server update. -func HandleUpdateServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResponse) - }) -} - -// HandleGetMetadataSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a server metadata. -func HandleGetMetadataSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MetadataResult) - }) -} - -// HandleGetMetadatumSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a server metadatum. -func HandleGetMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata/vmha", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, MetadatumResult) - }) -} - -// HandleCreateMetadatumSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server metadata creation. -func HandleCreateMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata/key1", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateMetadatumRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CreateMetadatumResponse) - }) -} - -// HandleDeleteMetadatumSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server metadata deletion. -func HandleDeleteMetadatumSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata/vmha", expectedServer1.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateMetadataSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server metadata update. -func HandleUpdateMetadataSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestJSONRequest(t, r, UpdateMetadataRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateMetadataResponse) - }) -} - -// HandleResetMetadataSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server metadata reset. -func HandleResetMetadataSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/metadata", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, ResetMetadataRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ResetMetadataResponse) - }) -} - -// HandleResizeServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server resize action. -func HandleResizeServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/action", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, ResizeRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} - -// HandleCreateImageSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests create server image. -func HandleCreateImageSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/action", expectedServer2.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateImageRequest) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) -} diff --git a/v3/ecl/compute/v2/servers/testing/requests_test.go b/v3/ecl/compute/v2/servers/testing/requests_test.go deleted file mode 100644 index 1f471e6..0000000 --- a/v3/ecl/compute/v2/servers/testing/requests_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/compute/v2/servers" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersDetailsSuccessfully(t) - - count := 0 - err := servers.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, expectedServers, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListServersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersDetailsSuccessfully(t) - - allPages, err := servers.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := servers.ExtractServers(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectedServers, actual) -} - -func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetServerSuccessfully(t) - - actual, err := servers.Get(client.ServiceClient(), expectedServer2.ID).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectedServer2, *actual) -} - -func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateServerSuccessfully(t) - - configDrive := true - createOpts := servers.CreateOpts{ - Name: "Test Server1", - ImageRef: "c11a6d55-70e9-4d04-a086-4451f07da0d7", - FlavorRef: "1CPU-4GB", - UserData: []byte("user_data"), - AvailabilityZone: "zone1-groupa", - Networks: []servers.Network{ - { - UUID: "4d98b876-b5d1-4861-8650-b5a53024486a", - }, - }, - Metadata: map[string]string{ - "foo": "bar", - }, - ConfigDrive: &configDrive, - } - - actual, err := servers.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedServer2.ID, actual.ID) - th.AssertDeepEquals(t, expectedServer2.Links, actual.Links) - th.AssertEquals(t, "aabbccddeeff", actual.AdminPass) -} - -func TestDeleteServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteServerSuccessfully(t) - - res := servers.Delete(client.ServiceClient(), expectedServer1.ID) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateServerSuccessfully(t) - - name := "Update Name" - updateOpts := servers.UpdateOpts{Name: &name} - - actual, err := servers.Update(client.ServiceClient(), expectedServer2.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, serverNameUpdated, *actual) -} - -func TestGetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMetadataSuccessfully(t) - - actual, err := servers.Metadata(client.ServiceClient(), expectedServer2.ID).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectMetadata, actual) -} - -func TestGetMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetMetadatumSuccessfully(t) - - actual, err := servers.Metadatum(client.ServiceClient(), expectedServer2.ID, "vmha").Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectMetadatum, actual) -} - -func TestCreateMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateMetadatumSuccessfully(t) - - createOpts := servers.MetadatumOpts{"key1": "val1"} - - actual, err := servers.CreateMetadatum(client.ServiceClient(), expectedServer2.ID, createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectCreateMetadatum, actual) -} - -func TestDeleteMetadatum(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteMetadatumSuccessfully(t) - - res := servers.DeleteMetadatum(client.ServiceClient(), expectedServer1.ID, "vmha") - th.AssertNoErr(t, res.Err) -} - -func TestUpdateMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateMetadataSuccessfully(t) - - updateOpts := servers.MetadataOpts{"key1": "update_val"} - - actual, err := servers.UpdateMetadata(client.ServiceClient(), expectedServer2.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ecpectUpdateMetadata, actual) -} - -func TestResetMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleResetMetadataSuccessfully(t) - - createOpts := servers.MetadataOpts{ - "key1": "val1", - "key2": "val2", - } - - actual, err := servers.ResetMetadata(client.ServiceClient(), expectedServer2.ID, createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectResetMetadata, actual) -} - -func TestResizeServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleResizeServerSuccessfully(t) - - resizeOpts := servers.ResizeOpts{FlavorRef: "2CPU-8GB"} - - err := servers.Resize(client.ServiceClient(), expectedServer2.ID, resizeOpts).ExtractErr() - th.AssertNoErr(t, err) -} - -func TestCreateImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateImageSuccessfully(t) - - snapshotOpts := servers.CreateImageOpts{ - Name: "Test Create Image", - Metadata: map[string]string{"key": "create_image"}, - } - - result := servers.CreateImage(client.ServiceClient(), expectedServer2.ID, snapshotOpts) - th.AssertNoErr(t, result.Err) -} diff --git a/v3/ecl/compute/v2/servers/urls.go b/v3/ecl/compute/v2/servers/urls.go deleted file mode 100644 index 4650302..0000000 --- a/v3/ecl/compute/v2/servers/urls.go +++ /dev/null @@ -1,39 +0,0 @@ -package servers - -import "github.com/nttcom/eclcloud/v3" - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers") -} - -func listURL(client *eclcloud.ServiceClient) string { - return createURL(client) -} - -func listDetailURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers", "detail") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return deleteURL(client, id) -} - -func updateURL(client *eclcloud.ServiceClient, id string) string { - return deleteURL(client, id) -} - -func actionURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "action") -} - -func metadatumURL(client *eclcloud.ServiceClient, id, key string) string { - return client.ServiceURL("servers", id, "metadata", key) -} - -func metadataURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "metadata") -} diff --git a/v3/ecl/compute/v2/servers/util.go b/v3/ecl/compute/v2/servers/util.go deleted file mode 100644 index 15823b5..0000000 --- a/v3/ecl/compute/v2/servers/util.go +++ /dev/null @@ -1,21 +0,0 @@ -package servers - -import "github.com/nttcom/eclcloud/v3" - -// WaitForStatus will continually poll a server until it successfully -// transitions to a specified status. It will do this for at most the number -// of seconds specified. -func WaitForStatus(c *eclcloud.ServiceClient, id, status string, secs int) error { - return eclcloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/v3/ecl/computevolume/extensions/volumeactions/doc.go b/v3/ecl/computevolume/extensions/volumeactions/doc.go deleted file mode 100644 index 5604976..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/doc.go +++ /dev/null @@ -1,86 +0,0 @@ -/* -Package volumeactions provides information and interaction with volumes in the -Enterprise Cloud Block Storage service. A volume is a detachable block storage -device, akin to a USB hard drive. - -Example of Attaching a Volume to an Instance - - attachOpts := volumeactions.AttachOpts{ - MountPoint: "/mnt", - Mode: "rw", - InstanceUUID: server.ID, - } - - err := volumeactions.Attach(client, volume.ID, attachOpts).ExtractErr() - if err != nil { - panic(err) - } - - detachOpts := volumeactions.DetachOpts{ - AttachmentID: volume.Attachments[0].AttachmentID, - } - - err = volumeactions.Detach(client, volume.ID, detachOpts).ExtractErr() - if err != nil { - panic(err) - } - - -Example of Creating an Image from a Volume - - uploadImageOpts := volumeactions.UploadImageOpts{ - ImageName: "my_vol", - Force: true, - } - - volumeImage, err := volumeactions.UploadImage(client, volume.ID, uploadImageOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", volumeImage) - -Example of Extending a Volume's Size - - extendOpts := volumeactions.ExtendSizeOpts{ - NewSize: 100, - } - - err := volumeactions.ExtendSize(client, volume.ID, extendOpts).ExtractErr() - if err != nil { - panic(err) - } - -Example of Initializing a Volume Connection - - connectOpts := &volumeactions.InitializeConnectionOpts{ - IP: "127.0.0.1", - Host: "stack", - Initiator: "iqn.1994-05.com.redhat:17cf566367d2", - Multipath: eclcloud.Disabled, - Platform: "x86_64", - OSType: "linux2", - } - - connectionInfo, err := volumeactions.InitializeConnection(client, volume.ID, connectOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", connectionInfo["data"]) - - terminateOpts := &volumeactions.InitializeConnectionOpts{ - IP: "127.0.0.1", - Host: "stack", - Initiator: "iqn.1994-05.com.redhat:17cf566367d2", - Multipath: eclcloud.Disabled, - Platform: "x86_64", - OSType: "linux2", - } - - err = volumeactions.TerminateConnection(client, volume.ID, terminateOpts).ExtractErr() - if err != nil { - panic(err) - } -*/ -package volumeactions diff --git a/v3/ecl/computevolume/extensions/volumeactions/requests.go b/v3/ecl/computevolume/extensions/volumeactions/requests.go deleted file mode 100644 index 9fe845d..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/requests.go +++ /dev/null @@ -1,84 +0,0 @@ -package volumeactions - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// ExtendSizeOptsBuilder allows extensions to add additional parameters to the -// ExtendSize request. -type ExtendSizeOptsBuilder interface { - ToVolumeExtendSizeMap() (map[string]interface{}, error) -} - -// ExtendSizeOpts contains options for extending the size of an existing Volume. -// This object is passed to the volumes.ExtendSize function. -type ExtendSizeOpts struct { - // NewSize is the new size of the volume, in GB. - NewSize int `json:"new_size" required:"true"` -} - -// ToVolumeExtendSizeMap assembles a request body based on the contents of an -// ExtendSizeOpts. -func (opts ExtendSizeOpts) ToVolumeExtendSizeMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "os-extend") -} - -// ExtendSize will extend the size of the volume based on the provided information. -// This operation does not return a response body. -func ExtendSize(client *eclcloud.ServiceClient, id string, opts ExtendSizeOptsBuilder) (r ExtendSizeResult) { - b, err := opts.ToVolumeExtendSizeMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(actionURL(client, id), b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// UploadImageOptsBuilder allows extensions to add additional parameters to the -// UploadImage request. -type UploadImageOptsBuilder interface { - ToVolumeUploadImageMap() (map[string]interface{}, error) -} - -// UploadImageOpts contains options for uploading a Volume to image storage. -type UploadImageOpts struct { - // Container format, may be bare, ofv, ova, etc. - ContainerFormat string `json:"container_format,omitempty"` - - // Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc. - DiskFormat string `json:"disk_format,omitempty"` - - // The name of image that will be stored in glance. - ImageName string `json:"image_name,omitempty"` - - // Force image creation, usable if volume attached to instance. - Force bool `json:"force,omitempty"` -} - -// ToVolumeUploadImageMap assembles a request body based on the contents of a -// UploadImageOpts. -func (opts UploadImageOpts) ToVolumeUploadImageMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "os-volume_upload_image") -} - -// UploadImage will upload an image based on the values in UploadImageOptsBuilder. -func UploadImage(client *eclcloud.ServiceClient, id string, opts UploadImageOptsBuilder) (r UploadImageResult) { - b, err := opts.ToVolumeUploadImageMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// ForceDelete will delete the volume regardless of state. -func ForceDelete(client *eclcloud.ServiceClient, id string) (r ForceDeleteResult) { - _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-force_delete": ""}, nil, nil) - return -} diff --git a/v3/ecl/computevolume/extensions/volumeactions/results.go b/v3/ecl/computevolume/extensions/volumeactions/results.go deleted file mode 100644 index 7a1cff1..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/results.go +++ /dev/null @@ -1,139 +0,0 @@ -package volumeactions - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" -) - -// UploadImageResult contains the response body and error from an UploadImage -// request. -type UploadImageResult struct { - eclcloud.Result -} - -// ExtendSizeResult contains the response body and error from an ExtendSize request. -type ExtendSizeResult struct { - eclcloud.ErrResult -} - -// ImageVolumeType contains volume type information obtained from UploadImage -// action. -type ImageVolumeType struct { - // The ID of a volume type. - ID string `json:"id"` - - // Human-readable display name for the volume type. - Name string `json:"name"` - - // Human-readable description for the volume type. - Description string `json:"display_description"` - - // Flag for public access. - IsPublic bool `json:"is_public"` - - // Extra specifications for volume type. - ExtraSpecs map[string]interface{} `json:"extra_specs"` - - // ID of quality of service specs. - QosSpecsID string `json:"qos_specs_id"` - - // Flag for deletion status of volume type. - Deleted bool `json:"deleted"` - - // The date when volume type was deleted. - DeletedAt time.Time `json:"-"` - - // The date when volume type was created. - CreatedAt time.Time `json:"-"` - - // The date when this volume was last updated. - UpdatedAt time.Time `json:"-"` -} - -func (r *ImageVolumeType) UnmarshalJSON(b []byte) error { - type tmp ImageVolumeType - var s struct { - tmp - CreatedAt eclcloud.JSONRFC3339MilliNoZ `json:"created_at"` - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - DeletedAt eclcloud.JSONRFC3339MilliNoZ `json:"deleted_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = ImageVolumeType(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - r.DeletedAt = time.Time(s.DeletedAt) - - return err -} - -// VolumeImage contains information about volume uploaded to an image service. -type VolumeImage struct { - // The ID of a volume an image is created from. - VolumeID string `json:"id"` - - // Container format, may be bare, ofv, ova, etc. - ContainerFormat string `json:"container_format"` - - // Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc. - DiskFormat string `json:"disk_format"` - - // Human-readable description for the volume. - Description string `json:"display_description"` - - // The ID of the created image. - ImageID string `json:"image_id"` - - // Human-readable display name for the image. - ImageName string `json:"image_name"` - - // Size of the volume in GB. - Size int `json:"size"` - - // Current status of the volume. - Status string `json:"status"` - - // The date when this volume was last updated. - UpdatedAt time.Time `json:"-"` - - // Volume type object of used volume. - VolumeType ImageVolumeType `json:"volume_type"` -} - -func (r *VolumeImage) UnmarshalJSON(b []byte) error { - type tmp VolumeImage - var s struct { - tmp - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = VolumeImage(s.tmp) - - r.UpdatedAt = time.Time(s.UpdatedAt) - - return err -} - -// Extract will get an object with info about the uploaded image out of the -// UploadImageResult object. -func (r UploadImageResult) Extract() (VolumeImage, error) { - var s struct { - VolumeImage VolumeImage `json:"os-volume_upload_image"` - } - err := r.ExtractInto(&s) - return s.VolumeImage, err -} - -// ForceDeleteResult contains the response body and error from a ForceDelete request. -type ForceDeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/computevolume/extensions/volumeactions/testing/doc.go b/v3/ecl/computevolume/extensions/volumeactions/testing/doc.go deleted file mode 100644 index 336406d..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// volumeactions unit tests -package testing diff --git a/v3/ecl/computevolume/extensions/volumeactions/testing/fixtures.go b/v3/ecl/computevolume/extensions/volumeactions/testing/fixtures.go deleted file mode 100644 index c643b80..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/testing/fixtures.go +++ /dev/null @@ -1,49 +0,0 @@ -package testing - -import ( - "fmt" -) - -const volumeID = "ff2ac0fd-ea58-4e15-bd71-aec0bc58c469" -const instanceID = "ff2ac0fd-ea58-4e15-bd71-aec0bc58c469" - -const uploadImageRequest = `{ - "os-volume_upload_image": { - "container_format": "bare", - "force": true, - "image_name": "imagetest", - "disk_format": "raw" - } -}` - -var uploadImageResponse = fmt.Sprintf(`{ - "os-volume_upload_image": { - "status": "uploading", - "image_id": "49d7efe7-975e-46d7-af0a-fd94fe8e62bf", - "image_name": "imagetest", - "volume_type": { - "name": "nfsdriver", - "qos_specs_id": null, - "deleted": false, - "created_at": "2018-06-04T08:05:09.000000", - "updated_at": null, - "deleted_at": null, - "id": "1f02ea8f-3823-4e69-a232-695adc39f5e0" - }, - "container_format": "bare", - "size": 40, - "disk_format": "raw", - "id": "%s", - "display_description": "test volume 2update", - "updated_at": "2019-02-06T22:06:27.000000" - } -}`, - volumeID, -) - -const extendRequest = `{ - "os-extend": - { - "new_size": 40 - } -}` diff --git a/v3/ecl/computevolume/extensions/volumeactions/testing/requests_test.go b/v3/ecl/computevolume/extensions/volumeactions/testing/requests_test.go deleted file mode 100644 index 2c86957..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/testing/requests_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/computevolume/extensions/volumeactions" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestVolumeUploadImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s/action", volumeID) - - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, uploadImageRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, uploadImageResponse) - }) - - options := &volumeactions.UploadImageOpts{ - ContainerFormat: "bare", - Force: true, - ImageName: "imagetest", - DiskFormat: "raw", - } - - actual, err := volumeactions.UploadImage(fakeclient.ServiceClient(), volumeID, options).Extract() - th.AssertNoErr(t, err) - - expected := volumeactions.VolumeImage{ - Status: "uploading", - ImageID: "49d7efe7-975e-46d7-af0a-fd94fe8e62bf", - ImageName: "imagetest", - VolumeType: volumeactions.ImageVolumeType{ - Name: "nfsdriver", - QosSpecsID: "", - Deleted: false, - CreatedAt: time.Date(2018, 6, 4, 8, 5, 9, 0, time.UTC), - UpdatedAt: time.Time{}, - DeletedAt: time.Time{}, - ID: "1f02ea8f-3823-4e69-a232-695adc39f5e0", - }, - ContainerFormat: "bare", - Size: 40, - DiskFormat: "raw", - VolumeID: volumeID, - Description: "test volume 2update", - UpdatedAt: time.Date(2019, 2, 6, 22, 6, 27, 0, time.UTC), - } - th.AssertDeepEquals(t, expected, actual) -} - -func TestVolumeExtendSize(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s/action", volumeID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, extendRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - }) - - options := &volumeactions.ExtendSizeOpts{ - NewSize: 40, - } - - err := volumeactions.ExtendSize(fakeclient.ServiceClient(), volumeID, options).ExtractErr() - th.AssertNoErr(t, err) -} diff --git a/v3/ecl/computevolume/extensions/volumeactions/urls.go b/v3/ecl/computevolume/extensions/volumeactions/urls.go deleted file mode 100644 index b6d2368..0000000 --- a/v3/ecl/computevolume/extensions/volumeactions/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package volumeactions - -import "github.com/nttcom/eclcloud/v3" - -func actionURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("volumes", id, "action") -} diff --git a/v3/ecl/computevolume/v2/volumes/doc.go b/v3/ecl/computevolume/v2/volumes/doc.go deleted file mode 100644 index 98fdc6b..0000000 --- a/v3/ecl/computevolume/v2/volumes/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package volumes provides information and interaction with volumes in the -// Enterprise Cloud Block Storage service. A volume is a detachable block storage -// device, akin to a USB hard drive. It can only be attached to one instance at -// a time. -package volumes diff --git a/v3/ecl/computevolume/v2/volumes/requests.go b/v3/ecl/computevolume/v2/volumes/requests.go deleted file mode 100644 index 35dfeab..0000000 --- a/v3/ecl/computevolume/v2/volumes/requests.go +++ /dev/null @@ -1,207 +0,0 @@ -package volumes - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToVolumeCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a Volume. This object is passed to -// the volumes.Create function. For more information about these parameters, -// see the Volume object. -type CreateOpts struct { - // The size of the volume, in GB - Size int `json:"size" required:"true"` - // The availability zone - AvailabilityZone string `json:"availability_zone,omitempty"` - // ConsistencyGroupID is the ID of a consistency group - ConsistencyGroupID string `json:"consistencygroup_id,omitempty"` - // The volume description - Description string `json:"description,omitempty"` - // One or more metadata key and value pairs to associate with the volume - Metadata map[string]string `json:"metadata,omitempty"` - // The volume name - Name string `json:"name,omitempty"` - // the ID of the existing volume snapshot - SnapshotID string `json:"snapshot_id,omitempty"` - // SourceReplica is a UUID of an existing volume to replicate with - SourceReplica string `json:"source_replica,omitempty"` - // the ID of the existing volume - SourceVolID string `json:"source_volid,omitempty"` - // The ID of the image from which you want to create the volume. - // Required to create a bootable volume. - ImageID string `json:"imageRef,omitempty"` - // The associated volume type - VolumeType string `json:"volume_type,omitempty"` -} - -// ToVolumeCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "volume") -} - -// Create will create a new Volume based on the values in CreateOpts. To extract -// the Volume object from the response, call the Extract method on the -// CreateResult. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToVolumeCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// Delete will delete the existing Volume with the provided ID. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// Get retrieves the Volume with the provided ID. To extract the Volume object -// from the response, call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToVolumeListQuery() (string, error) -} - -// ListOpts holds options for listing Volumes. It is passed to the volumes.List -// function. -type ListOpts struct { - // AllTenants will retrieve volumes of all tenants/projects. - AllTenants bool `q:"all_tenants"` - - // Metadata will filter results based on specified metadata. - Metadata map[string]string `q:"metadata"` - - // Name will filter by the specified volume name. - Name string `q:"name"` - - // Status will filter by the specified status. - Status string `q:"status"` - - // TenantID will filter by a specific tenant/project ID. - // Setting AllTenants is required for this. - TenantID string `q:"project_id"` - - // Comma-separated list of sort keys and optional sort directions in the - // form of [:]. - Sort string `q:"sort"` - - // Requests a page size of items. - Limit int `q:"limit"` - - // Used in conjunction with limit to return a slice of items. - Offset int `q:"offset"` - - // The ID of the last-seen item. - Marker string `q:"marker"` -} - -// ToVolumeListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVolumeListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns Volumes optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToVolumeListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VolumePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToVolumeUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contain options for updating an existing Volume. This object is passed -// to the volumes.Update function. For more information about the parameters, see -// the Volume object. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Metadata *map[string]string `json:"metadata,omitempty"` -} - -// ToVolumeUpdateMap assembles a request body based on the contents of an -// UpdateOpts. -func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "volume") -} - -// Update will update the Volume with provided information. To extract the updated -// Volume from the response, call the Extract method on the UpdateResult. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToVolumeUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// IDFromName is a convienience function that returns a server's ID given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractVolumes(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "volume"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"} - } -} diff --git a/v3/ecl/computevolume/v2/volumes/results.go b/v3/ecl/computevolume/v2/volumes/results.go deleted file mode 100644 index e7066fa..0000000 --- a/v3/ecl/computevolume/v2/volumes/results.go +++ /dev/null @@ -1,169 +0,0 @@ -package volumes - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type Attachment struct { - AttachedAt time.Time `json:"-"` - AttachmentID string `json:"attachment_id"` - Device string `json:"device"` - HostName string `json:"host_name"` - ID string `json:"id"` - ServerID string `json:"server_id"` - VolumeID string `json:"volume_id"` -} - -func (r *Attachment) UnmarshalJSON(b []byte) error { - type tmp Attachment - var s struct { - tmp - AttachedAt eclcloud.JSONRFC3339MilliNoZ `json:"attached_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Attachment(s.tmp) - - r.AttachedAt = time.Time(s.AttachedAt) - - return err -} - -// Volume contains all the information associated with an Enterprise Cloud Volume. -type Volume struct { - // Unique identifier for the volume. - ID string `json:"id"` - // Current status of the volume. - Status string `json:"status"` - // Size of the volume in GB. - Size int `json:"size"` - // AvailabilityZone is which availability zone the volume is in. - AvailabilityZone string `json:"availability_zone"` - // The date when this volume was created. - CreatedAt time.Time `json:"-"` - // The date when this volume was last updated - UpdatedAt time.Time `json:"-"` - // Instances onto which the volume is attached. - Attachments []Attachment `json:"attachments"` - // Human-readable display name for the volume. - Name string `json:"name"` - // Human-readable description for the volume. - Description string `json:"description"` - // The type of volume to create, either SATA or SSD. - VolumeType string `json:"volume_type"` - // The ID of the snapshot from which the volume was created - SnapshotID string `json:"snapshot_id"` - // The ID of another block storage volume from which the current volume was created - SourceVolID string `json:"source_volid"` - // Arbitrary key-value pairs defined by the user. - Metadata map[string]string `json:"metadata"` - // UserID is the id of the user who created the volume. - UserID string `json:"user_id"` - // Indicates whether this is a bootable volume. - Bootable string `json:"bootable"` - // Encrypted denotes if the volume is encrypted. - Encrypted bool `json:"encrypted"` - // ReplicationStatus is the status of replication. - ReplicationStatus string `json:"replication_status"` - // ConsistencyGroupID is the consistency group ID. - ConsistencyGroupID string `json:"consistencygroup_id"` - // Multiattach denotes if the volume is multi-attach capable. - Multiattach bool `json:"multiattach"` - // TenantID is the id of the project that owns the volume. - TenantID string `json:"os-vol-tenant-attr:tenant_id"` -} - -func (r *Volume) UnmarshalJSON(b []byte) error { - type tmp Volume - var s struct { - tmp - CreatedAt eclcloud.JSONRFC3339MilliNoZ `json:"created_at"` - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Volume(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - - return err -} - -// VolumePage is a pagination.pager that is returned from a call to the List function. -type VolumePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a ListResult contains no Volumes. -func (r VolumePage) IsEmpty() (bool, error) { - volumes, err := ExtractVolumes(r) - return len(volumes) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to the -// next page of results. -func (r VolumePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"volumes_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. -func ExtractVolumes(r pagination.Page) ([]Volume, error) { - var s []Volume - err := ExtractVolumesInto(r, &s) - return s, err -} - -type commonResult struct { - eclcloud.Result -} - -// Extract will get the Volume object out of the commonResult object. -func (r commonResult) Extract() (*Volume, error) { - var s Volume - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "volume") -} - -func ExtractVolumesInto(r pagination.Page, v interface{}) error { - return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes") -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// UpdateResult contains the response body and error from an Update request. -type UpdateResult struct { - commonResult -} - -// DeleteResult contains the response body and error from a Delete request. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/computevolume/v2/volumes/testing/doc.go b/v3/ecl/computevolume/v2/volumes/testing/doc.go deleted file mode 100644 index 100d586..0000000 --- a/v3/ecl/computevolume/v2/volumes/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// volumes_v2 unittest -package testing diff --git a/v3/ecl/computevolume/v2/volumes/testing/fixtures.go b/v3/ecl/computevolume/v2/volumes/testing/fixtures.go deleted file mode 100644 index 130f261..0000000 --- a/v3/ecl/computevolume/v2/volumes/testing/fixtures.go +++ /dev/null @@ -1,358 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/computevolume/v2/volumes" -) - -const idVolume1 = "251df9eb-c088-4e71-808b-75a690e8814b" -const idVolume2 = "7e0b432b-c922-49d7-b85a-28ac88164328" - -const sizeVolume1 = 40 - -const nameVolume1 = "volume1" -const nameVolume1Update = "volume1-update" - -const descriptionVolume1 = "test volume 1" -const descriptionVolume1Update = "test volume 1-update" - -const instanceID = "83ec2e3b-4321-422b-8706-a84185f52a0a" -const tenantID = "9ee80f2a926c49f88f166af47df4e9f5" -const az = "zone1-groupa" - -const createdAt = "2019-02-06T08:06:57.000000" - -var timeCreatedAt = time.Date(2019, 2, 6, 8, 6, 57, 0, time.UTC) - -var listResponse = fmt.Sprintf(`{ - "volumes": [{ - "id": "%s", - "name": "%s", - "status": "in-use", - "size": %d, - "availability_zone": "%s", - "created_at": "%s", - "os-vol-tenant-attr:tenant_id": "%s", - "description": "%s", - "attachments": [{ - "host_name": null, - "device": "/dev/vdb", - "server_id": "%s", - "id": "%s", - "volume_id": "%s" - }], - "links": [{ - "href": "dummy_self_link", - "rel": "self" - }, { - "href": "dummy_bookmark_link", - "rel": "bookmark" - }], - "encrypted": false, - "os-volume-replication:extended_status": null, - "volume_type": "nfsdriver", - "snapshot_id": null, - "user_id": "2a5719084bc9457c93e659f4f13c6bfc", - "metadata": { - "readonly": "False", - "attached_mode": "rw" - }, - "volume_image_metadata": { - ".edition": "none", - ".major.version": "7", - ".official_image_template": "CentOS-7.1-1503_64_virtual-server_12", - "container_format": "bare", - "min_ram": "0", - "disk_format": "qcow2", - ".is_license": "False", - "image_name": "CentOS-7.1-1503_64_virtual-server_12", - "image_id": "df1944a7-ca45-4709-9ec6-e31664133650", - ".os.type": "centos", - ".enable.download": "True", - "checksum": "a828b6ba68b9d13d2da0a0cb3cfaa950", - "min_disk": "15", - ".service.type": "virtual-server", - ".virtual_server.os.pod": "other", - ".minor.version": "1-1503", - "size": "461504512" - }, - "source_volid": null, - "consistencygroup_id": null, - "bootable": "true", - "os-volume-replication:driver_data": null, - "replication_status": "disabled" - }, { - "id": "%s", - "name": "volume 2", - "status": "available", - "size": 40, - "availability_zone": "%s", - "created_at": "%s", - "os-vol-tenant-attr:tenant_id": "%s", - "description": "test volume 2", - "attachments": [], - "links": [{ - "href": "dummy_self_link", - "rel": "self" - }, { - "href": "dummy_bookmark_link", - "rel": "bookmark" - }], - "encrypted": false, - "os-volume-replication:extended_status": null, - "volume_type": "nfsdriver", - "snapshot_id": null, - "user_id": "2a5719084bc9457c93e659f4f13c6bfc", - "metadata": {}, - "volume_image_metadata": { - ".edition": "none", - ".major.version": "7", - "container_format": "bare", - "min_ram": "0", - "disk_format": "qcow2", - ".is_license": "True", - "image_name": "RedHatEnterpriseLinux-7.1_64_include-license_virtual-server_42", - "image_id": "f304bc07-056a-406f-85fc-9f97c7b8ef95", - ".os.type": "rhel", - ".enable.download": "False", - "checksum": "85851188a680c5bddecb664914917a81", - "min_disk": "40", - ".service.type": "virtual-server", - ".virtual_server.os.pod": "rhel", - ".minor.version": "1", - "size": "515899392" - }, - "source_volid": null, - "consistencygroup_id": null, - "bootable": "true", - "os-volume-replication:driver_data": null, - "replication_status": "disabled" - }] -}`, - // For volume 1 - idVolume1, - nameVolume1, - sizeVolume1, - az, - createdAt, - tenantID, - descriptionVolume1, - instanceID, - idVolume1, - idVolume1, - // For volume 2 - idVolume2, - az, - createdAt, - tenantID, -) - -var structVolume1 = volumes.Volume{ - ID: idVolume1, - Status: "in-use", - Size: sizeVolume1, - AvailabilityZone: az, - CreatedAt: timeCreatedAt, - Attachments: []volumes.Attachment{{ - // AttachedAt: time.Date(2016, 8, 6, 14, 48, 20, 0, time.UTC), - // AttachmentID: idVolume1, - Device: "/dev/vdb", - HostName: "", - ID: idVolume1, - ServerID: instanceID, - VolumeID: idVolume1, - }}, - Name: nameVolume1, - Description: descriptionVolume1, - VolumeType: "nfsdriver", - SnapshotID: "", - SourceVolID: "", - Metadata: map[string]string{ - "readonly": "False", - "attached_mode": "rw", - }, - UserID: "2a5719084bc9457c93e659f4f13c6bfc", - Bootable: "true", - Encrypted: false, - ReplicationStatus: "disabled", - TenantID: tenantID, -} - -var structVolume2 = volumes.Volume{ - ID: idVolume2, - Status: "available", - Size: 40, - AvailabilityZone: az, - CreatedAt: timeCreatedAt, - Attachments: []volumes.Attachment{}, - Name: "volume 2", - Description: "test volume 2", - VolumeType: "nfsdriver", - SnapshotID: "", - SourceVolID: "", - Metadata: map[string]string{}, - UserID: "2a5719084bc9457c93e659f4f13c6bfc", - Bootable: "true", - Encrypted: false, - ReplicationStatus: "disabled", - TenantID: tenantID, -} - -var expectedVolumesSlice = []volumes.Volume{ - structVolume1, - structVolume2, -} - -var getResponse = fmt.Sprintf(`{ - "volume": { - "id": "%s", - "name": "%s", - "status": "in-use", - "size": %d, - "availability_zone": "%s", - "created_at": "%s", - "os-vol-tenant-attr:tenant_id": "%s", - "description": "%s", - "attachments": [{ - "host_name": null, - "device": "/dev/vdb", - "server_id": "%s", - "id": "%s", - "volume_id": "%s" - }], - "links": [{ - "href": "dummy_self_link", - "rel": "self" - }, { - "href": "dummy_bookmark_link", - "rel": "bookmark" - }], - "encrypted": false, - "os-volume-replication:extended_status": null, - "volume_type": "nfsdriver", - "snapshot_id": null, - "user_id": "2a5719084bc9457c93e659f4f13c6bfc", - "metadata": { - "readonly": "False", - "attached_mode": "rw" - }, - "volume_image_metadata": { - ".edition": "none", - ".major.version": "7", - ".official_image_template": "CentOS-7.1-1503_64_virtual-server_12", - "container_format": "bare", - "min_ram": "0", - "disk_format": "qcow2", - ".is_license": "False", - "image_name": "CentOS-7.1-1503_64_virtual-server_12", - "image_id": "df1944a7-ca45-4709-9ec6-e31664133650", - ".os.type": "centos", - ".enable.download": "True", - "checksum": "a828b6ba68b9d13d2da0a0cb3cfaa950", - "min_disk": "15", - ".service.type": "virtual-server", - ".virtual_server.os.pod": "other", - ".minor.version": "1-1503", - "size": "461504512" - }, - "source_volid": null, - "consistencygroup_id": null, - "bootable": "true", - "os-volume-replication:driver_data": null, - "replication_status": "disabled" - } -}`, - idVolume1, - nameVolume1, - sizeVolume1, - az, - createdAt, - tenantID, - descriptionVolume1, - instanceID, - idVolume1, - idVolume1, -) - -var createRequest = fmt.Sprintf(`{ - "volume": { - "size": 15, - "availability_zone": "%s", - "description": "%s", - "name": "%s", - "imageRef": "dummyimage" - } -}`, - az, - descriptionVolume1, - nameVolume1, -) - -var createResponse = fmt.Sprintf(`{ - "volume": { - "status": "creating", - "user_id": "2a5719084bc9457c93e659f4f13c6bfc", - "attachments": [], - "links": [{ - "href": "https://cinder-jp4-ecl.api.ntt.com/v2/9ee80f2a926c49f88f166af47df4e9f5/volumes/251df9eb-c088-4e71-808b-75a690e8814b", - "rel": "self" - }, { - "href": "https://cinder-jp4-ecl.api.ntt.com/9ee80f2a926c49f88f166af47df4e9f5/volumes/251df9eb-c088-4e71-808b-75a690e8814b", - "rel": "bookmark" - }], - "availability_zone": "%s", - "bootable": "false", - "encrypted": false, - "created_at": "2019-02-06T08:06:57.581271", - "description": "%s", - "volume_type": "nfsdriver", - "name": "%s", - "replication_status": "disabled", - "consistencygroup_id": null, - "source_volid": null, - "snapshot_id": null, - "metadata": {}, - "id": "%s", - "size": 15 - } -}`, az, - descriptionVolume1, - nameVolume1, - idVolume1, -) - -var updateResponse = fmt.Sprintf(`{ - "volume": { - "status": "available", - "user_id": "2a5719084bc9457c93e659f4f13c6bfc", - "attachments": [], - "links": [{ - "href": "https://cinder-jp4-ecl.api.ntt.com/v2/9ee80f2a926c49f88f166af47df4e9f5/volumes/7e0b432b-c922-49d7-b85a-28ac88164328", - "rel": "self" - }, { - "href": "https://cinder-jp4-ecl.api.ntt.com/9ee80f2a926c49f88f166af47df4e9f5/volumes/7e0b432b-c922-49d7-b85a-28ac88164328", - "rel": "bookmark" - }], - "availability_zone": "%s", - "bootable": "true", - "encrypted": false, - "created_at": "2019-02-06T08:08:32.000000", - "description": "%s", - "volume_type": "nfsdriver", - "name": "%s", - "replication_status": "disabled", - "consistencygroup_id": null, - "source_volid": null, - "snapshot_id": null, - "metadata": {}, - "id": "%s", - "size": 40 - } -}`, - az, - descriptionVolume1Update, - nameVolume1Update, - idVolume1, -) diff --git a/v3/ecl/computevolume/v2/volumes/testing/requests_test.go b/v3/ecl/computevolume/v2/volumes/testing/requests_test.go deleted file mode 100644 index c38c5fb..0000000 --- a/v3/ecl/computevolume/v2/volumes/testing/requests_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/computevolume/v2/volumes" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListVolumeAll(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/volumes/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, listResponse) - }) - - allPages, err := volumes.List(fakeclient.ServiceClient(), &volumes.ListOpts{}).AllPages() - th.AssertNoErr(t, err) - actual, err := volumes.ExtractVolumes(allPages) - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, expectedVolumesSlice, actual) - -} - -func TestGetVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s", idVolume1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, getResponse) - }) - - v, err := volumes.Get(fakeclient.ServiceClient(), idVolume1).Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, &expectedVolumesSlice[0], v) -} - -func TestCreateVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, createRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, createResponse) - }) - - options := &volumes.CreateOpts{ - Size: 15, - AvailabilityZone: az, - Description: descriptionVolume1, - Name: nameVolume1, - ImageID: "dummyimage", - } - v, err := volumes.Create(fakeclient.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, v.AvailabilityZone, az) - th.AssertEquals(t, v.Size, 15) - th.AssertEquals(t, v.ID, idVolume1) - th.AssertEquals(t, v.Description, descriptionVolume1) -} - -func TestUpdatVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s", idVolume1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, updateResponse) - }) - - name := nameVolume1Update - description := descriptionVolume1Update - metadata := map[string]string{} - - updateOpts := volumes.UpdateOpts{ - Name: &name, - Description: &description, - Metadata: &metadata, - } - - v, err := volumes.Update(fakeclient.ServiceClient(), idVolume1, updateOpts).Extract() - - blankMeta := map[string]string{} - th.AssertNoErr(t, err) - th.CheckEquals(t, nameVolume1Update, v.Name) - th.CheckEquals(t, descriptionVolume1Update, v.Description) - th.CheckDeepEquals(t, &blankMeta, &v.Metadata) -} - -func TestDeleteVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s", idVolume1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - w.WriteHeader(http.StatusAccepted) - }) - - res := volumes.Delete(fakeclient.ServiceClient(), idVolume1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/computevolume/v2/volumes/urls.go b/v3/ecl/computevolume/v2/volumes/urls.go deleted file mode 100644 index 4865b34..0000000 --- a/v3/ecl/computevolume/v2/volumes/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package volumes - -import "github.com/nttcom/eclcloud/v3" - -func createURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("volumes") -} - -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("volumes", "detail") -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("volumes", id) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} diff --git a/v3/ecl/computevolume/v2/volumes/util.go b/v3/ecl/computevolume/v2/volumes/util.go deleted file mode 100644 index 548329c..0000000 --- a/v3/ecl/computevolume/v2/volumes/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package volumes - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// WaitForStatus will continually poll the resource, checking for a particular -// status. It will do this for the amount of seconds defined. -func WaitForStatus(c *eclcloud.ServiceClient, id, status string, secs int) error { - return eclcloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/doc.go b/v3/ecl/dedicated_hypervisor/v1/license_types/doc.go deleted file mode 100644 index f7ed6ce..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Package license_types manages and retrieves license type in the Enterprise Cloud Dedicated Hypervisor Service. - -Example to List License types - - allPages, err := license_types.List(dhClient).AllPages() - if err != nil { - panic(err) - } - - allLicenseTypes, err := license_types.ExtractLicenseTypes(allPages) - if err != nil { - panic(err) - } - - for _, licenseType := range allLicenseTypes { - fmt.Printf("%+v\n", licenseType) - } -*/ -package license_types diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/requests.go b/v3/ecl/dedicated_hypervisor/v1/license_types/requests.go deleted file mode 100644 index 278aed7..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/requests.go +++ /dev/null @@ -1,14 +0,0 @@ -package license_types - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List retrieves a list of LicenseTypes. -func List(client *eclcloud.ServiceClient) pagination.Pager { - url := listURL(client) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return LicenseTypePage{pagination.LinkedPageBase{PageResult: r}} - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/results.go b/v3/ecl/dedicated_hypervisor/v1/license_types/results.go deleted file mode 100644 index ad63b95..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/results.go +++ /dev/null @@ -1,35 +0,0 @@ -package license_types - -import ( - "github.com/nttcom/eclcloud/v3/pagination" -) - -// LicenseType represents guest image license information. -type LicenseType struct { - ID string `json:"id"` - Name string `json:"name"` - HasLicenseKey bool `json:"has_license_key"` - Unit string `json:"unit"` - LicenseSwitch bool `json:"license_switch"` - Description string `json:"description"` -} - -// LicenseTypePage is a single page of LicenseType results. -type LicenseTypePage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of LicenseTypes contains any results. -func (r LicenseTypePage) IsEmpty() (bool, error) { - licenses, err := ExtractLicenseTypes(r) - return len(licenses) == 0, err -} - -// ExtractLicenseTypes returns a slice of LicenseTypes contained in a single page of results. -func ExtractLicenseTypes(r pagination.Page) ([]LicenseType, error) { - var s struct { - LicenseTypes []LicenseType `json:"license_types"` - } - err := (r.(LicenseTypePage)).ExtractInto(&s) - return s.LicenseTypes, err -} diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/testing/fixtures.go b/v3/ecl/dedicated_hypervisor/v1/license_types/testing/fixtures.go deleted file mode 100644 index ba7cee0..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/testing/fixtures.go +++ /dev/null @@ -1,73 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/license_types" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// ListResult provides a single page of LicenseType results. -const ListResult = ` -{ - "license_types": [ - { - "description": "Windows Server 2016 Standard Edition", - "has_license_key": false, - "id": "9c54c437-5f0f-46f5-8270-ddf450a44135", - "license_switch": true, - "name": "Windows Server 2016 Standard Edition", - "unit": "VM" - }, - { - "description": "vCenter Server 6.x Standard", - "has_license_key": true, - "id": "e37c05ba-8fd0-493e-93d2-688833363a74", - "license_switch": false, - "name": "vCenter Server 6.x Standard", - "unit": "License" - } - ] -} -` - -// FirstLicenseType is the first LicenseType in the List request. -var FirstLicenseType = license_types.LicenseType{ - ID: "9c54c437-5f0f-46f5-8270-ddf450a44135", - Name: "Windows Server 2016 Standard Edition", - HasLicenseKey: false, - Unit: "VM", - LicenseSwitch: true, - Description: "Windows Server 2016 Standard Edition", -} - -// SecondLicenseType is the second LicenseType in the List request. -var SecondLicenseType = license_types.LicenseType{ - ID: "e37c05ba-8fd0-493e-93d2-688833363a74", - Name: "vCenter Server 6.x Standard", - HasLicenseKey: true, - Unit: "License", - LicenseSwitch: false, - Description: "vCenter Server 6.x Standard", -} - -// ExpectedLicenseTypesSlice is the slice of LicenseTypes expected to be returned from ListResult. -var ExpectedLicenseTypesSlice = []license_types.LicenseType{FirstLicenseType, SecondLicenseType} - -// HandleListLicenseTypesSuccessfully creates an HTTP handler at `/license_types` on the -// test handler mux that responds with a list of two LicenseType. -func HandleListLicenseTypesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/license_types", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/testing/requests_test.go b/v3/ecl/dedicated_hypervisor/v1/license_types/testing/requests_test.go deleted file mode 100644 index 3b999e1..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/testing/requests_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/license_types" - - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListLicenseTypes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLicenseTypesSuccessfully(t) - - count := 0 - err := license_types.List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := license_types.ExtractLicenseTypes(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedLicenseTypesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListLicenseTypesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLicenseTypesSuccessfully(t) - - allPages, err := license_types.List(client.ServiceClient()).AllPages() - th.AssertNoErr(t, err) - actual, err := license_types.ExtractLicenseTypes(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedLicenseTypesSlice, actual) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/license_types/urls.go b/v3/ecl/dedicated_hypervisor/v1/license_types/urls.go deleted file mode 100644 index 1768654..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/license_types/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package license_types - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("license_types") -} diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/doc.go b/v3/ecl/dedicated_hypervisor/v1/licenses/doc.go deleted file mode 100644 index a35c2aa..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/doc.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Package licenses manages and retrieves license in the Enterprise Cloud Dedicated Hypervisor Service. - -Example to List Licenses - - listOpts := licenses.ListOpts{ - LicenseType: "vCenter Server 6.x Standard", - } - - allPages, err := licenses.List(dhClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allLicenses, err := licenses.ExtractLicenses(allPages) - if err != nil { - panic(err) - } - - for _, license := range allLicenses { - fmt.Printf("%+v\n", license) - } - -Example to Create a License - - createOpts := licenses.CreateOpts{ - LicenseType: "vCenter Server 6.x Standard", - } - - result := licenses.Create(dhClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a license - - licenseID := "02471b45-3de0-4fc8-8469-a7cc52c378df" - - result := licenses.Delete(dhClient, licenseID) - if result.Err != nil { - panic(result.Err) - } -*/ -package licenses diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/requests.go b/v3/ecl/dedicated_hypervisor/v1/licenses/requests.go deleted file mode 100644 index 6f444dd..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/requests.go +++ /dev/null @@ -1,76 +0,0 @@ -package licenses - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToResourceListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - LicenseType string `q:"license_type"` -} - -// ToResourceListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToResourceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List retrieves a list of Licenses. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToResourceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return LicensePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToResourceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a License. -type CreateOpts struct { - LicenseType string `json:"license_type"` -} - -// ToResourceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToResourceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new License. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToResourceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a License. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/results.go b/v3/ecl/dedicated_hypervisor/v1/licenses/results.go deleted file mode 100644 index 4b81b89..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/results.go +++ /dev/null @@ -1,63 +0,0 @@ -package licenses - -import ( - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// License represents guest image license key information. -type License struct { - ID string `json:"id"` - Key string `json:"key"` - AssignedFrom time.Time `json:"assigned_from"` - ExpiresAt *time.Time `json:"expires_at"` - LicenseType string `json:"license_type"` -} - -type commonResult struct { - eclcloud.Result -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a License. -type CreateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// LicensePage is a single page of License results. -type LicensePage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Licenses contains any results. -func (r LicensePage) IsEmpty() (bool, error) { - licenses, err := ExtractLicenses(r) - return len(licenses) == 0, err -} - -// ExtractLicenses returns a slice of Licenses contained in a single page of -// results. -func ExtractLicenses(r pagination.Page) ([]License, error) { - var s struct { - Licenses []License `json:"licenses"` - } - err := (r.(LicensePage)).ExtractInto(&s) - return s.Licenses, err -} - -// ExtractLicenseInfo interprets any commonResult as a License. -func (r commonResult) ExtractLicenseInfo() (*License, error) { - var s struct { - License *License `json:"license"` - } - err := r.ExtractInto(&s) - return s.License, err -} diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/testing/fixtures.go b/v3/ecl/dedicated_hypervisor/v1/licenses/testing/fixtures.go deleted file mode 100644 index 0050613..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/testing/fixtures.go +++ /dev/null @@ -1,114 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/licenses" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// ListResult provides a single page of License results. -const ListResult = ` -{ - "licenses": [ - { - "id": "02471b45-3de0-4fc8-8469-a7cc52c378df", - "key": "5H69L-8C3D7-K8292-03926-CREMN", - "assigned_from": "2017-04-27T09:20:47Z", - "expires_at": null, - "license_type": "vCenter Server 6.x Standard" - }, - { - "id": "0801a388-68e8-4e41-9158-73571117c915", - "key": "0021L-8CJ47-2829A-0A8K2-CXN4J", - "assigned_from": "2017-06-01T04:13:31Z", - "expires_at": null, - "license_type": "vCenter Server 6.x Standard" - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "license": { - "id": "0801a388-68e8-4e41-9158-73571117c915", - "key": "0021L-8CJ47-2829A-0A8K2-CXN4J", - "assigned_from": "2017-06-01T04:13:31Z", - "expires_at": null, - "license_type": "vCenter Server 6.x Standard" - } -} -` - -// CreateRequest provides the input to a Create request. -const CreateRequest = ` -{ - "license_type": "vCenter Server 6.x Standard" -} -` - -// FirstLicense is the first License in the List request. -var FirstLicense = licenses.License{ - ID: "02471b45-3de0-4fc8-8469-a7cc52c378df", - Key: "5H69L-8C3D7-K8292-03926-CREMN", - AssignedFrom: time.Date(2017, 4, 27, 9, 20, 47, 0, time.UTC), - ExpiresAt: nil, - LicenseType: "vCenter Server 6.x Standard", -} - -// SecondLicense is the second License in the List request. -var SecondLicense = licenses.License{ - ID: "0801a388-68e8-4e41-9158-73571117c915", - Key: "0021L-8CJ47-2829A-0A8K2-CXN4J", - AssignedFrom: time.Date(2017, 6, 1, 4, 13, 31, 0, time.UTC), - ExpiresAt: nil, - LicenseType: "vCenter Server 6.x Standard", -} - -// ExpectedLicensesSlice is the slice of Licenses expected to be returned from ListResult. -var ExpectedLicensesSlice = []licenses.License{FirstLicense, SecondLicense} - -// HandleListLicenseSuccessfully creates an HTTP handler at `/licenses` on the -// test handler mux that responds with a list of two Licenses. -func HandleListLicensesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/licenses", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} - -// HandleCreateLicenseSuccessfully creates an HTTP handler at `/licenses` on the -// test handler mux that tests License creation. -func HandleCreateLicenseSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/licenses", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResult) - }) -} - -// HandleDeleteLicenseSuccessfully creates an HTTP handler at `/licenses` on the -// test handler mux that tests License deletion. -func HandleDeleteLicenseSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/licenses/%s", FirstLicense.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/testing/requests_test.go b/v3/ecl/dedicated_hypervisor/v1/licenses/testing/requests_test.go deleted file mode 100644 index d417578..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/testing/requests_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/licenses" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListLicenses(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLicensesSuccessfully(t) - - count := 0 - err := licenses.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := licenses.ExtractLicenses(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedLicensesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListLicensesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListLicensesSuccessfully(t) - - allPages, err := licenses.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := licenses.ExtractLicenses(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedLicensesSlice, actual) -} - -func TestCreateLicense(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateLicenseSuccessfully(t) - - createOpts := licenses.CreateOpts{ - LicenseType: SecondLicense.LicenseType, - } - - actual, err := licenses.Create(client.ServiceClient(), createOpts).ExtractLicenseInfo() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondLicense, *actual) -} - -func TestDeleteLicense(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteLicenseSuccessfully(t) - - res := licenses.Delete(client.ServiceClient(), FirstLicense.ID) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/licenses/urls.go b/v3/ecl/dedicated_hypervisor/v1/licenses/urls.go deleted file mode 100644 index 0fffd00..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/licenses/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package licenses - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("licenses") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("licenses") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("licenses", id) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/doc.go b/v3/ecl/dedicated_hypervisor/v1/servers/doc.go deleted file mode 100644 index 5bc3134..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/doc.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Package servers manages and retrieves servers in the Enterprise Cloud Dedicated Hypervisor Service. - -Example to List servers - - listOpts := servers.ListOpts{ - Limit: 10, - } - - allPages, err := servers.List(dhClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allServers, err := servers.ExtractServers(allPages) - if err != nil { - panic(err) - } - - for _, server := range allServers { - fmt.Printf("%+v\n", server) - } - -Example to List servers details - - listOpts := servers.ListOpts{ - Limit: 10, - } - - allPages, err := servers.ListDetails(dhClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allServers, err := servers.ExtractServers(allPages) - if err != nil { - panic(err) - } - - for _, server := range allServers { - fmt.Printf("%+v\n", server) - } - -Example to Get a server - - serverID := "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - - result := servers.Get(dhClient, serverID) - if result.Err != nil { - panic(result.Err) - } - - server, err := result.Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", server) - -Example to Create a server - - createOpts := servers.CreateOpts{ - Name: "test", - Networks: []servers.Network{ - { - UUID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - Plane: "data", - SegmentationID: 6, - }, - { - UUID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - Plane: "data", - SegmentationID: 6, - }, - }, - ImageRef: "dfd25820-b368-4012-997b-29a6d0cf8518", - FlavorRef: "a830b61c-3155-4a61-b7ed-c450862845e6", - } - - result := servers.Create(dhClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a server - - serverID := "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - - result := servers.Delete(dhClient, serverID) - if result.Err != nil { - panic(result.Err) - } - -Example to Add license to a server - - serverID := "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - - addLicenseOpts := servers.AddLicenseOpts{ - VmName: "Alice", - LicenseTypes: []string{ - "Windows Server", - "SQL Server Standard 2014", - }, - } - - result := servers.AddLicense(dhClient, serverID, addLicenseOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Get result for add license to a server - - serverID := "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - - getAddLicenseResultOpts := servers.GetAddLicenseResultOpts{ - JobID: AddLicenseJob.JobID, - } - - result := servers.GetAddLicenseResult(dhClient, serverID, getAddLicenseResultOpts) - if result.Err != nil { - panic(result.Err) - } - - job, err := result.Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", job) -*/ -package servers diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/requests.go b/v3/ecl/dedicated_hypervisor/v1/servers/requests.go deleted file mode 100644 index 7085741..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/requests.go +++ /dev/null @@ -1,160 +0,0 @@ -package servers - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToResourceListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - ChangesSince string `q:"changes-since"` - Marker string `q:"marker"` - Limit int `q:"limit"` - Name string `q:"name"` - Image string `q:"image"` - Flavor string `q:"flavor"` - Status string `q:"status"` -} - -// ToResourceListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToResourceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List retrieves a list of Servers. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToResourceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// ListDetails retrieves a list of Servers in details. -func ListDetails(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listDetailsURL(client) - if opts != nil { - query, err := opts.ToResourceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details of a Server. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToResourceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a Server. -type CreateOpts struct { - Name string `json:"name"` - Description string `json:"description,omitempty"` - Networks []Network `json:"networks"` - AdminPass string `json:"adminPass,omitempty"` - ImageRef string `json:"imageRef"` - FlavorRef string `json:"flavorRef"` - AvailabilityZone string `json:"availability_zone,omitempty"` - Metadata map[string]string `json:"metadata,omitempty"` -} - -type Network struct { - UUID string `json:"uuid"` - Port string `json:"port,omitempty"` - FixedIP string `json:"fixed_ip,omitempty"` - Plane string `json:"plane"` - SegmentationID int `json:"segmentation_id"` -} - -// ToResourceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToResourceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "server") -} - -// Create creates a new Server. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToResourceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a Server. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -type AddLicenseOpts struct { - VmName string `json:"vm_name,omitempty"` - VmID string `json:"vm_id,omitempty"` - LicenseTypes []string `json:"license_types"` -} - -func (opts AddLicenseOpts) ToResourceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "add-license-to-vm") -} - -func AddLicense(client *eclcloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r AddLicenseResult) { - b, err := opts.ToResourceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(actionURL(client, serverID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -type GetAddLicenseResultOpts struct { - JobID string `json:"job_id"` -} - -func (opts GetAddLicenseResultOpts) ToResourceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "get-result-for-add-license-to-vm") -} - -func GetAddLicenseResult(client *eclcloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r AddLicenseResult) { - b, err := opts.ToResourceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(actionURL(client, serverID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/results.go b/v3/ecl/dedicated_hypervisor/v1/servers/results.go deleted file mode 100644 index 5d71676..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/results.go +++ /dev/null @@ -1,203 +0,0 @@ -package servers - -import ( - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Server represents dedicated hypervisor server information. -type Server struct { - ID string `json:"id"` - Name string `json:"name"` - ImageRef string `json:"imageRef"` - Description *string `json:"description"` - Status string `json:"status"` - HypervisorType string `json:"hypervisor_type"` - BaremetalServer BaremetalServer `json:"baremetal_server"` - Links []Link `json:"links"` - AdminPass string `json:"adminPass"` -} - -type BaremetalServer struct { - PowerState string `json:"OS-EXT-STS:power_state"` - TaskState string `json:"OS-EXT-STS:task_state"` - VMState string `json:"OS-EXT-STS:vm_state"` - AvailabilityZone string `json:"OS-EXT-AZ:availability_zone"` - Created time.Time `json:"created"` - Flavor Flavor `json:"flavor"` - ID string `json:"id"` - Image Image `json:"image"` - Metadata map[string]string `json:"metadata"` - Name string `json:"name"` - Progress int `json:"progress"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` - Updated time.Time `json:"updated"` - UserID string `json:"user_id"` - NicPhysicalPorts []NicPhysicalPort `json:"nic_physical_ports"` - ChassisStatus ChassisStatus `json:"chassis-status"` - Links []Link `json:"links"` - RaidArrays []RaidArray `json:"raid_arrays"` - LvmVolumeGroups []LvmVolumeGroup `json:"lvm_volume_groups"` - Filesystems []Filesystem `json:"filesystems"` - MediaAttachments []MediaAttachment `json:"media_attachments"` - ManagedByService string `json:"managed_by_service"` - ManagedServiceResourceID string `json:"managed_service_resource_id"` -} - -type Flavor struct { - ID string `json:"id"` - Links []Link `json:"links"` -} - -type Image struct { - ID string `json:"id"` - Links []Link `json:"links"` -} - -type Link struct { - Href string `json:"href"` - Rel string `json:"rel"` -} - -type NicPhysicalPort struct { - ID string `json:"id"` - MACAddr string `json:"mac_addr"` - NetworkPhysicalPortID string `json:"network_physical_port_id"` - Plane string `json:"plane"` - AttachedPorts []Port `json:"attached_ports"` - HardwareID string `json:"hardware_id"` -} - -type Port struct { - PortID string `json:"port_id"` - NetworkID string `json:"network_id"` - FixedIPs []FixedIP `json:"fixed_ips"` -} - -type FixedIP struct { - SubnetID string `json:"subnet_id"` - IPAddress string `json:"ip_address"` -} - -type ChassisStatus struct { - ChassisPower bool `json:"chassis-power"` - PowerSupply bool `json:"power-supply"` - CPU bool `json:"cpu"` - Memory bool `json:"memory"` - Fan bool `json:"fan"` - Disk int `json:"disk"` - Nic bool `json:"nic"` - SystemBoard bool `json:"system-board"` - Etc bool `json:"etc"` - Console bool `json:"console"` -} - -type RaidArray struct { - PrimaryStorage bool `json:"primary_storage"` - Partitions []Partition `json:"partitions"` - RaidCardHardwareID string `json:"raid_card_hardware_id"` - DiskHardwareIDs []string `json:"disk_hardware_ids"` -} - -type Partition struct { - Lvm bool `json:"lvm"` - Size string `json:"size"` - PartitionLabel string `json:"partition_label"` -} - -type LvmVolumeGroup struct { - VgLabel string `json:"vg_label"` - PhysicalVolumePartitionLabels []string `json:"physical_volume_partition_labels"` - LogicalVolumes []LogicalVolume `json:"logical_volumes"` -} - -type LogicalVolume struct { - LvLabel string `json:"lv_label"` - Size string `json:"size"` -} - -type Filesystem struct { - Label string `json:"label"` - MountPoint string `json:"mount_point"` - FsType string `json:"fs_type"` -} - -type MediaAttachment struct { - Image Image `json:"image"` -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a Server. -type GetResult struct { - commonResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a Server. -type CreateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// ServerPage is a single page of Server results. -type ServerPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Servers contains any results. -func (r ServerPage) IsEmpty() (bool, error) { - servers, err := ExtractServers(r) - return len(servers) == 0, err -} - -// ExtractServers returns a slice of Servers contained in a single page of -// results. -func ExtractServers(r pagination.Page) ([]Server, error) { - var s struct { - Servers []Server `json:"servers"` - } - err := (r.(ServerPage)).ExtractInto(&s) - return s.Servers, err -} - -// Extract interprets any commonResult as a Server. -func (r commonResult) Extract() (*Server, error) { - var s struct { - Server *Server `json:"server"` - } - err := r.ExtractInto(&s) - return s.Server, err -} - -type Job struct { - JobID string `json:"job_id"` - Status string `json:"status"` - RequestedParam RequestedParam `json:"requested_param"` -} - -type RequestedParam struct { - VmName string `json:"vm_name"` - LicenseTypes []string `json:"license_types"` -} - -type AddLicenseResult struct { - eclcloud.Result -} - -func (r AddLicenseResult) Extract() (*Job, error) { - var job Job - err := r.ExtractInto(&job) - return &job, err -} diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/testing/fixtures.go b/v3/ecl/dedicated_hypervisor/v1/servers/testing/fixtures.go deleted file mode 100644 index 0e97c46..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/testing/fixtures.go +++ /dev/null @@ -1,1119 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/servers" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// ListResult provides a single page of Server results. -const ListResult = ` -{ - "servers": [ - { - "id": "194573e4-8f53-4ee4-806f-d9b2db74a380", - "name": "GP2v1", - "links": [ - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//v2/1bc271e7a8af4d988ff91612f5b122f8/servers/194573e4-8f53-4ee4-806f-d9b2db74a380", - "rel": "self" - }, - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//1bc271e7a8af4d988ff91612f5b122f8/servers/194573e4-8f53-4ee4-806f-d9b2db74a380", - "rel": "bookmark" - } - ], - "baremetal_server": { - "id": "621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "rel": "self" - }, - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "rel": "bookmark" - } - ], - "name": "GP2v1" - } - }, - { - "id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "name": "test", - "links": [ - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//v2/1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "rel": "self" - }, - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "rel": "bookmark" - } - ], - "baremetal_server": { - "id": "24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "self" - }, - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "bookmark" - } - ], - "name": "test" - } - } - ] -} -` - -// ListDetailsResult provides a single page of Server results in details. -const ListDetailsResult = ` -{ - "servers": [ - { - "id": "194573e4-8f53-4ee4-806f-d9b2db74a380", - "name": "GP2v1", - "imageRef": "293063f6-8986-4b79-becd-7a6d28794bb8", - "description": null, - "status": "ACTIVE", - "hypervisor_type": "vsphere_esxi", - "baremetal_server": { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "groupb", - "progress": 100, - "created": "2019-10-18T07:42:35Z", - "flavor": { - "id": "303b4993-cf29-4301-abd0-99512b5413a5", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/303b4993-cf29-4301-abd0-99512b5413a5", - "rel": "bookmark" - } - ] - }, - "id": "621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "image": { - "id": "02441adc-0d9a-4e9d-b359-ce23413e7ea7", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/02441adc-0d9a-4e9d-b359-ce23413e7ea7", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "rel": "self" - }, - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "GP2v1", - "status": "ACTIVE", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "updated": "2019-10-18T07:44:18Z", - "user_id": "55891ce6a3cb4bb0833514667d67288c", - "raid_arrays": [ - { - "primary_storage": true, - "partitions": null, - "raid_card_hardware_id": "24184dcf-dc76-4ea2-a34e-bccc6c11d5be", - "disk_hardware_ids": [ - "4de7d3df-8e2f-4193-98dc-145f78df29a2", - "de158fab-7bc2-49e3-98d1-9db5451d43e3", - "97087307-cab2-40cb-a84c-86d98da0f393" - ] - } - ], - "lvm_volume_groups": null, - "filesystems": null, - "nic_physical_ports": [ - { - "id": "b49c0624-e89a-469f-8c90-7a27ee1f61cb", - "mac_addr": "8C:DC:D4:B7:41:48", - "plane": "DATA", - "network_physical_port_id": "4cfbe3b2-a502-485f-82fa-a0949396e567", - "hardware_id": "8e1e2fe0-60a7-4211-a891-80e808426708", - "attached_ports": [ - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "8808acc2-d930-40fb-b382-ce7074baef83", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.11" - } - ] - }, - { - "network_id": "722f9e4f-39f8-406a-b98c-5fbd5689b89a", - "port_id": "9d3baa16-e0e5-4e50-9677-08dd338e0c14", - "fixed_ips": [ - { - "subnet_id": "dc84c9dc-0b4d-40fc-8605-e518af7cdd30", - "ip_address": "192.168.4.3" - } - ] - } - ] - }, - { - "id": "8bea93c4-721b-480c-8713-f2a4b6e5dbad", - "mac_addr": "8C:DC:D4:B7:41:49", - "plane": "STORAGE", - "network_physical_port_id": "ab38075d-128f-4f3d-a16a-c6426375a380", - "hardware_id": "8e1e2fe0-60a7-4211-a891-80e808426708", - "attached_ports": [] - }, - { - "id": "a7fbca5e-ff49-4ddb-8659-02ec462f98ec", - "mac_addr": "8C:DC:D4:B7:45:89", - "plane": "STORAGE", - "network_physical_port_id": "9ef62803-7848-460c-9dae-17fd02606a26", - "hardware_id": "1aa1c2a4-2608-41e6-b4f5-87679d1aea43", - "attached_ports": [] - }, - { - "id": "71af4de1-0c9b-4870-8c95-c7b9b4115bb8", - "mac_addr": "8C:DC:D4:B7:45:88", - "plane": "DATA", - "network_physical_port_id": "ad92f33a-eac4-408d-bc27-22d91eccd465", - "hardware_id": "1aa1c2a4-2608-41e6-b4f5-87679d1aea43", - "attached_ports": [ - { - "network_id": "722f9e4f-39f8-406a-b98c-5fbd5689b89a", - "port_id": "705bde94-7189-40b1-b8a2-188e6cc3c546", - "fixed_ips": [ - { - "subnet_id": "dc84c9dc-0b4d-40fc-8605-e518af7cdd30", - "ip_address": "192.168.4.4" - } - ] - }, - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "7b860eb4-0eb6-4c2a-873e-ccefd6029d97", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.12" - } - ] - } - ] - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true, - "console": true - }, - "media_attachments": [], - "managed_by_service": "dedicated-hypervisor", - "managed_service_resource_id": "194573e4-8f53-4ee4-806f-d9b2db74a380" - } - }, - { - "id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "name": "test", - "imageRef": "dfd25820-b368-4012-997b-29a6d0cf8518", - "description": "test", - "status": "ACTIVE", - "hypervisor_type": "vsphere_esxi", - "baremetal_server": { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "groupb", - "progress": 100, - "created": "2019-10-10T04:11:41Z", - "flavor": { - "id": "a830b61c-3155-4a61-b7ed-c450862845e6", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/a830b61c-3155-4a61-b7ed-c450862845e6", - "rel": "bookmark" - } - ] - }, - "id": "24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "image": { - "id": "112a26a0-ff25-4513-afe1-407e41b0a48b", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/112a26a0-ff25-4513-afe1-407e41b0a48b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "self" - }, - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "test", - "status": "ACTIVE", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "updated": "2019-10-10T04:14:08Z", - "user_id": "55891ce6a3cb4bb0833514667d67288c", - "raid_arrays": [ - { - "primary_storage": true, - "partitions": null, - "raid_card_hardware_id": "bdfb75d1-194d-426d-b288-f588dfa5ac49", - "disk_hardware_ids": [ - "76649053-863e-4533-86e3-f194a79485a6", - "a25827e3-67da-47be-ba96-849ab4685a1d" - ] - } - ], - "lvm_volume_groups": null, - "filesystems": null, - "nic_physical_ports": [ - { - "id": "a2f63380-6c77-4cd5-8868-e3556ffd35ce", - "mac_addr": "48:DF:37:90:B4:58", - "plane": "DATA", - "network_physical_port_id": "d8e40a51-f1e2-4681-8953-9fe1e9992c42", - "hardware_id": "be2d30d6-f891-4200-b827-95f229fb8c6b", - "attached_ports": [ - { - "network_id": "94055904-6b2c-4839-a14a-c61c93a8bc48", - "port_id": "30fc1c27-fb5f-4955-94d0-a56cd28d09e8", - "fixed_ips": [ - { - "subnet_id": "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - "ip_address": "2.1.1.10" - } - ] - }, - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "aa6c61f4-db8a-44c7-a91c-7e636dac1dc6", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.9" - } - ] - } - ] - }, - { - "id": "b01dfdb0-f247-47d8-8224-c257aa3265e9", - "mac_addr": "48:DF:37:90:B4:50", - "plane": "STORAGE", - "network_physical_port_id": "00dfea92-5c5b-4860-aa05-efef6c2bb2af", - "hardware_id": "be2d30d6-f891-4200-b827-95f229fb8c6b", - "attached_ports": [] - }, - { - "id": "f4355e8e-39fc-48bd-a283-a2dbef8a2e32", - "mac_addr": "48:DF:37:82:B0:A0", - "plane": "STORAGE", - "network_physical_port_id": "cf798cc0-c869-45d5-a5a7-bcc578a300b0", - "hardware_id": "84c74a86-7045-4284-80f9-0e7aff5d27ad", - "attached_ports": [] - }, - { - "id": "5ef177fd-888c-4fae-9925-a8920beb07cb", - "mac_addr": "48:DF:37:82:B0:A8", - "plane": "DATA", - "network_physical_port_id": "2bbbb516-c75a-42b2-8a46-9cb5f26c219e", - "hardware_id": "84c74a86-7045-4284-80f9-0e7aff5d27ad", - "attached_ports": [ - { - "network_id": "94055904-6b2c-4839-a14a-c61c93a8bc48", - "port_id": "4e329a01-2cf4-4028-9259-03b7aa145cb6", - "fixed_ips": [ - { - "subnet_id": "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - "ip_address": "2.1.1.20" - } - ] - }, - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "a256b4a1-3ae3-4102-a14e-987ae1610f97", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.10" - } - ] - } - ] - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true, - "console": true - }, - "media_attachments": [], - "managed_by_service": "dedicated-hypervisor", - "managed_service_resource_id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - } - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "server": { - "id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "name": "test", - "imageRef": "dfd25820-b368-4012-997b-29a6d0cf8518", - "description": "test", - "status": "ACTIVE", - "hypervisor_type": "vsphere_esxi", - "baremetal_server": { - "OS-EXT-STS:power_state": "RUNNING", - "OS-EXT-STS:task_state": "None", - "OS-EXT-STS:vm_state": "ACTIVE", - "OS-EXT-AZ:availability_zone": "groupb", - "progress": 100, - "created": "2019-10-10T04:11:41Z", - "flavor": { - "id": "a830b61c-3155-4a61-b7ed-c450862845e6", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/a830b61c-3155-4a61-b7ed-c450862845e6", - "rel": "bookmark" - } - ] - }, - "id": "24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "image": { - "id": "112a26a0-ff25-4513-afe1-407e41b0a48b", - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/112a26a0-ff25-4513-afe1-407e41b0a48b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "self" - }, - { - "href": "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - "rel": "bookmark" - } - ], - "metadata": {}, - "name": "test", - "status": "ACTIVE", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "updated": "2019-10-10T04:14:08Z", - "user_id": "55891ce6a3cb4bb0833514667d67288c", - "raid_arrays": [ - { - "primary_storage": true, - "partitions": null, - "raid_card_hardware_id": "bdfb75d1-194d-426d-b288-f588dfa5ac49", - "disk_hardware_ids": [ - "76649053-863e-4533-86e3-f194a79485a6", - "a25827e3-67da-47be-ba96-849ab4685a1d" - ] - } - ], - "lvm_volume_groups": null, - "filesystems": null, - "nic_physical_ports": [ - { - "id": "a2f63380-6c77-4cd5-8868-e3556ffd35ce", - "mac_addr": "48:DF:37:90:B4:58", - "plane": "DATA", - "network_physical_port_id": "d8e40a51-f1e2-4681-8953-9fe1e9992c42", - "hardware_id": "be2d30d6-f891-4200-b827-95f229fb8c6b", - "attached_ports": [ - { - "network_id": "94055904-6b2c-4839-a14a-c61c93a8bc48", - "port_id": "30fc1c27-fb5f-4955-94d0-a56cd28d09e8", - "fixed_ips": [ - { - "subnet_id": "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - "ip_address": "2.1.1.10" - } - ] - }, - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "aa6c61f4-db8a-44c7-a91c-7e636dac1dc6", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.9" - } - ] - } - ] - }, - { - "id": "b01dfdb0-f247-47d8-8224-c257aa3265e9", - "mac_addr": "48:DF:37:90:B4:50", - "plane": "STORAGE", - "network_physical_port_id": "00dfea92-5c5b-4860-aa05-efef6c2bb2af", - "hardware_id": "be2d30d6-f891-4200-b827-95f229fb8c6b", - "attached_ports": [] - }, - { - "id": "f4355e8e-39fc-48bd-a283-a2dbef8a2e32", - "mac_addr": "48:DF:37:82:B0:A0", - "plane": "STORAGE", - "network_physical_port_id": "cf798cc0-c869-45d5-a5a7-bcc578a300b0", - "hardware_id": "84c74a86-7045-4284-80f9-0e7aff5d27ad", - "attached_ports": [] - }, - { - "id": "5ef177fd-888c-4fae-9925-a8920beb07cb", - "mac_addr": "48:DF:37:82:B0:A8", - "plane": "DATA", - "network_physical_port_id": "2bbbb516-c75a-42b2-8a46-9cb5f26c219e", - "hardware_id": "84c74a86-7045-4284-80f9-0e7aff5d27ad", - "attached_ports": [ - { - "network_id": "94055904-6b2c-4839-a14a-c61c93a8bc48", - "port_id": "4e329a01-2cf4-4028-9259-03b7aa145cb6", - "fixed_ips": [ - { - "subnet_id": "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - "ip_address": "2.1.1.20" - } - ] - }, - { - "network_id": "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - "port_id": "a256b4a1-3ae3-4102-a14e-987ae1610f97", - "fixed_ips": [ - { - "subnet_id": "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - "ip_address": "169.254.0.10" - } - ] - } - ] - } - ], - "chassis-status": { - "chassis-power": true, - "power-supply": true, - "cpu": true, - "memory": true, - "fan": true, - "disk": 0, - "nic": true, - "system-board": true, - "etc": true, - "console": true - }, - "media_attachments": [], - "managed_by_service": "dedicated-hypervisor", - "managed_service_resource_id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5" - } - } -} -` - -// CreateRequest provides the input to a Create request. -const CreateRequest = ` -{ - "server": { - "imageRef": "dfd25820-b368-4012-997b-29a6d0cf8518", - "name": "test", - "networks": [ - { - "segmentation_id": 6, - "plane": "data", - "uuid": "94055904-6b2c-4839-a14a-c61c93a8bc48" - }, - { - "segmentation_id": 6, - "plane": "data", - "uuid": "94055904-6b2c-4839-a14a-c61c93a8bc48" - } - ], - "flavorRef": "a830b61c-3155-4a61-b7ed-c450862845e6" - } -} -` - -const CreateResponse = ` -{ - "server": { - "id": "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "links": [ - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//v2/1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "rel": "self" - }, - { - "href": "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - "rel": "bookmark" - } - ], - "adminPass": "aabbccddeeff" - } -} -` - -const AddLicenseRequest = ` -{ - "add-license-to-vm": { - "vm_name": "Alice", - "license_types": [ - "Windows Server", - "SQL Server Standard 2014" - ] - } -} -` - -const AddLicenseResponse = ` -{ - "job_id": "b4f888dc2b9d4c41bb769cbd" -} -` - -const GetAddLicenseResultRequest = ` -{ - "get-result-for-add-license-to-vm": { - "job_id": "b4f888dc2b9d4c41bb769cbd" - } -} -` - -const GetAddLicenseResultResponse = ` -{ - "job_id": "b4f888dc2b9d4c41bb769cbd", - "status": "COMPLETED", - "requested_param": { - "vm_name": "Alice", - "license_types": ["Windows Server", "SQL Server Standard 2014"] - } -} -` - -// FirstServer is the first resource in the List request. -var FirstServer = servers.Server{ - ID: "194573e4-8f53-4ee4-806f-d9b2db74a380", - Name: "GP2v1", - Links: []servers.Link{ - { - Href: "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//v2/1bc271e7a8af4d988ff91612f5b122f8/servers/194573e4-8f53-4ee4-806f-d9b2db74a380", - Rel: "self", - }, - { - Href: "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//1bc271e7a8af4d988ff91612f5b122f8/servers/194573e4-8f53-4ee4-806f-d9b2db74a380", - Rel: "bookmark", - }, - }, - BaremetalServer: servers.BaremetalServer{ - ID: "621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Name: "GP2v1", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Rel: "self", - }, - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Rel: "bookmark", - }, - }, - }, -} - -// SecondServer is the second resource in the List request. -var SecondServer = servers.Server{ - ID: "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - Name: "test", - Links: []servers.Link{ - { - Href: "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//v2/1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - Rel: "self", - }, - { - Href: "https://dedicated-hypervisor-jp1-ecl.api.ntt.com/v1.0//1bc271e7a8af4d988ff91612f5b122f8/servers/f42dbc37-4642-4628-8b47-50bf95d8fdd5", - Rel: "bookmark", - }, - }, - BaremetalServer: servers.BaremetalServer{ - ID: "24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Name: "test", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Rel: "self", - }, - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Rel: "bookmark", - }, - }, - }, -} - -// ExpectedServersSlice is the slice of resources expected to be returned from ListResult. -var ExpectedServersSlice = []servers.Server{FirstServer, SecondServer} - -// FirstServerDetail is the first resource in the List details request. -var FirstServerDetail = servers.Server{ - ID: "194573e4-8f53-4ee4-806f-d9b2db74a380", - Name: "GP2v1", - ImageRef: "293063f6-8986-4b79-becd-7a6d28794bb8", - Description: nil, - Status: "ACTIVE", - HypervisorType: "vsphere_esxi", - BaremetalServer: servers.BaremetalServer{ - PowerState: "RUNNING", - TaskState: "None", - VMState: "ACTIVE", - AvailabilityZone: "groupb", - Created: time.Date(2019, 10, 18, 7, 42, 35, 0, time.UTC), - Flavor: servers.Flavor{ - ID: "303b4993-cf29-4301-abd0-99512b5413a5", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/303b4993-cf29-4301-abd0-99512b5413a5", - Rel: "bookmark", - }, - }, - }, - ID: "621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Image: servers.Image{ - ID: "02441adc-0d9a-4e9d-b359-ce23413e7ea7", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/02441adc-0d9a-4e9d-b359-ce23413e7ea7", - Rel: "bookmark", - }, - }, - }, - Metadata: map[string]string{}, - Name: "GP2v1", - Progress: 100, - Status: "ACTIVE", - TenantID: "1bc271e7a8af4d988ff91612f5b122f8", - Updated: time.Date(2019, 10, 18, 7, 44, 18, 0, time.UTC), - UserID: "55891ce6a3cb4bb0833514667d67288c", - NicPhysicalPorts: []servers.NicPhysicalPort{ - { - ID: "b49c0624-e89a-469f-8c90-7a27ee1f61cb", - MACAddr: "8C:DC:D4:B7:41:48", - Plane: "DATA", - NetworkPhysicalPortID: "4cfbe3b2-a502-485f-82fa-a0949396e567", - HardwareID: "8e1e2fe0-60a7-4211-a891-80e808426708", - AttachedPorts: []servers.Port{ - { - NetworkID: "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - PortID: "8808acc2-d930-40fb-b382-ce7074baef83", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - IPAddress: "169.254.0.11", - }, - }, - }, - { - NetworkID: "722f9e4f-39f8-406a-b98c-5fbd5689b89a", - PortID: "9d3baa16-e0e5-4e50-9677-08dd338e0c14", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "dc84c9dc-0b4d-40fc-8605-e518af7cdd30", - IPAddress: "192.168.4.3", - }, - }, - }, - }, - }, - { - ID: "8bea93c4-721b-480c-8713-f2a4b6e5dbad", - MACAddr: "8C:DC:D4:B7:41:49", - Plane: "STORAGE", - NetworkPhysicalPortID: "ab38075d-128f-4f3d-a16a-c6426375a380", - HardwareID: "8e1e2fe0-60a7-4211-a891-80e808426708", - AttachedPorts: []servers.Port{}, - }, - { - ID: "a7fbca5e-ff49-4ddb-8659-02ec462f98ec", - MACAddr: "8C:DC:D4:B7:45:89", - Plane: "STORAGE", - NetworkPhysicalPortID: "9ef62803-7848-460c-9dae-17fd02606a26", - HardwareID: "1aa1c2a4-2608-41e6-b4f5-87679d1aea43", - AttachedPorts: []servers.Port{}, - }, - { - ID: "71af4de1-0c9b-4870-8c95-c7b9b4115bb8", - MACAddr: "8C:DC:D4:B7:45:88", - Plane: "DATA", - NetworkPhysicalPortID: "ad92f33a-eac4-408d-bc27-22d91eccd465", - HardwareID: "1aa1c2a4-2608-41e6-b4f5-87679d1aea43", - AttachedPorts: []servers.Port{ - { - NetworkID: "722f9e4f-39f8-406a-b98c-5fbd5689b89a", - PortID: "705bde94-7189-40b1-b8a2-188e6cc3c546", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "dc84c9dc-0b4d-40fc-8605-e518af7cdd30", - IPAddress: "192.168.4.4", - }, - }, - }, - { - NetworkID: "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - PortID: "7b860eb4-0eb6-4c2a-873e-ccefd6029d97", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - IPAddress: "169.254.0.12", - }, - }, - }, - }, - }, - }, - ChassisStatus: servers.ChassisStatus{ - ChassisPower: true, - PowerSupply: true, - CPU: true, - Memory: true, - Fan: true, - Disk: 0, - Nic: true, - SystemBoard: true, - Etc: true, - Console: true, - }, - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Rel: "self", - }, - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/621b56e4-4aae-4de5-86a0-8ffeeda6a00b", - Rel: "bookmark", - }, - }, - RaidArrays: []servers.RaidArray{ - { - PrimaryStorage: true, - Partitions: nil, - RaidCardHardwareID: "24184dcf-dc76-4ea2-a34e-bccc6c11d5be", - DiskHardwareIDs: []string{ - "4de7d3df-8e2f-4193-98dc-145f78df29a2", - "de158fab-7bc2-49e3-98d1-9db5451d43e3", - "97087307-cab2-40cb-a84c-86d98da0f393", - }, - }, - }, - LvmVolumeGroups: nil, - Filesystems: nil, - MediaAttachments: []servers.MediaAttachment{}, - ManagedByService: "dedicated-hypervisor", - ManagedServiceResourceID: "194573e4-8f53-4ee4-806f-d9b2db74a380", - }, -} - -var SecondServerDescription = "test" - -// SecondServerDetail is the second resource in the List detail request. -var SecondServerDetail = servers.Server{ - ID: "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - Name: "test", - ImageRef: "dfd25820-b368-4012-997b-29a6d0cf8518", - Description: &SecondServerDescription, - Status: "ACTIVE", - HypervisorType: "vsphere_esxi", - BaremetalServer: servers.BaremetalServer{ - PowerState: "RUNNING", - TaskState: "None", - VMState: "ACTIVE", - AvailabilityZone: "groupb", - Created: time.Date(2019, 10, 10, 4, 11, 41, 0, time.UTC), - Flavor: servers.Flavor{ - ID: "a830b61c-3155-4a61-b7ed-c450862845e6", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/flavors/a830b61c-3155-4a61-b7ed-c450862845e6", - Rel: "bookmark", - }, - }, - }, - ID: "24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Image: servers.Image{ - ID: "112a26a0-ff25-4513-afe1-407e41b0a48b", - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/images/112a26a0-ff25-4513-afe1-407e41b0a48b", - Rel: "bookmark", - }, - }, - }, - Metadata: map[string]string{}, - Name: "test", - Progress: 100, - Status: "ACTIVE", - TenantID: "1bc271e7a8af4d988ff91612f5b122f8", - Updated: time.Date(2019, 10, 10, 4, 14, 8, 0, time.UTC), - UserID: "55891ce6a3cb4bb0833514667d67288c", - NicPhysicalPorts: []servers.NicPhysicalPort{ - { - ID: "a2f63380-6c77-4cd5-8868-e3556ffd35ce", - MACAddr: "48:DF:37:90:B4:58", - Plane: "DATA", - NetworkPhysicalPortID: "d8e40a51-f1e2-4681-8953-9fe1e9992c42", - HardwareID: "be2d30d6-f891-4200-b827-95f229fb8c6b", - AttachedPorts: []servers.Port{ - { - NetworkID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - PortID: "30fc1c27-fb5f-4955-94d0-a56cd28d09e8", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - IPAddress: "2.1.1.10", - }, - }, - }, - { - NetworkID: "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - PortID: "aa6c61f4-db8a-44c7-a91c-7e636dac1dc6", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - IPAddress: "169.254.0.9", - }, - }, - }, - }, - }, - { - ID: "b01dfdb0-f247-47d8-8224-c257aa3265e9", - MACAddr: "48:DF:37:90:B4:50", - Plane: "STORAGE", - NetworkPhysicalPortID: "00dfea92-5c5b-4860-aa05-efef6c2bb2af", - HardwareID: "be2d30d6-f891-4200-b827-95f229fb8c6b", - AttachedPorts: []servers.Port{}, - }, - { - ID: "f4355e8e-39fc-48bd-a283-a2dbef8a2e32", - MACAddr: "48:DF:37:82:B0:A0", - Plane: "STORAGE", - NetworkPhysicalPortID: "cf798cc0-c869-45d5-a5a7-bcc578a300b0", - HardwareID: "84c74a86-7045-4284-80f9-0e7aff5d27ad", - AttachedPorts: []servers.Port{}, - }, - { - ID: "5ef177fd-888c-4fae-9925-a8920beb07cb", - MACAddr: "48:DF:37:82:B0:A8", - Plane: "DATA", - NetworkPhysicalPortID: "2bbbb516-c75a-42b2-8a46-9cb5f26c219e", - HardwareID: "84c74a86-7045-4284-80f9-0e7aff5d27ad", - AttachedPorts: []servers.Port{ - { - NetworkID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - PortID: "4e329a01-2cf4-4028-9259-03b7aa145cb6", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "acd41997-5ebb-4ff2-8cd2-22cae6cf2883", - IPAddress: "2.1.1.20", - }, - }, - }, - { - NetworkID: "4a59f728-3920-4b71-ae54-d0d5c14ba04b", - PortID: "a256b4a1-3ae3-4102-a14e-987ae1610f97", - FixedIPs: []servers.FixedIP{ - { - SubnetID: "b87d9c85-af5c-403d-a49a-55a6ab0a36d2", - IPAddress: "169.254.0.10", - }, - }, - }, - }, - }, - }, - ChassisStatus: servers.ChassisStatus{ - ChassisPower: true, - PowerSupply: true, - CPU: true, - Memory: true, - Fan: true, - Disk: 0, - Nic: true, - SystemBoard: true, - Etc: true, - Console: true, - }, - Links: []servers.Link{ - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/v2/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Rel: "self", - }, - { - Href: "https://baremetal-server-jp1-ecl.api.ntt.com/1bc271e7a8af4d988ff91612f5b122f8/servers/24ebe7b8-ecfb-4d9f-a66b-c0120534fc90", - Rel: "bookmark", - }, - }, - RaidArrays: []servers.RaidArray{ - { - PrimaryStorage: true, - Partitions: nil, - RaidCardHardwareID: "bdfb75d1-194d-426d-b288-f588dfa5ac49", - DiskHardwareIDs: []string{ - "76649053-863e-4533-86e3-f194a79485a6", - "a25827e3-67da-47be-ba96-849ab4685a1d", - }, - }, - }, - LvmVolumeGroups: nil, - Filesystems: nil, - MediaAttachments: []servers.MediaAttachment{}, - ManagedByService: "dedicated-hypervisor", - ManagedServiceResourceID: "f42dbc37-4642-4628-8b47-50bf95d8fdd5", - }, -} - -// ExpectedServersDetailsSlice is the slice of resources expected to be returned from ListDetailsResult. -var ExpectedServersDetailsSlice = []servers.Server{FirstServerDetail, SecondServerDetail} - -var AddLicenseJob = servers.Job{ - JobID: "b4f888dc2b9d4c41bb769cbd", - Status: "COMPLETED", - RequestedParam: servers.RequestedParam{ - VmName: "Alice", - LicenseTypes: []string{ - "Windows Server", - "SQL Server Standard 2014", - }, - }, -} - -// HandleListServersSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a list of two servers. -func HandleListServersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} - -// HandleListServersDetailsSuccessfully creates an HTTP handler at `/servers/detail` on the -// test handler mux that responds with a list of two servers. -func HandleListServersDetailsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListDetailsResult) - }) -} - -// HandleGetServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that responds with a single server. -func HandleGetServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s", SecondServer.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResult) - }) -} - -// HandleCreateServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server creation. -func HandleCreateServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CreateResponse) - }) -} - -// HandleDeleteServerSuccessfully creates an HTTP handler at `/servers` on the -// test handler mux that tests server deletion. -func HandleDeleteServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s", FirstServer.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -func HandleAddLicenseSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/action", SecondServer.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, AddLicenseRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, AddLicenseResponse) - }) -} - -func HandleGetAddLicenseResultSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/servers/%s/action", SecondServer.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, GetAddLicenseResultRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetAddLicenseResultResponse) - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/testing/requests_test.go b/v3/ecl/dedicated_hypervisor/v1/servers/testing/requests_test.go deleted file mode 100644 index 5fa8ce8..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/testing/requests_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/servers" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListServers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersSuccessfully(t) - - count := 0 - err := servers.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedServersSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListServersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersSuccessfully(t) - - allPages, err := servers.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := servers.ExtractServers(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedServersSlice, actual) -} - -func TestListServersDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersDetailsSuccessfully(t) - - count := 0 - err := servers.ListDetails(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := servers.ExtractServers(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedServersDetailsSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListServersDetailsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListServersDetailsSuccessfully(t) - - allPages, err := servers.ListDetails(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := servers.ExtractServers(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedServersDetailsSlice, actual) -} - -func TestGetServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetServerSuccessfully(t) - - actual, err := servers.Get(client.ServiceClient(), SecondServer.ID).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondServerDetail, *actual) -} - -func TestCreateServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateServerSuccessfully(t) - - createOpts := servers.CreateOpts{ - Name: "test", - Networks: []servers.Network{ - { - UUID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - Plane: "data", - SegmentationID: 6, - }, - { - UUID: "94055904-6b2c-4839-a14a-c61c93a8bc48", - Plane: "data", - SegmentationID: 6, - }, - }, - ImageRef: "dfd25820-b368-4012-997b-29a6d0cf8518", - FlavorRef: "a830b61c-3155-4a61-b7ed-c450862845e6", - } - - actual, err := servers.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, SecondServer.ID, actual.ID) - th.AssertDeepEquals(t, SecondServer.Links, actual.Links) - th.AssertEquals(t, "aabbccddeeff", actual.AdminPass) -} - -func TestDeleteResource(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteServerSuccessfully(t) - - res := servers.Delete(client.ServiceClient(), FirstServer.ID) - th.AssertNoErr(t, res.Err) -} - -func TestAddLicense(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleAddLicenseSuccessfully(t) - - addLicenseOpts := servers.AddLicenseOpts{ - VmName: "Alice", - LicenseTypes: []string{ - "Windows Server", - "SQL Server Standard 2014", - }, - } - - actual, err := servers.AddLicense(client.ServiceClient(), SecondServer.ID, addLicenseOpts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, AddLicenseJob.JobID, actual.JobID) -} - -func TestGetAddLicenseResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetAddLicenseResultSuccessfully(t) - - getAddLicenseResultOpts := servers.GetAddLicenseResultOpts{ - JobID: AddLicenseJob.JobID, - } - - actual, err := servers.GetAddLicenseResult(client.ServiceClient(), SecondServer.ID, getAddLicenseResultOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, AddLicenseJob, *actual) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/servers/urls.go b/v3/ecl/dedicated_hypervisor/v1/servers/urls.go deleted file mode 100644 index 324aec0..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/servers/urls.go +++ /dev/null @@ -1,27 +0,0 @@ -package servers - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers") -} - -func listDetailsURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers", "detail") -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("servers") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id) -} - -func actionURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("servers", id, "action") -} diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/doc.go b/v3/ecl/dedicated_hypervisor/v1/usages/doc.go deleted file mode 100644 index ce71466..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/doc.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Package usages manages and retrieves usage in the Enterprise Cloud Dedicated Hypervisor Service. - -Example to List Usages - - listOpts := usages.ListOpts{ - From: "2019-10-10T00:00:00Z", - To: "2019-10-15T00:00:00Z", - LicenseType: "dedicated-hypervisor.guest-image.vcenter-server-6-0-standard", - } - - allPages, err := usages.List(dhClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allUsages, err := usages.ExtractUsages(allPages) - if err != nil { - panic(err) - } - - for _, usage := range allUsages { - fmt.Printf("%+v\n", usage) - } - -Example to Get Usage Histories - - getHistoriesOpts := usages.GetHistoriesOpts{ - From: "2019-10-10T00:00:00Z", - To: "2019-10-15T00:00:00Z", - } - - usageID := "9ada4c06-a2a4-46d5-b969-72ac12433a79" - histories, err := usages.GetHistories(client, usageID, getHistoriesOpts).ExtractHistories() - if err != nil { - panic(err) - } -*/ -package usages diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/requests.go b/v3/ecl/dedicated_hypervisor/v1/usages/requests.go deleted file mode 100644 index bb46491..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/requests.go +++ /dev/null @@ -1,73 +0,0 @@ -package usages - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToResourceListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - From string `q:"from"` - To string `q:"to"` - LicenseType string `q:"license_type"` -} - -// ToResourceListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToResourceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List retrieves a list of Usages. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToResourceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return UsagePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// GetHistoriesOpts provides options to filter the GetHistories results. -type GetHistoriesOpts struct { - From string `q:"from"` - To string `q:"to"` -} - -// ToResourceListQuery formats a GetHistoriesOpts into a query string. -func (opts GetHistoriesOpts) ToResourceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// GetHistories retrieves details of usage histories. -func GetHistories(client *eclcloud.ServiceClient, usageID string, opts ListOptsBuilder) (r GetHistoriesResult) { - url := getHistoriesURL(client, usageID) - if opts != nil { - query, err := opts.ToResourceListQuery() - if err != nil { - r.Err = err - return - } - url += query - } - _, r.Err = client.Get(url, &r.Body, nil) - return -} diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/results.go b/v3/ecl/dedicated_hypervisor/v1/usages/results.go deleted file mode 100644 index f1362c0..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/results.go +++ /dev/null @@ -1,89 +0,0 @@ -package usages - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Usage represents guest image usage information. -type Usage struct { - ID string `json:"id"` - Type string `json:"type"` - Value string `json:"value"` - Unit string `json:"unit"` - Name string `json:"name"` - Description string `json:"description"` - HasLicenseKey bool `json:"has_license_key"` - ResourceID string `json:"resource_id"` -} - -type UsageHistories struct { - Unit string `json:"unit"` - ResourceID string `json:"resource_id"` - LicenseType string `json:"license_type"` - Histories []History `json:"histories"` -} - -type History struct { - Time time.Time `json:"-"` - Value string `json:"value"` -} - -func (h *History) UnmarshalJSON(b []byte) error { - type tmp History - var s struct { - tmp - Time eclcloud.JSONRFC3339ZNoTNoZ `json:"time"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *h = History(s.tmp) - - h.Time = time.Time(s.Time) - - return err -} - -type commonResult struct { - eclcloud.Result -} - -// GetHistoriesResult is the response from a Get operation. Call its Extract method -// to interpret it as usage histories. -type GetHistoriesResult struct { - commonResult -} - -// UsagePage is a single page of Usage results. -type UsagePage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Usages contains any results. -func (r UsagePage) IsEmpty() (bool, error) { - usages, err := ExtractUsages(r) - return len(usages) == 0, err -} - -// ExtractUsages returns a slice of Usages contained in a single page of -// results. -func ExtractUsages(r pagination.Page) ([]Usage, error) { - var s struct { - Usages []Usage `json:"usages"` - } - err := (r.(UsagePage)).ExtractInto(&s) - return s.Usages, err -} - -// ExtractHistories interprets any commonResult as usage histories. -func (r commonResult) ExtractHistories() (*UsageHistories, error) { - var s UsageHistories - err := r.ExtractInto(&s) - return &s, err -} diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/testing/fixtures.go b/v3/ecl/dedicated_hypervisor/v1/usages/testing/fixtures.go deleted file mode 100644 index af8b354..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/testing/fixtures.go +++ /dev/null @@ -1,140 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/usages" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// ListResult provides a single page of Usage results. -const ListResult = ` -{ - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "usages": [ - { - "description": "vCenter Server 6.x Standard", - "has_license_key": true, - "id": "9ada4c06-a2a4-46d5-b969-72ac12433a79", - "name": "vCenter Server 6.x Standard", - "resource_id": "1bc271e7a8af4d988ff91612f5b122f8", - "type": "dedicated-hypervisor.guest-image.vcenter-server-6-0-standard", - "unit": "License", - "value": "2" - }, - { - "description": "SQL Server 2014 Standard Edition", - "has_license_key": false, - "id": "9da9116d-cc44-4ad8-aca5-7db398fcb478", - "name": "SQL Server 2014 Standard Edition", - "resource_id": "d-cc44-4ad8-aca5-7db398fcb477bbbbbb", - "type": "dedicated-hypervisor.guest-image.sql-server-2014-standard", - "unit": "vCPU", - "value": "6" - } - ] -} -` - -// FirstUsage is the first Usage in the List request. -var FirstUsage = usages.Usage{ - ID: "9ada4c06-a2a4-46d5-b969-72ac12433a79", - Type: "dedicated-hypervisor.guest-image.vcenter-server-6-0-standard", - Value: "2", - Unit: "License", - Name: "vCenter Server 6.x Standard", - Description: "vCenter Server 6.x Standard", - HasLicenseKey: true, - ResourceID: "1bc271e7a8af4d988ff91612f5b122f8", -} - -// SecondUsage is the second Usage in the List request. -var SecondUsage = usages.Usage{ - ID: "9da9116d-cc44-4ad8-aca5-7db398fcb478", - Type: "dedicated-hypervisor.guest-image.sql-server-2014-standard", - Value: "6", - Unit: "vCPU", - Name: "SQL Server 2014 Standard Edition", - Description: "SQL Server 2014 Standard Edition", - HasLicenseKey: false, - ResourceID: "d-cc44-4ad8-aca5-7db398fcb477bbbbbb", -} - -// ExpectedUsagesSlice is the slice of LicenseTypes expected to be returned from ListResult. -var ExpectedUsagesSlice = []usages.Usage{FirstUsage, SecondUsage} - -// HandleListUsagesSuccessfully creates an HTTP handler at `/usages` on the -// test handler mux that responds with a list of two Usages. -func HandleListUsagesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/usages", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} - -const usageID = "9ada4c06-a2a4-46d5-b969-72ac12433a79" - -// GetHistoriesResult provides a single page of Usage results. -const GetHistoriesResult = ` -{ - "description": "vCenter Server 6.x Standard", - "histories": [ - { - "time": "2019-10-10 00:00:00", - "value": "1" - }, - { - "time": "2019-10-10 01:00:00", - "value": "1" - } - ], - "license_type": "vCenter Server 6.x Standard", - "resource_id": "1bc271e7a8af4d988ff91612f5b122f8", - "tenant_id": "1bc271e7a8af4d988ff91612f5b122f8", - "unit": "License" -} -` - -// FirstHistory is the first History in the Get histories request. -var FirstHistory = usages.History{ - Time: time.Date(2019, 10, 10, 0, 0, 0, 0, time.UTC), - Value: "1", -} - -// SecondHistory is the second History in the Get histories request. -var SecondHistory = usages.History{ - Time: time.Date(2019, 10, 10, 1, 0, 0, 0, time.UTC), - Value: "1", -} - -// ExpectedHistories is the UsageHistories expected to be returned from GetHistoriesResult. -var ExpectedHistories = &usages.UsageHistories{ - Unit: "License", - ResourceID: "1bc271e7a8af4d988ff91612f5b122f8", - LicenseType: "vCenter Server 6.x Standard", - Histories: []usages.History{FirstHistory, SecondHistory}, -} - -// HandleGetHistoriesSuccessfully creates an HTTP handler at `/usages//histories` on the -// test handler mux that responds with usage histories. -func HandleGetHistoriesSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/usages/%s/histories", usageID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetHistoriesResult) - }) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/testing/requests_test.go b/v3/ecl/dedicated_hypervisor/v1/usages/testing/requests_test.go deleted file mode 100644 index b05a940..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/testing/requests_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dedicated_hypervisor/v1/usages" - - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListUsages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsagesSuccessfully(t) - - count := 0 - err := usages.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := usages.ExtractUsages(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedUsagesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListUsagesAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsagesSuccessfully(t) - - allPages, err := usages.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := usages.ExtractUsages(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedUsagesSlice, actual) -} - -func TestGetUsageHistories(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetHistoriesSuccessfully(t) - - result := usages.GetHistories(client.ServiceClient(), usageID, nil) - th.AssertNoErr(t, result.Err) - actual, err := result.ExtractHistories() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedHistories, actual) -} diff --git a/v3/ecl/dedicated_hypervisor/v1/usages/urls.go b/v3/ecl/dedicated_hypervisor/v1/usages/urls.go deleted file mode 100644 index 30f3ac8..0000000 --- a/v3/ecl/dedicated_hypervisor/v1/usages/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package usages - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("usages") -} - -func getHistoriesURL(client *eclcloud.ServiceClient, usageID string) string { - return client.ServiceURL("usages", usageID, "histories") -} diff --git a/v3/ecl/dns/v2/recordsets/doc.go b/v3/ecl/dns/v2/recordsets/doc.go deleted file mode 100644 index cc65bed..0000000 --- a/v3/ecl/dns/v2/recordsets/doc.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Package recordsets provides information and interaction with the zone API -resource for the Enterprise Cloud DNS service. - -Example to List RecordSets by Zone - - listOpts := recordsets.ListOpts{ - Type: "A", - } - - zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" - - allPages, err := recordsets.ListByZone(dnsClient, zoneID, listOpts).AllPages() - if err != nil { - panic(err) - } - - allRRs, err := recordsets.ExtractRecordSets(allPages() - if err != nil { - panic(err) - } - - for _, rr := range allRRs { - fmt.Printf("%+v\n", rr) - } - -Example to Create a RecordSet - - createOpts := recordsets.CreateOpts{ - Name: "example.com.", - Type: "A", - TTL: 3600, - Description: "This is a recordset.", - Records: []string{"10.1.0.2"}, - } - - zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" - - rr, err := recordsets.Create(dnsClient, zoneID, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a RecordSet - - zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" - recordsetID := "d96ed01a-b439-4eb8-9b90-7a9f71017f7b" - - err := recordsets.Delete(dnsClient, zoneID, recordsetID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package recordsets diff --git a/v3/ecl/dns/v2/recordsets/requests.go b/v3/ecl/dns/v2/recordsets/requests.go deleted file mode 100644 index b946464..0000000 --- a/v3/ecl/dns/v2/recordsets/requests.go +++ /dev/null @@ -1,162 +0,0 @@ -package recordsets - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToRecordSetListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - ZoneID string `q:"zone_id"` - - // Domain name of zone for partial-match search. - DomainName string `q:"data"` - - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - - // UUID of the recordset at which you want to set a marker. - Marker string `q:"marker"` - - // Integer value for the limit of values to return. - Limit int `q:"limit"` -} - -// ToRecordSetListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToRecordSetListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// ListByZone implements the recordset list request. -func ListByZone(client *eclcloud.ServiceClient, zoneID string, opts ListOptsBuilder) pagination.Pager { - url := baseURL(client, zoneID) - if opts != nil { - query, err := opts.ToRecordSetListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return RecordSetPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get implements the recordset Get request. -func Get(client *eclcloud.ServiceClient, zoneID string, rrsetID string) (r GetResult) { - _, r.Err = client.Get(rrsetURL(client, zoneID, rrsetID), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional attributes to the -// Create request. -type CreateOptsBuilder interface { - ToRecordSetCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies the base attributes that may be used to create a -// RecordSet. -type CreateOpts struct { - // Name is the name of the RecordSet. - Name string `json:"name" required:"true"` - - // Description is a description of the RecordSet. - Description string `json:"description,omitempty"` - - // Records are the DNS records of the RecordSet. - Records []string `json:"records,omitempty"` - - // TTL is the time to live of the RecordSet. - TTL int `json:"ttl,omitempty"` - - // Type is the record type of the RecordSet. - Type string `json:"type" required:"true"` -} - -// ToRecordSetCreateMap formats an CreateOpts structure into a request body. -func (opts CreateOpts) ToRecordSetCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - return b, nil -} - -// Create creates a recordset in a given zone. -func Create(client *eclcloud.ServiceClient, zoneID string, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToRecordSetCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(baseURL(client, zoneID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201, 202}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the -// Update request. -type UpdateOptsBuilder interface { - ToRecordSetUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts specifies the base attributes that may be updated on an existing -// RecordSet. -type UpdateOpts struct { - // Name is the name of the RecordSet. - Name *string `json:"name,omitempty"` - - // Description is a description of the RecordSet. - Description *string `json:"description,omitempty"` - - // TTL is the time to live of the RecordSet. - TTL *int `json:"ttl,omitempty"` - - // Records are the DNS records of the RecordSet. - Records *[]string `json:"records,omitempty"` -} - -// ToRecordSetUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToRecordSetUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - return b, nil -} - -// Update updates a recordset in a given zone -func Update(client *eclcloud.ServiceClient, zoneID string, rrsetID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToRecordSetUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(rrsetURL(client, zoneID, rrsetID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 202}, - }) - return -} - -// Delete removes an existing RecordSet. -func Delete(client *eclcloud.ServiceClient, zoneID string, rrsetID string) (r DeleteResult) { - _, r.Err = client.Delete( - rrsetURL(client, zoneID, rrsetID), - &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} diff --git a/v3/ecl/dns/v2/recordsets/results.go b/v3/ecl/dns/v2/recordsets/results.go deleted file mode 100644 index 29572b1..0000000 --- a/v3/ecl/dns/v2/recordsets/results.go +++ /dev/null @@ -1,163 +0,0 @@ -package recordsets - -import ( - "encoding/json" - "fmt" - // "log" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a RecordSet. -// An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*RecordSet, error) { - var s *RecordSet - err := r.ExtractInto(&s) - return s, err -} - -func (r commonResult) ExtractCreatedRecordSet() (*RecordSet, error) { - var sl []*RecordSet - err := r.ExtractIntoSlicePtr(&sl, "recordsets") - if err != nil { - return nil, fmt.Errorf("[Error] Error in parsing result of recordset create %s", err) - } - return sl[0], nil -} - -// CreateResult is the result of a Create operation. Call its Extract method to -// interpret the result as a RecordSet. -type CreateResult struct { - commonResult -} - -// GetResult is the result of a Get operation. Call its Extract method to -// interpret the result as a RecordSet. -type GetResult struct { - commonResult -} - -// RecordSetPage is a single page of RecordSet results. -type RecordSetPage struct { - pagination.LinkedPageBase -} - -// UpdateResult is result of an Update operation. Call its Extract method to -// interpret the result as a RecordSet. -type UpdateResult struct { - commonResult -} - -// DeleteResult is result of a Delete operation. Call its ExtractErr method to -// determine if the operation succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// IsEmpty returns true if the page contains no results. -func (r RecordSetPage) IsEmpty() (bool, error) { - s, err := ExtractRecordSets(r) - return len(s) == 0, err -} - -// ExtractRecordSets extracts a slice of RecordSets from a List result. -func ExtractRecordSets(r pagination.Page) ([]RecordSet, error) { - var s struct { - RecordSets []RecordSet `json:"recordsets"` - } - err := (r.(RecordSetPage)).ExtractInto(&s) - return s.RecordSets, err -} - -// RecordSet represents a DNS Record Set. -type RecordSet struct { - // ID is the unique ID of the recordset - ID string `json:"id"` - - // ZoneID is the ID of the zone the recordset belongs to. - ZoneID string `json:"zone_id"` - - // ProjectID is the ID of the project that owns the recordset. - // ProjectID string `json:"project_id"` - - // Name is the name of the recordset. - Name string `json:"name"` - - // Type is the RRTYPE of the recordset. - Type string `json:"type"` - - // Records are the DNS records of the recordset. - // This is original code. - // Records []string `json:"records"` - // - // But in ECL2.0, record set will be returned as simple string - // e.g. - // Usual response(like creation) reccordset: "[10.0.0.1]" - // Update response(like creation) reccordset: "10.0.0.1]" - Records interface{} `json:"records"` - - // TTL is the time to live of the recordset. - TTL int `json:"ttl"` - - // Description is the description of the recordset. - Description string `json:"description"` - - // Version is the revision of the recordset. - Version int `json:"version"` - - // CreatedAt is the date when the recordset was created. - CreatedAt time.Time `json:"-"` - - // UpdatedAt is the date when the recordset was updated. - UpdatedAt time.Time `json:"-"` - - // Status is the current status of recordset. - Status string `json:"status"` - - // Current action in progress on the resource. - // This parameter is not currently supported. it always return an empty. - Action string `json:"action"` - - // Links includes HTTP references to the itself, - // useful for passing along to other APIs that might want a recordset - // reference. - Links []eclcloud.Link `json:"-"` -} - -func (r *RecordSet) UnmarshalJSON(b []byte) error { - type tmp RecordSet - var s struct { - tmp - CreatedAt eclcloud.JSONRFC3339MilliNoZ `json:"created_at"` - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - Links map[string]interface{} `json:"links"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = RecordSet(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - - if s.Links != nil { - for rel, href := range s.Links { - if v, ok := href.(string); ok { - link := eclcloud.Link{ - Rel: rel, - Href: v, - } - r.Links = append(r.Links, link) - } - } - } - - return err -} diff --git a/v3/ecl/dns/v2/recordsets/testing/doc.go b/v3/ecl/dns/v2/recordsets/testing/doc.go deleted file mode 100644 index f4d91dc..0000000 --- a/v3/ecl/dns/v2/recordsets/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// recordsets unit tests -package testing diff --git a/v3/ecl/dns/v2/recordsets/testing/fixtures.go b/v3/ecl/dns/v2/recordsets/testing/fixtures.go deleted file mode 100644 index 3190a8e..0000000 --- a/v3/ecl/dns/v2/recordsets/testing/fixtures.go +++ /dev/null @@ -1,320 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/dns/v2/recordsets" -) - -const idZone = "4eb5c333-7031-48ff-a247-0eeccc57472e" - -const idRecordSet1 = "f1dcc528-6b94-47aa-9b13-b62a356ed44f" -const idRecordSet2 = "a0b9df1e-fa38-47a5-855d-f15927fea579" - -const nameRecordSet1 = "rs1.zone1.com." -const nameRecordSet1Update = "rs1update.zone1.com." - -const descriptionRecordSet1 = "a record set 1" -const descriptionRecordSet1Update = "a record set 1-updated" - -const ipRecordSet1 = "10.1.0.0" -const ipRecordSet1Update = "10.1.0.1" - -const TTLRecordSet1 = 3000 -const TTLRecordSet1Update = 3600 - -const recordSetCreatedAt = "2019-02-05T23:41:57" -const recordSetUpdatedAt = "2019-02-05T23:42:13" - -// ListResponse is a sample response to a TestListDNSRecordSet call. -var ListResponse = fmt.Sprintf(`{ - "recordsets": [{ - "id": "%s", - "action": "", - "name": "%s", - "ttl": %d, - "description": "%s", - "records": ["%s"], - "type": "A", - "version": 1, - "status": "ACTIVE", - "created_at": "%s", - "updated_at": "%s", - "zone_id": "%s", - "links": { - "self": "dummylink" - } - }, { - "id": "%s", - "action": "", - "name": "rs2.zone1.com.", - "ttl": 3000, - "description": "a record set 2", - "records": ["20.1.0.0"], - "type": "A", - "version": 1, - "status": "ACTIVE", - "created_at": "%s", - "updated_at": "%s", - "zone_id": "%s", - "links": { - "self": "dummylink" - } - }], - "links": { - "self": "dummylink" - }, - "metadata": { - "total_count": 2 - } -}`, - // For recordSet1 - idRecordSet1, - nameRecordSet1, - TTLRecordSet1, - descriptionRecordSet1, - ipRecordSet1, - recordSetCreatedAt, - recordSetUpdatedAt, - idZone, - // For recordSet2 - idRecordSet2, - recordSetCreatedAt, - recordSetUpdatedAt, - idZone, -) - -// ListResponseLimited is a sample response with limit query option. -var ListResponseLimited = fmt.Sprintf(`{ - "recordsets": [{ - "id": "%s", - "action": "", - "name": "rs2.zone1.com.", - "ttl": 3000, - "description": "a record set 2", - "records": ["20.1.0.0"], - "type": "A", - "version": 1, - "status": "ACTIVE", - "created_at": "%s", - "updated_at": "%s", - "zone_id": "%s", - "links": { - "self": "dummylink" - } - }], - "links": { - "self": "dummylink" - }, - "metadata": { - "total_count": 1 - } -}`, - idRecordSet2, - recordSetCreatedAt, - recordSetUpdatedAt, - idZone, -) - -// RecordSetCreatedAt is mocked created time of each records. -var RecordSetCreatedAt, _ = time.Parse(eclcloud.RFC3339MilliNoZ, recordSetCreatedAt) - -// RecordSetUpdatedAt is mocked updated time of each records. -var RecordSetUpdatedAt, _ = time.Parse(eclcloud.RFC3339MilliNoZ, recordSetUpdatedAt) - -// FirstRecordSet is initialized struct as actual response -var FirstRecordSet = recordsets.RecordSet{ - ID: idRecordSet1, - Description: descriptionRecordSet1, - Records: []string{ipRecordSet1}, - TTL: TTLRecordSet1, - Name: nameRecordSet1, - ZoneID: idZone, - CreatedAt: RecordSetCreatedAt, - UpdatedAt: RecordSetUpdatedAt, - Version: 1, - Type: "A", - Status: "ACTIVE", - Action: "", - Links: []eclcloud.Link{ - { - Rel: "self", - Href: "dummylink", - }, - }, -} - -// SecondRecordSet is initialized struct as actual response -var SecondRecordSet = recordsets.RecordSet{ - ID: idRecordSet2, - Description: "a record set 2", - Records: []string{"20.1.0.0"}, - TTL: 3000, - Name: "rs2.zone1.com.", - ZoneID: idZone, - CreatedAt: RecordSetCreatedAt, - UpdatedAt: RecordSetUpdatedAt, - Version: 1, - Type: "A", - Status: "ACTIVE", - Action: "", - Links: []eclcloud.Link{ - { - Rel: "self", - Href: "dummylink", - }, - }, -} - -// ExpectedRecordSetSlice is the slice of results that should be parsed -// from ListByZoneOutput, in the expected order. -var ExpectedRecordSetSlice = []recordsets.RecordSet{FirstRecordSet, SecondRecordSet} - -// ExpectedRecordSetSliceLimited is the slice of limited results that should be parsed -// from ListByZoneOutput. -var ExpectedRecordSetSliceLimited = []recordsets.RecordSet{SecondRecordSet} - -// GetResponse is a sample response to a Get call. -var GetResponse = fmt.Sprintf(`{ - "id": "%s", - "name": "%s", - "ttl": %d, - "description": "%s", - "records": ["%s"], - "type": "A", - "version": 1, - "created_at": "%s", - "updated_at": "%s", - "zone_id": "%s", - "status": "ACTIVE", - "links": { - "self": "dummylink" - } -}`, - idRecordSet1, - nameRecordSet1, - TTLRecordSet1, - descriptionRecordSet1, - ipRecordSet1, - recordSetCreatedAt, - recordSetUpdatedAt, - idZone, -) - -const selfURL = "http://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets?limit=1" -const nextURL = "http://127.0.0.1:9001/v2/zones/2150b1bf-dee2-4221-9d85-11f7886fb15f/recordsets?limit=1&marker=f7b10e9b-0cae-4a91-b162-562bc6096648" - -// NextPageRequest is a sample request to test pagination. -var NextPageRequest = fmt.Sprintf(` -{ - "links": { - "self": "%s", - "next": "%s" - } -}`, selfURL, nextURL) - -// CreateRequest is a sample request to create a resource record. -var CreateRequest = fmt.Sprintf(`{ - "name" : "%s", - "description" : "%s", - "type" : "A", - "ttl" : %d, - "records" : ["%s"] -}`, - nameRecordSet1, - descriptionRecordSet1, - TTLRecordSet1, - ipRecordSet1, -) - -// CreateResponse is a sample response to a create request. -var CreateResponse = fmt.Sprintf(`{ - "recordsets": [{ - "id": "%s", - "zone_id": "%s", - "records": ["%s"], - "ttl": %d, - "name": "%s", - "description": "%s", - "type": "A", - "version": 1, - "created_at": "", - "updated_at": null, - "links": { - "self": "dummylink" - } - }], - "links": { - "self": "dummylink" - }, - "metadata": { - "total_count": 1 - } -}`, idRecordSet1, - idZone, - ipRecordSet1, - TTLRecordSet1, - nameRecordSet1, - descriptionRecordSet1, -) - -// UpdateRequest is a sample request to update a record set. -var UpdateRequest = fmt.Sprintf(`{ - "name": "%s", - "description" : "%s", - "ttl" : %d, - "records" : ["%s"] -}`, - nameRecordSet1Update, - descriptionRecordSet1Update, - TTLRecordSet1Update, - ipRecordSet1Update, -) - -// UpdateResponse is a sample response to an update request. -var UpdateResponse = fmt.Sprintf(`{ - "id": "%s", - "name": "%s", - "ttl": %d, - "description": "%s", - "records": "%s", - "type": "A", - "version": 1, - "created_at": null, - "updated_at": null, - "zone_id": "%s", - "links": { - "self": "dummylink" - } -}`, - idRecordSet1, - nameRecordSet1Update, - TTLRecordSet1Update, - descriptionRecordSet1Update, - ipRecordSet1Update, - idZone, -) - -// UpdatedRecordSet is initialized struct as actual response of update -var UpdatedRecordSet = recordsets.RecordSet{ - ID: idRecordSet1, - Name: nameRecordSet1Update, - TTL: TTLRecordSet1Update, - Description: descriptionRecordSet1Update, - Records: ipRecordSet1Update, - Type: "A", - Version: 1, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - ZoneID: idZone, - // Status: "", - // Action: "", - Links: []eclcloud.Link{ - { - Rel: "self", - Href: "dummylink", - }, - }, -} diff --git a/v3/ecl/dns/v2/recordsets/testing/requests_test.go b/v3/ecl/dns/v2/recordsets/testing/requests_test.go deleted file mode 100644 index df55fec..0000000 --- a/v3/ecl/dns/v2/recordsets/testing/requests_test.go +++ /dev/null @@ -1,204 +0,0 @@ -package testing - -import ( - "encoding/json" - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/dns/v2/recordsets" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDNSRecordSet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - prepareMuxForListResponse(t) - - count := 0 - err := recordsets.ListByZone(fakeclient.ServiceClient(), idZone, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := recordsets.ExtractRecordSets(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedRecordSetSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDNSRecordSetLimited(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - prepareMuxForListResponse(t) - - count := 0 - listOpts := recordsets.ListOpts{ - Limit: 1, - Marker: idRecordSet1, - } - err := recordsets.ListByZone(fakeclient.ServiceClient(), idZone, listOpts).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := recordsets.ExtractRecordSets(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedRecordSetSliceLimited, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDNSRecordSetAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - prepareMuxForListResponse(t) - - allPages, err := recordsets.ListByZone(fakeclient.ServiceClient(), idZone, nil).AllPages() - th.AssertNoErr(t, err) - allRecordSets, err := recordsets.ExtractRecordSets(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allRecordSets)) -} - -func prepareMuxForListResponse(t *testing.T) { - url := fmt.Sprintf("/zones/%s/recordsets", idZone) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - r.ParseForm() - - marker := r.Form.Get("marker") - switch marker { - case idRecordSet1: - fmt.Fprintf(w, ListResponseLimited) - case "": - fmt.Fprintf(w, ListResponse) - } - }) -} - -func TestGetDNSRecordSet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s/recordsets/%s", idZone, idRecordSet1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetResponse) - }) - - actual, err := recordsets.Get(fakeclient.ServiceClient(), idZone, idRecordSet1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &FirstRecordSet, actual) -} - -func TestNextPageURL(t *testing.T) { - var page recordsets.RecordSetPage - var body map[string]interface{} - err := json.Unmarshal([]byte(NextPageRequest), &body) - if err != nil { - t.Fatalf("Error unmarshaling data into page body: %v", err) - } - page.Body = body - expected := nextURL - actual, err := page.NextPageURL() - th.AssertNoErr(t, err) - th.CheckEquals(t, expected, actual) -} - -func TestCreateDNSRecordSet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s/recordsets", idZone) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateResponse) - }) - - createOpts := recordsets.CreateOpts{ - Name: nameRecordSet1, - Type: "A", - TTL: TTLRecordSet1, - Description: descriptionRecordSet1, - Records: []string{ipRecordSet1}, - } - - // Clone FirstRecord into CreatedRecordSet(Created result struct) - CreatedRecordSet := FirstRecordSet - CreatedRecordSet.CreatedAt = time.Time{} - CreatedRecordSet.UpdatedAt = time.Time{} - CreatedRecordSet.Status = "" - - actual, err := recordsets.Create(fakeclient.ServiceClient(), idZone, createOpts).ExtractCreatedRecordSet() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CreatedRecordSet, actual) -} - -func TestUpdateDNSRecordSet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s/recordsets/%s", idZone, idRecordSet1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, UpdateRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, UpdateResponse) - }) - - name := nameRecordSet1Update - ttl := TTLRecordSet1Update - description := descriptionRecordSet1Update - records := []string{ipRecordSet1Update} - - updateOpts := recordsets.UpdateOpts{ - Name: &name, - TTL: &ttl, - Description: &description, - Records: &records, - } - - actual, err := recordsets.Update( - fakeclient.ServiceClient(), idZone, idRecordSet1, updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &UpdatedRecordSet, actual) -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s/recordsets/%s", idZone, idRecordSet1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - rs := recordsets.Delete(fakeclient.ServiceClient(), idZone, idRecordSet1) - th.AssertNoErr(t, rs.Err) -} diff --git a/v3/ecl/dns/v2/recordsets/urls.go b/v3/ecl/dns/v2/recordsets/urls.go deleted file mode 100644 index 7f63a05..0000000 --- a/v3/ecl/dns/v2/recordsets/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package recordsets - -import "github.com/nttcom/eclcloud/v3" - -func baseURL(c *eclcloud.ServiceClient, zoneID string) string { - return c.ServiceURL("zones", zoneID, "recordsets") -} - -func rrsetURL(c *eclcloud.ServiceClient, zoneID string, rrsetID string) string { - return c.ServiceURL("zones", zoneID, "recordsets", rrsetID) -} diff --git a/v3/ecl/dns/v2/zones/doc.go b/v3/ecl/dns/v2/zones/doc.go deleted file mode 100644 index 9a56cd5..0000000 --- a/v3/ecl/dns/v2/zones/doc.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Package zones provides information and interaction with the zone API -resource for the Enterprise Cloud DNS service. - -Example to List Zones - - listOpts := zones.ListOpts{ - Email: "jdoe@example.com", - } - - allPages, err := zones.List(dnsClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allZones, err := zones.ExtractZones(allPages) - if err != nil { - panic(err) - } - - for _, zone := range allZones { - fmt.Printf("%+v\n", zone) - } - -Example to Create a Zone - - createOpts := zones.CreateOpts{ - Name: "example.com.", - Email: "jdoe@example.com", - Type: "PRIMARY", - TTL: 7200, - Description: "This is a zone.", - } - - zone, err := zones.Create(dnsClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Zone - - zoneID := "99d10f68-5623-4491-91a0-6daafa32b60e" - err := zones.Delete(dnsClient, zoneID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package zones diff --git a/v3/ecl/dns/v2/zones/requests.go b/v3/ecl/dns/v2/zones/requests.go deleted file mode 100644 index 81d5065..0000000 --- a/v3/ecl/dns/v2/zones/requests.go +++ /dev/null @@ -1,173 +0,0 @@ -package zones - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add parameters to the List request. -type ListOptsBuilder interface { - ToZoneListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // Domain name of zone for partial-match search. - DomainName string `q:"domain_name"` - // Sorts the response by the attribute value. A valid value is only domain_name. - SortKey string `q:"sort_key"` - // Sorts the response by the requested sort direction. - // A valid value is asc (ascending) or desc (descending). Default is asc. - SortDir string `q:"sort_dir"` - // UUID of the zone at which you want to set a marker. - Marker string `q:"marker"` - // Integer value for the limit of values to return. - Limit int `q:"limit"` - - // Following are original designate parameters. - // But can not be used in ECL2.0 - // TODO: Remove them at last of development. - // - // Description string `q:"description"` - // Email string `q:"email"` - // Name string `q:"name"` - // Status string `q:"status"` - // TTL int `q:"ttl"` - // Type string `q:"type"` -} - -// ToZoneListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToZoneListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List implements a zone List request. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := baseURL(client) - if opts != nil { - query, err := opts.ToZoneListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ZonePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get returns information about a zone, given its ID. -func Get(client *eclcloud.ServiceClient, zoneID string) (r GetResult) { - _, r.Err = client.Get(zoneURL(client, zoneID), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional attributes to the -// Create request. -type CreateOptsBuilder interface { - ToZoneCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies the attributes used to create a zone. -type CreateOpts struct { - // Description of the zone. - Description string `json:"description,omitempty"` - - // Email contact of the zone. - Email string `json:"email,omitempty"` - - // Name of the zone. - Name string `json:"name" required:"true"` - - // Masters specifies zone masters if this is a secondary zone. - Masters []string `json:"masters,omitempty"` - - // TTL is the time to live of the zone. - TTL int `json:"-"` - - // Type specifies if this is a primary or secondary zone. - Type string `json:"type,omitempty"` -} - -// ToZoneCreateMap formats an CreateOpts structure into a request body. -func (opts CreateOpts) ToZoneCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - if opts.TTL > 0 { - b["ttl"] = opts.TTL - } - - return b, nil -} - -// Create implements a zone create request. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToZoneCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(baseURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201, 202}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the -// Update request. -type UpdateOptsBuilder interface { - ToZoneUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts specifies the attributes to update a zone. -type UpdateOpts struct { - // Description of the zone. - Description *string `json:"description,omitempty"` - - // TTL is the time to live of the zone. - TTL *int `json:"ttl,omitempty"` - - // Masters specifies zone masters if this is a secondary zone. - Masters *[]string `json:"masters,omitempty"` - - // Email contact of the zone. - Email *string `json:"email,omitempty"` -} - -// ToZoneUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToZoneUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - return b, nil -} - -// Update implements a zone update request. -func Update(client *eclcloud.ServiceClient, zoneID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToZoneUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(zoneURL(client, zoneID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 202}, - }) - return -} - -// Delete implements a zone delete request. -func Delete(client *eclcloud.ServiceClient, zoneID string) (r DeleteResult) { - _, r.Err = client.Delete(zoneURL(client, zoneID), &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} diff --git a/v3/ecl/dns/v2/zones/results.go b/v3/ecl/dns/v2/zones/results.go deleted file mode 100644 index 8046ed2..0000000 --- a/v3/ecl/dns/v2/zones/results.go +++ /dev/null @@ -1,166 +0,0 @@ -package zones - -import ( - "encoding/json" - "strconv" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a Zone. -// An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*Zone, error) { - var s *Zone - err := r.ExtractInto(&s) - return s, err -} - -// CreateResult is the result of a Create request. Call its Extract method -// to interpret the result as a Zone. -type CreateResult struct { - commonResult -} - -// GetResult is the result of a Get request. Call its Extract method -// to interpret the result as a Zone. -type GetResult struct { - commonResult -} - -// UpdateResult is the result of an Update request. Call its Extract method -// to interpret the result as a Zone. -type UpdateResult struct { - commonResult -} - -// DeleteResult is the result of a Delete request. Call its ExtractErr method -// to determine if the request succeeded or failed. -type DeleteResult struct { - commonResult -} - -// ZonePage is a single page of Zone results. -type ZonePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if the page contains no results. -func (r ZonePage) IsEmpty() (bool, error) { - s, err := ExtractZones(r) - return len(s) == 0, err -} - -// ExtractZones extracts a slice of Zones from a List result. -func ExtractZones(r pagination.Page) ([]Zone, error) { - var s struct { - Zones []Zone `json:"zones"` - } - err := (r.(ZonePage)).ExtractInto(&s) - return s.Zones, err -} - -// Zone represents a DNS zone. -type Zone struct { - // ID uniquely identifies this zone amongst all other zones, including those - // not accessible to the current tenant. - ID string `json:"id"` - - // PoolID is the ID for the pool hosting this zone. - PoolID string `json:"pool_id"` - - // ProjectID identifies the project/tenant owning this resource. - ProjectID string `json:"project_id"` - - // Name is the DNS Name for the zone. - Name string `json:"name"` - - // Email for the zone. Used in SOA records for the zone. - Email string `json:"email"` - - // TTL is the Time to Live for the zone. - TTL int `json:"ttl"` - - // Serial is the current serial number for the zone. - Serial int `json:"-"` - - // Status is the status of the resource. - Status string `json:"status"` - - // Description for this zone. - Description string `json:"description"` - - // Masters is the servers for slave servers to get DNS information from. - Masters []string `json:"masters"` - - // Type of zone. Primary is controlled by Designate. - // Secondary zones are slaved from another DNS Server. - // Defaults to Primary. - Type string `json:"type"` - - // TransferredAt is the last time an update was retrieved from the - // master servers. - TransferredAt time.Time `json:"-"` - - // Version of the resource. - Version int `json:"version"` - - // CreatedAt is the date when the zone was created. - CreatedAt time.Time `json:"-"` - - // UpdatedAt is the date when the last change was made to the zone. - UpdatedAt time.Time `json:"-"` - - // Action for the zone. - Action string `json:"action"` - - // Attributes for the zone. - Attributes []string `json:"attributes"` - - // Links includes HTTP references to the itself, useful for passing along - // to other APIs that might want a server reference. - Links map[string]interface{} `json:"links"` -} - -func (r *Zone) UnmarshalJSON(b []byte) error { - type tmp Zone - var s struct { - tmp - CreatedAt eclcloud.JSONRFC3339MilliNoZ `json:"created_at"` - UpdatedAt eclcloud.JSONRFC3339MilliNoZ `json:"updated_at"` - TransferredAt eclcloud.JSONRFC3339MilliNoZ `json:"transferred_at"` - Serial interface{} `json:"serial"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Zone(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - r.TransferredAt = time.Time(s.TransferredAt) - - switch t := s.Serial.(type) { - case float64: - r.Serial = int(t) - case string: - switch t { - case "": - r.Serial = 0 - default: - serial, err := strconv.ParseFloat(t, 64) - if err != nil { - return err - } - r.Serial = int(serial) - } - } - - return err -} diff --git a/v3/ecl/dns/v2/zones/testing/doc.go b/v3/ecl/dns/v2/zones/testing/doc.go deleted file mode 100644 index b9b6286..0000000 --- a/v3/ecl/dns/v2/zones/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// zones unit tests -package testing diff --git a/v3/ecl/dns/v2/zones/testing/fixtures.go b/v3/ecl/dns/v2/zones/testing/fixtures.go deleted file mode 100644 index 797bd9d..0000000 --- a/v3/ecl/dns/v2/zones/testing/fixtures.go +++ /dev/null @@ -1,324 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/dns/v2/zones" -) - -const idZone1 = "dcbd3d17-26ce-461d-b77c-a8774cafee75" -const idZone2 = "db511e50-3b1d-4805-98c6-a00adeb6ded0" - -const nameZone1 = "myzone.com." - -const descriptionZone1 = "this is my zone" -const descriptionZone1Update = "this is my zone-update" - -const tenantID = "9b8f16df551e42f3b905859f28a33d55" - -const zoneCreatedAt = "2019-02-05T06:09:41" -const zoneUpdatedAt = "2019-02-05T06:09:45" - -// ListResponse is a sample response to a List call. -var ListResponse = fmt.Sprintf(` -{ - "api_result": "success", - "zones": [{ - "id": "%s", - "description": "%s", - "project_id": "%s", - "created_at": "%s", - "updated_at": "%s", - "name": "%s", - "pool_id": "", - "email": "", - "ttl": 0, - "serial": 0, - "status": "ACTIVE", - "masters": [], - "type": "", - "transferred_at": null, - "version": 1, - "links": { - "self": "dummylink" - }, - "action": "", - "attributes": [] - }, { - "id": "%s", - "description": "This is my zone 2", - "project_id": "%s", - "created_at": "%s", - "updated_at": "%s", - "name": "myzone2.com.", - "pool_id": "", - "email": "", - "ttl": 0, - "serial": 0, - "status": "ACTIVE", - "masters": [], - "type": "", - "transferred_at": null, - "version": 1, - "links": { - "self": "dummylink" - }, - "action": "", - "attributes": [] - }], - "links": { - "self": "dummylink" - }, - "metadata": { - "total_count": 2 - } -}`, - // for Zone1 - idZone1, - descriptionZone1, - tenantID, - zoneCreatedAt, - zoneUpdatedAt, - nameZone1, - // for Zone2 - idZone2, - tenantID, - zoneCreatedAt, - zoneUpdatedAt, -) - -// ExpectedZonesSlice is the slice of results that should be parsed -// from ListOutput, in the expected order. -var ExpectedZonesSlice = []zones.Zone{FirstZone, SecondZone} - -// ZoneCreatedAt is parsed zone creation time -var ZoneCreatedAt, _ = time.Parse(eclcloud.RFC3339MilliNoZ, zoneCreatedAt) - -// ZoneUpdatedAt is parsed zone update time -var ZoneUpdatedAt, _ = time.Parse(eclcloud.RFC3339MilliNoZ, zoneUpdatedAt) - -// FirstZone is the mock object of expected zone-1 -var FirstZone = zones.Zone{ - ID: idZone1, - PoolID: "", - ProjectID: tenantID, - Name: nameZone1, - Email: "", - TTL: 0, - Serial: 0, - Status: "ACTIVE", - Description: descriptionZone1, - Masters: []string{}, - Type: "", - TransferredAt: time.Time{}, - Version: 1, - CreatedAt: ZoneCreatedAt, - UpdatedAt: ZoneUpdatedAt, - Action: "", - Attributes: []string{}, - Links: map[string]interface{}{ - "self": "dummylink", - }, -} - -// SecondZone is the mock object of expected zone-2 -var SecondZone = zones.Zone{ - ID: idZone2, - PoolID: "", - ProjectID: tenantID, - Name: "myzone2.com.", - Email: "", - TTL: 0, - Serial: 0, - Status: "ACTIVE", - Description: "This is my zone 2", - Masters: []string{}, - Type: "", - TransferredAt: time.Time{}, - Version: 1, - CreatedAt: ZoneCreatedAt, - UpdatedAt: ZoneUpdatedAt, - Action: "", - Attributes: []string{}, - Links: map[string]interface{}{ - "self": "dummylink", - }} - -// GetResponse is a sample response to a Get call. -// This get result does not have action, attributes in ECL2.0 -var GetResponse = fmt.Sprintf(` -{ - "id": "%s", - "name": "%s", - "description": "%s", - "project_id": "%s", - "pool_id": "", - "email": "", - "ttl": 0, - "serial": 0, - "status": "ACTIVE", - "masters": [], - "type": "", - "transferred_at": null, - "version": 1, - "created_at": "%s", - "updated_at": "%s", - "links": { - "self": "dummylink" - } -}`, idZone1, - nameZone1, - descriptionZone1, - tenantID, - zoneCreatedAt, - zoneUpdatedAt, -) - -// GetResponseStruct mocked actual -var GetResponseStruct = zones.Zone{ - ID: idZone1, - PoolID: "", - ProjectID: tenantID, - Name: nameZone1, - Email: "", - TTL: 0, - Serial: 0, - Status: "ACTIVE", - Description: descriptionZone1, - Masters: []string{}, - Type: "", - TransferredAt: time.Time{}, - Version: 1, - CreatedAt: ZoneCreatedAt, - UpdatedAt: ZoneUpdatedAt, - Action: "", - Links: map[string]interface{}{ - "self": "dummylink", - }, -} - -// CreateZoneRequest is a sample request to create a zone. -var CreateZoneRequest = fmt.Sprintf(`{ - "description": "%s", - "email": "joe@example.org", - "name": "%s", - "ttl": 7200, - "type": "PRIMARY" -}`, - descriptionZone1, - nameZone1, -) - -// CreateZoneResponse is a sample response to a create request. -var CreateZoneResponse = fmt.Sprintf(`{ - "id": "%s", - "name": "%s", - "description": "%s", - "project_id": "%s", - "pool_id": "", - "email": "", - "ttl": 0, - "serial": 0, - "status": "CREATING", - "masters": [], - "type": "", - "transferred_at": null, - "version": 1, - "created_at": "%s", - "updated_at": null, - "links": { - "self": "dummylink" - } -}`, idZone1, - nameZone1, - descriptionZone1, - tenantID, - zoneCreatedAt, -) - -// CreatedZone is the expected created zone -var CreatedZone = zones.Zone{ - ID: idZone1, - Name: nameZone1, - Description: descriptionZone1, - ProjectID: tenantID, - PoolID: "", - Email: "", - TTL: 0, - Serial: 0, - Status: "CREATING", - Masters: []string{}, - Type: "", - TransferredAt: time.Time{}, - Version: 1, - CreatedAt: ZoneCreatedAt, - UpdatedAt: time.Time{}, - // Action: "", - Links: map[string]interface{}{ - "self": "dummylink", - }, -} - -// UpdateZoneRequest is a sample request to update a zone. -var UpdateZoneRequest = fmt.Sprintf(` -{ - "ttl": 600, - "description": "%s", - "masters": [], - "email": "" -}`, - descriptionZone1Update, -) - -// UpdateZoneResponse is a sample response to update a zone. -var UpdateZoneResponse = fmt.Sprintf(`{ - "id": "%s", - "name": "%s", - "description": "%s", - "project_id": "%s", - "pool_id": "", - "email": "", - "ttl": 0, - "serial": 0, - "status": "ACTIVE", - "masters": [], - "type": "", - "transferred_at": null, - "version": 1, - "created_at": "%s", - "updated_at": "%s", - "links": { - "self": "dummylink" - } -}`, idZone1, - nameZone1, - descriptionZone1Update, - tenantID, - zoneCreatedAt, - zoneUpdatedAt, -) - -// UpdatedZone is the expected updated zone -var UpdatedZone = zones.Zone{ - ID: idZone1, - Name: nameZone1, - Description: descriptionZone1Update, - ProjectID: tenantID, - PoolID: "", - Email: "", - TTL: 0, - Serial: 0, - Status: "ACTIVE", - Masters: []string{}, - Type: "", - TransferredAt: time.Time{}, - Version: 1, - CreatedAt: ZoneCreatedAt, - UpdatedAt: ZoneUpdatedAt, - // Action: "", - Links: map[string]interface{}{ - "self": "dummylink", - }, -} diff --git a/v3/ecl/dns/v2/zones/testing/requests_test.go b/v3/ecl/dns/v2/zones/testing/requests_test.go deleted file mode 100644 index 6097237..0000000 --- a/v3/ecl/dns/v2/zones/testing/requests_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/dns/v2/zones" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDNSZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, ListResponse) - }) - - count := 0 - err := zones.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := zones.ExtractZones(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedZonesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDNSZoneAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, ListResponse) - }) - - allPages, err := zones.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allZones, err := zones.ExtractZones(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allZones)) -} - -func TestGetDNSZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s", idZone1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, GetResponse) - }) - - actual, err := zones.Get(fakeclient.ServiceClient(), idZone1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &GetResponseStruct, actual) -} - -func TestCreateDNSZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, CreateZoneRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, CreateZoneResponse) - }) - - createOpts := zones.CreateOpts{ - Description: descriptionZone1, - Email: "joe@example.org", - Name: nameZone1, - TTL: 7200, - Type: "PRIMARY", - } - - actual, err := zones.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CreatedZone, actual) -} - -func TestUpdateDNSZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s", idZone1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, UpdateZoneRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, UpdateZoneResponse) - }) - - description := descriptionZone1Update - ttl := 600 - masters := make([]string, 0) - email := "" - - updateOpts := zones.UpdateOpts{ - TTL: &ttl, - Description: &description, - Masters: &masters, - Email: &email, - } - - actual, err := zones.Update(fakeclient.ServiceClient(), idZone1, updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &UpdatedZone, actual) -} - -func TestDeleteDNSZone(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/zones/%s", idZone1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusAccepted) - w.Header().Add("Content-Type", "application/json") - }) - - res := zones.Delete(fakeclient.ServiceClient(), idZone1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/dns/v2/zones/urls.go b/v3/ecl/dns/v2/zones/urls.go deleted file mode 100644 index ed838dc..0000000 --- a/v3/ecl/dns/v2/zones/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package zones - -import "github.com/nttcom/eclcloud/v3" - -func baseURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("zones") -} - -func zoneURL(c *eclcloud.ServiceClient, zoneID string) string { - return c.ServiceURL("zones", zoneID) -} diff --git a/v3/ecl/doc.go b/v3/ecl/doc.go deleted file mode 100644 index c7024cf..0000000 --- a/v3/ecl/doc.go +++ /dev/null @@ -1,14 +0,0 @@ -/* -Package ecl contains resources for the individual Enterprise Cloud projects -supported in eclcloud. It also includes functions to authenticate to an -Enterprise cloud and for provisioning various service-level clients. - -Example of Creating a Service Client - - ao, err := ecl.AuthOptionsFromEnv() - provider, err := ecl.AuthenticatedClient(ao) - client, err := ecl.NewNetworkV2(client, eclcloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), - }) -*/ -package ecl diff --git a/v3/ecl/endpoint_location.go b/v3/ecl/endpoint_location.go deleted file mode 100644 index c914fee..0000000 --- a/v3/ecl/endpoint_location.go +++ /dev/null @@ -1,52 +0,0 @@ -package ecl - -import ( - "github.com/nttcom/eclcloud/v3" - tokens3 "github.com/nttcom/eclcloud/v3/ecl/identity/v3/tokens" -) - -/* -V3EndpointURL discovers the endpoint URL for a specific service from a Catalog -acquired during the v3 identity service. - -The specified EndpointOpts are used to identify a unique, unambiguous endpoint -to return. It's an error both when multiple endpoints match the provided -criteria and when none do. The minimum that can be specified is a Type, but you -will also often need to specify a Name and/or a Region depending on what's -available on your Enterprise Cloud deployment. -*/ -func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts eclcloud.EndpointOpts) (string, error) { - // Extract Endpoints from the catalog entries that match the requested Type, Interface, - // Name if provided, and Region if provided. - var endpoints = make([]tokens3.Endpoint, 0, 1) - for _, entry := range catalog.Entries { - if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { - for _, endpoint := range entry.Endpoints { - if opts.Availability != eclcloud.AvailabilityPublic { - err := &ErrInvalidAvailabilityProvided{} - err.Argument = "Availability" - err.Value = opts.Availability - return "", err - } - if (opts.Availability == eclcloud.Availability(endpoint.Interface)) && - (opts.Region == "" || endpoint.Region == opts.Region || endpoint.RegionID == opts.Region) { - endpoints = append(endpoints, endpoint) - } - } - } - } - - // Report an error if the options were ambiguous. - if len(endpoints) > 1 { - return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints} - } - - // Extract the URL from the matching Endpoint. - for _, endpoint := range endpoints { - return eclcloud.NormalizeURL(endpoint.URL), nil - } - - // Report an error if there were no matching endpoints. - err := &eclcloud.ErrEndpointNotFound{} - return "", err -} diff --git a/v3/ecl/errors.go b/v3/ecl/errors.go deleted file mode 100644 index 3b749a2..0000000 --- a/v3/ecl/errors.go +++ /dev/null @@ -1,58 +0,0 @@ -package ecl - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3" - tokens3 "github.com/nttcom/eclcloud/v3/ecl/identity/v3/tokens" -) - -// ErrEndpointNotFound is the error when no suitable endpoint can be found -// in the user's catalog -type ErrEndpointNotFound struct{ eclcloud.BaseError } - -func (e ErrEndpointNotFound) Error() string { - return "No suitable endpoint could be found in the service catalog." -} - -// ErrInvalidAvailabilityProvided is the error when an invalid endpoint -// availability is provided -type ErrInvalidAvailabilityProvided struct{ eclcloud.ErrInvalidInput } - -func (e ErrInvalidAvailabilityProvided) Error() string { - return fmt.Sprintf("Unexpected availability in endpoint query: %s", e.Value) -} - -// ErrMultipleMatchingEndpointsV3 is the error when more than one endpoint -// for the given options is found in the v3 catalog -type ErrMultipleMatchingEndpointsV3 struct { - eclcloud.BaseError - Endpoints []tokens3.Endpoint -} - -func (e ErrMultipleMatchingEndpointsV3) Error() string { - return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints) -} - -// ErrNoAuthURL is the error when the OS_AUTH_URL environment variable is not -// found -type ErrNoAuthURL struct{ eclcloud.ErrInvalidInput } - -func (e ErrNoAuthURL) Error() string { - return "Environment variable OS_AUTH_URL needs to be set." -} - -// ErrNoUsername is the error when the OS_USERNAME environment variable is not -// found -type ErrNoUsername struct{ eclcloud.ErrInvalidInput } - -func (e ErrNoUsername) Error() string { - return "Environment variable OS_USERNAME needs to be set." -} - -// ErrNoPassword is the error when the OS_PASSWORD environment variable is not -// found -type ErrNoPassword struct{ eclcloud.ErrInvalidInput } - -func (e ErrNoPassword) Error() string { - return "Environment variable OS_PASSWORD needs to be set." -} diff --git a/v3/ecl/identity/v3/endpoints/doc.go b/v3/ecl/identity/v3/endpoints/doc.go deleted file mode 100644 index c0ea6b2..0000000 --- a/v3/ecl/identity/v3/endpoints/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Package endpoints provides information and interaction with the service -endpoints API resource in the Enterprise Cloud Identity service. - -Example to List Endpoints - - serviceID := "e629d6e599d9489fb3ae5d9cc12eaea3" - - listOpts := endpoints.ListOpts{ - ServiceID: serviceID, - } - - allPages, err := endpoints.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allEndpoints, err := endpoints.ExtractEndpoints(allPages) - if err != nil { - panic(err) - } - - for _, endpoint := range allEndpoints { - fmt.Printf("%+v\n", endpoint) - } - -Example to Create an Endpoint - - serviceID := "e629d6e599d9489fb3ae5d9cc12eaea3" - - createOpts := endpoints.CreateOpts{ - Availability: eclcloud.AvailabilityPublic, - Name: "neutron", - Region: "RegionOne", - URL: "https://localhost:9696", - ServiceID: serviceID, - } - - endpoint, err := endpoints.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - - -Example to Update an Endpoint - - endpointID := "ad59deeec5154d1fa0dcff518596f499" - - updateOpts := endpoints.UpdateOpts{ - Region: "RegionTwo", - } - - endpoint, err := endpoints.Update(identityClient, endpointID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete an Endpoint - - endpointID := "ad59deeec5154d1fa0dcff518596f499" - err := endpoints.Delete(identityClient, endpointID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package endpoints diff --git a/v3/ecl/identity/v3/endpoints/requests.go b/v3/ecl/identity/v3/endpoints/requests.go deleted file mode 100644 index d646a3c..0000000 --- a/v3/ecl/identity/v3/endpoints/requests.go +++ /dev/null @@ -1,136 +0,0 @@ -package endpoints - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type CreateOptsBuilder interface { - ToEndpointCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains the subset of Endpoint attributes that should be used -// to create an Endpoint. -type CreateOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the eclcloud.Availability type. - Availability eclcloud.Availability `json:"interface" required:"true"` - - // Name is the name of the Endpoint. - Name string `json:"name" required:"true"` - - // Region is the region the Endpoint is located in. - // This field can be omitted or left as a blank string. - Region string `json:"region,omitempty"` - - // URL is the url of the Endpoint. - URL string `json:"url" required:"true"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id" required:"true"` -} - -// ToEndpointCreateMap builds a request body from the Endpoint Create options. -func (opts CreateOpts) ToEndpointCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "endpoint") -} - -// Create inserts a new Endpoint into the service catalog. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToEndpointCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(listURL(client), &b, &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add parameters to the List request. -type ListOptsBuilder interface { - ToEndpointListParams() (string, error) -} - -// ListOpts allows finer control over the endpoints returned by a List call. -// All fields are optional. -type ListOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the eclcloud.Availability type. - Availability eclcloud.Availability `q:"interface"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `q:"service_id"` - - // RegionID is the ID of the region the Endpoint refers to. - RegionID int `q:"region_id"` -} - -// ToEndpointListParams builds a list request from the List options. -func (opts ListOpts) ToEndpointListParams() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates endpoints in a paginated collection, optionally filtered -// by ListOpts criteria. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - u := listURL(client) - if opts != nil { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return pagination.Pager{Err: err} - } - u += q.String() - } - return pagination.NewPager(client, u, func(r pagination.PageResult) pagination.Page { - return EndpointPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// UpdateOptsBuilder allows extensions to add parameters to the Update request. -type UpdateOptsBuilder interface { - ToEndpointUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contains the subset of Endpoint attributes that should be used to -// update an Endpoint. -type UpdateOpts struct { - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the eclcloud.Availability type. - Availability eclcloud.Availability `json:"interface,omitempty"` - - // Name is the name of the Endpoint. - Name string `json:"name,omitempty"` - - // Region is the region the Endpoint is located in. - // This field can be omitted or left as a blank string. - Region string `json:"region,omitempty"` - - // URL is the url of the Endpoint. - URL string `json:"url,omitempty"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id,omitempty"` -} - -// ToEndpointUpdateMap builds an update request body from the Update options. -func (opts UpdateOpts) ToEndpointUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "endpoint") -} - -// Update changes an existing endpoint with new data. -func Update(client *eclcloud.ServiceClient, endpointID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToEndpointUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(endpointURL(client, endpointID), &b, &r.Body, nil) - return -} - -// Delete removes an endpoint from the service catalog. -func Delete(client *eclcloud.ServiceClient, endpointID string) (r DeleteResult) { - _, r.Err = client.Delete(endpointURL(client, endpointID), nil) - return -} diff --git a/v3/ecl/identity/v3/endpoints/results.go b/v3/ecl/identity/v3/endpoints/results.go deleted file mode 100644 index 66e81bb..0000000 --- a/v3/ecl/identity/v3/endpoints/results.go +++ /dev/null @@ -1,80 +0,0 @@ -package endpoints - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete -// Endpoint. An error is returned if the original call or the extraction failed. -func (r commonResult) Extract() (*Endpoint, error) { - var s struct { - Endpoint *Endpoint `json:"endpoint"` - } - err := r.ExtractInto(&s) - return s.Endpoint, err -} - -// CreateResult is the response from a Create operation. Call its Extract -// method to interpret it as an Endpoint. -type CreateResult struct { - commonResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as an Endpoint. -type UpdateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// Endpoint describes the entry point for another service's API. -type Endpoint struct { - // ID is the unique ID of the endpoint. - ID string `json:"id"` - - // Availability is the interface type of the Endpoint (admin, internal, - // or public), referenced by the eclcloud.Availability type. - Availability eclcloud.Availability `json:"interface"` - - // Name is the name of the Endpoint. - Name string `json:"name"` - - // Region is the region the Endpoint is located in. - Region string `json:"region"` - - // ServiceID is the ID of the service the Endpoint refers to. - ServiceID string `json:"service_id"` - - // URL is the url of the Endpoint. - URL string `json:"url"` -} - -// EndpointPage is a single page of Endpoint results. -type EndpointPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if no Endpoints were returned. -func (r EndpointPage) IsEmpty() (bool, error) { - es, err := ExtractEndpoints(r) - return len(es) == 0, err -} - -// ExtractEndpoints extracts an Endpoint slice from a Page. -func ExtractEndpoints(r pagination.Page) ([]Endpoint, error) { - var s struct { - Endpoints []Endpoint `json:"endpoints"` - } - err := (r.(EndpointPage)).ExtractInto(&s) - return s.Endpoints, err -} diff --git a/v3/ecl/identity/v3/endpoints/urls.go b/v3/ecl/identity/v3/endpoints/urls.go deleted file mode 100644 index 9bb5d64..0000000 --- a/v3/ecl/identity/v3/endpoints/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package endpoints - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("endpoints") -} - -func endpointURL(client *eclcloud.ServiceClient, endpointID string) string { - return client.ServiceURL("endpoints", endpointID) -} diff --git a/v3/ecl/identity/v3/groups/doc.go b/v3/ecl/identity/v3/groups/doc.go deleted file mode 100644 index 40afa1d..0000000 --- a/v3/ecl/identity/v3/groups/doc.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Package groups manages and retrieves Groups in the Enterprise Cloud Identity Service. - -Example to List Groups - - listOpts := groups.ListOpts{ - DomainID: "default", - } - - allPages, err := groups.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allGroups, err := groups.ExtractGroups(allPages) - if err != nil { - panic(err) - } - - for _, group := range allGroups { - fmt.Printf("%+v\n", group) - } - -Example to Create a Group - - createOpts := groups.CreateOpts{ - Name: "groupname", - DomainID: "default", - Extra: map[string]interface{}{ - "email": "groupname@example.com", - } - } - - group, err := groups.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Group - - groupID := "0fe36e73809d46aeae6705c39077b1b3" - - updateOpts := groups.UpdateOpts{ - Description: "Updated Description for group", - } - - group, err := groups.Update(identityClient, groupID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Group - - groupID := "0fe36e73809d46aeae6705c39077b1b3" - err := groups.Delete(identityClient, groupID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package groups diff --git a/v3/ecl/identity/v3/groups/errors.go b/v3/ecl/identity/v3/groups/errors.go deleted file mode 100644 index 98e6fe4..0000000 --- a/v3/ecl/identity/v3/groups/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package groups - -import "fmt" - -// InvalidListFilter is returned by the ToUserListQuery method when validation of -// a filter does not pass -type InvalidListFilter struct { - FilterName string -} - -func (e InvalidListFilter) Error() string { - s := fmt.Sprintf( - "Invalid filter name [%s]: it must be in format of NAME__COMPARATOR", - e.FilterName, - ) - return s -} diff --git a/v3/ecl/identity/v3/groups/requests.go b/v3/ecl/identity/v3/groups/requests.go deleted file mode 100644 index af35b1d..0000000 --- a/v3/ecl/identity/v3/groups/requests.go +++ /dev/null @@ -1,179 +0,0 @@ -package groups - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" - "net/url" - "strings" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToGroupListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - // DomainID filters the response by a domain ID. - DomainID string `q:"domain_id"` - - // Name filters the response by group name. - Name string `q:"name"` - - // Filters filters the response by custom filters such as - // 'name__contains=foo' - Filters map[string]string `q:"-"` -} - -// ToGroupListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToGroupListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - - params := q.Query() - for k, v := range opts.Filters { - i := strings.Index(k, "__") - if i > 0 && i < len(k)-2 { - params.Add(k, v) - } else { - return "", InvalidListFilter{FilterName: k} - } - } - - q = &url.URL{RawQuery: params.Encode()} - return q.String(), err -} - -// List enumerates the Groups to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToGroupListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return GroupPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single group, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToGroupCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a group. -type CreateOpts struct { - // Name is the name of the new group. - Name string `json:"name" required:"true"` - - // Description is a description of the group. - Description string `json:"description,omitempty"` - - // DomainID is the ID of the domain the group belongs to. - DomainID string `json:"domain_id,omitempty"` - - // Extra is free-form extra key/value pairs to describe the group. - Extra map[string]interface{} `json:"-"` -} - -// ToGroupCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToGroupCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "group") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["group"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Create creates a new Group. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToGroupCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToGroupUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts provides options for updating a group. -type UpdateOpts struct { - // Name is the name of the new group. - Name string `json:"name,omitempty"` - - // Description is a description of the group. - Description string `json:"description,omitempty"` - - // DomainID is the ID of the domain the group belongs to. - DomainID string `json:"domain_id,omitempty"` - - // Extra is free-form extra key/value pairs to describe the group. - Extra map[string]interface{} `json:"-"` -} - -// ToGroupUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToGroupUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "group") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["group"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Update updates an existing Group. -func Update(client *eclcloud.ServiceClient, groupID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToGroupUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, groupID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a group. -func Delete(client *eclcloud.ServiceClient, groupID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, groupID), nil) - return -} diff --git a/v3/ecl/identity/v3/groups/results.go b/v3/ecl/identity/v3/groups/results.go deleted file mode 100644 index e633aa2..0000000 --- a/v3/ecl/identity/v3/groups/results.go +++ /dev/null @@ -1,131 +0,0 @@ -package groups - -import ( - "encoding/json" - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/internal" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Group helps manage related users. -type Group struct { - // Description describes the group purpose. - Description string `json:"description"` - - // DomainID is the domain ID the group belongs to. - DomainID string `json:"domain_id"` - - // ID is the unique ID of the group. - ID string `json:"id"` - - // Extra is a collection of miscellaneous key/values. - Extra map[string]interface{} `json:"-"` - - // Links contains referencing links to the group. - Links map[string]interface{} `json:"links"` - - // Name is the name of the group. - Name string `json:"name"` -} - -func (r *Group) UnmarshalJSON(b []byte) error { - type tmp Group - var s struct { - tmp - Extra map[string]interface{} `json:"extra"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Group(s.tmp) - - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. - if s.Extra != nil { - r.Extra = s.Extra - } else { - var result interface{} - err := json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - r.Extra = internal.RemainingKeys(Group{}, resultMap) - } - } - - return err -} - -type groupResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a Group. -type GetResult struct { - groupResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a Group. -type CreateResult struct { - groupResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as a Group. -type UpdateResult struct { - groupResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// GroupPage is a single page of Group results. -type GroupPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Groups contains any results. -func (r GroupPage) IsEmpty() (bool, error) { - groups, err := ExtractGroups(r) - return len(groups) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r GroupPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractGroups returns a slice of Groups contained in a single page of results. -func ExtractGroups(r pagination.Page) ([]Group, error) { - var s struct { - Groups []Group `json:"groups"` - } - err := (r.(GroupPage)).ExtractInto(&s) - return s.Groups, err -} - -// Extract interprets any group results as a Group. -func (r groupResult) Extract() (*Group, error) { - var s struct { - Group *Group `json:"group"` - } - err := r.ExtractInto(&s) - return s.Group, err -} diff --git a/v3/ecl/identity/v3/groups/urls.go b/v3/ecl/identity/v3/groups/urls.go deleted file mode 100644 index 3af12ee..0000000 --- a/v3/ecl/identity/v3/groups/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package groups - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("groups") -} - -func getURL(client *eclcloud.ServiceClient, groupID string) string { - return client.ServiceURL("groups", groupID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("groups") -} - -func updateURL(client *eclcloud.ServiceClient, groupID string) string { - return client.ServiceURL("groups", groupID) -} - -func deleteURL(client *eclcloud.ServiceClient, groupID string) string { - return client.ServiceURL("groups", groupID) -} diff --git a/v3/ecl/identity/v3/projects/doc.go b/v3/ecl/identity/v3/projects/doc.go deleted file mode 100644 index f2e73a8..0000000 --- a/v3/ecl/identity/v3/projects/doc.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Package projects manages and retrieves Projects in the Enterprise Cloud Identity -Service. - -Example to List Projects - - listOpts := projects.ListOpts{ - Enabled: eclcloud.Enabled, - } - - allPages, err := projects.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allProjects, err := projects.ExtractProjects(allPages) - if err != nil { - panic(err) - } - - for _, project := range allProjects { - fmt.Printf("%+v\n", project) - } - -Example to Create a Project - - createOpts := projects.CreateOpts{ - Name: "project_name", - Description: "Project Description" - } - - project, err := projects.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Project - - projectID := "966b3c7d36a24facaf20b7e458bf2192" - - updateOpts := projects.UpdateOpts{ - Enabled: eclcloud.Disabled, - } - - project, err := projects.Update(identityClient, projectID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Project - - projectID := "966b3c7d36a24facaf20b7e458bf2192" - err := projects.Delete(identityClient, projectID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package projects diff --git a/v3/ecl/identity/v3/projects/errors.go b/v3/ecl/identity/v3/projects/errors.go deleted file mode 100644 index 7be97d8..0000000 --- a/v3/ecl/identity/v3/projects/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package projects - -import "fmt" - -// InvalidListFilter is returned by the ToUserListQuery method when validation of -// a filter does not pass -type InvalidListFilter struct { - FilterName string -} - -func (e InvalidListFilter) Error() string { - s := fmt.Sprintf( - "Invalid filter name [%s]: it must be in format of NAME__COMPARATOR", - e.FilterName, - ) - return s -} diff --git a/v3/ecl/identity/v3/projects/requests.go b/v3/ecl/identity/v3/projects/requests.go deleted file mode 100644 index 1199de2..0000000 --- a/v3/ecl/identity/v3/projects/requests.go +++ /dev/null @@ -1,173 +0,0 @@ -package projects - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" - "net/url" - "strings" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToProjectListQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -type ListOpts struct { - // DomainID filters the response by a domain ID. - DomainID string `q:"domain_id"` - - // Enabled filters the response by enabled projects. - Enabled *bool `q:"enabled"` - - // IsDomain filters the response by projects that are domains. - // Setting this to true is effectively listing domains. - IsDomain *bool `q:"is_domain"` - - // Name filters the response by project name. - Name string `q:"name"` - - // ParentID filters the response by projects of a given parent project. - ParentID string `q:"parent_id"` - - // Filters filters the response by custom filters such as - // 'name__contains=foo' - Filters map[string]string `q:"-"` -} - -// ToProjectListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToProjectListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - - params := q.Query() - for k, v := range opts.Filters { - i := strings.Index(k, "__") - if i > 0 && i < len(k)-2 { - params.Add(k, v) - } else { - return "", InvalidListFilter{FilterName: k} - } - } - - q = &url.URL{RawQuery: params.Encode()} - return q.String(), err -} - -// List enumerates the Projects to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToProjectListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ProjectPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single project, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToProjectCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a project. -type CreateOpts struct { - // DomainID is the ID this project will belong under. - DomainID string `json:"domain_id,omitempty"` - - // Enabled sets the project status to enabled or disabled. - Enabled *bool `json:"enabled,omitempty"` - - // IsDomain indicates if this project is a domain. - IsDomain *bool `json:"is_domain,omitempty"` - - // Name is the name of the project. - Name string `json:"name" required:"true"` - - // ParentID specifies the parent project of this new project. - ParentID string `json:"parent_id,omitempty"` - - // Description is the description of the project. - Description string `json:"description,omitempty"` -} - -// ToProjectCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToProjectCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "project") -} - -// Create creates a new Project. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToProjectCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, nil) - return -} - -// Delete deletes a project. -func Delete(client *eclcloud.ServiceClient, projectID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, projectID), nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToProjectUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a project. -type UpdateOpts struct { - // DomainID is the ID this project will belong under. - DomainID string `json:"domain_id,omitempty"` - - // Enabled sets the project status to enabled or disabled. - Enabled *bool `json:"enabled,omitempty"` - - // IsDomain indicates if this project is a domain. - IsDomain *bool `json:"is_domain,omitempty"` - - // Name is the name of the project. - Name string `json:"name,omitempty"` - - // ParentID specifies the parent project of this new project. - ParentID string `json:"parent_id,omitempty"` - - // Description is the description of the project. - Description string `json:"description,omitempty"` -} - -// ToUpdateCreateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToProjectUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "project") -} - -// Update modifies the attributes of a project. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToProjectUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/identity/v3/projects/results.go b/v3/ecl/identity/v3/projects/results.go deleted file mode 100644 index fdf3e35..0000000 --- a/v3/ecl/identity/v3/projects/results.go +++ /dev/null @@ -1,103 +0,0 @@ -package projects - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type projectResult struct { - eclcloud.Result -} - -// GetResult is the result of a Get request. Call its Extract method to -// interpret it as a Project. -type GetResult struct { - projectResult -} - -// CreateResult is the result of a Create request. Call its Extract method to -// interpret it as a Project. -type CreateResult struct { - projectResult -} - -// DeleteResult is the result of a Delete request. Call its ExtractErr method to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a Project. -type UpdateResult struct { - projectResult -} - -// Project represents an Enterprise Cloud Identity Project. -type Project struct { - // IsDomain indicates whether the project is a domain. - IsDomain bool `json:"is_domain"` - - // Description is the description of the project. - Description string `json:"description"` - - // DomainID is the domain ID the project belongs to. - DomainID string `json:"domain_id"` - - // Enabled is whether or not the project is enabled. - Enabled bool `json:"enabled"` - - // ID is the unique ID of the project. - ID string `json:"id"` - - // Name is the name of the project. - Name string `json:"name"` - - // ParentID is the parent_id of the project. - ParentID string `json:"parent_id"` -} - -// ProjectPage is a single page of Project results. -type ProjectPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Projects contains any results. -func (r ProjectPage) IsEmpty() (bool, error) { - projects, err := ExtractProjects(r) - return len(projects) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r ProjectPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractProjects returns a slice of Projects contained in a single page of -// results. -func ExtractProjects(r pagination.Page) ([]Project, error) { - var s struct { - Projects []Project `json:"projects"` - } - err := (r.(ProjectPage)).ExtractInto(&s) - return s.Projects, err -} - -// Extract interprets any projectResults as a Project. -func (r projectResult) Extract() (*Project, error) { - var s struct { - Project *Project `json:"project"` - } - err := r.ExtractInto(&s) - return s.Project, err -} diff --git a/v3/ecl/identity/v3/projects/urls.go b/v3/ecl/identity/v3/projects/urls.go deleted file mode 100644 index e9e9d4d..0000000 --- a/v3/ecl/identity/v3/projects/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package projects - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("projects") -} - -func getURL(client *eclcloud.ServiceClient, projectID string) string { - return client.ServiceURL("projects", projectID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("projects") -} - -func deleteURL(client *eclcloud.ServiceClient, projectID string) string { - return client.ServiceURL("projects", projectID) -} - -func updateURL(client *eclcloud.ServiceClient, projectID string) string { - return client.ServiceURL("projects", projectID) -} diff --git a/v3/ecl/identity/v3/roles/doc.go b/v3/ecl/identity/v3/roles/doc.go deleted file mode 100644 index 2c0dfeb..0000000 --- a/v3/ecl/identity/v3/roles/doc.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Package roles provides information and interaction with the roles API -resource for the Enterprise Cloud Identity service. - -Example to List Roles - - listOpts := roles.ListOpts{ - DomainID: "default", - } - - allPages, err := roles.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allRoles, err := roles.ExtractRoles(allPages) - if err != nil { - panic(err) - } - - for _, role := range allRoles { - fmt.Printf("%+v\n", role) - } - -Example to Create a Role - - createOpts := roles.CreateOpts{ - Name: "read-only-admin", - DomainID: "default", - Extra: map[string]interface{}{ - "description": "this role grants read-only privilege cross tenant", - } - } - - role, err := roles.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Role - - roleID := "0fe36e73809d46aeae6705c39077b1b3" - - updateOpts := roles.UpdateOpts{ - Name: "read only admin", - } - - role, err := roles.Update(identityClient, roleID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Role - - roleID := "0fe36e73809d46aeae6705c39077b1b3" - err := roles.Delete(identityClient, roleID).ExtractErr() - if err != nil { - panic(err) - } - -Example to List Role Assignments - - listOpts := roles.ListAssignmentsOpts{ - UserID: "97061de2ed0647b28a393c36ab584f39", - ScopeProjectID: "9df1a02f5eb2416a9781e8b0c022d3ae", - } - - allPages, err := roles.ListAssignments(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allRoles, err := roles.ExtractRoleAssignments(allPages) - if err != nil { - panic(err) - } - - for _, role := range allRoles { - fmt.Printf("%+v\n", role) - } - -Example to List Role Assignments for a User on a Project - - projectID := "a99e9b4e620e4db09a2dfb6e42a01e66" - userID := "9df1a02f5eb2416a9781e8b0c022d3ae" - listAssignmentsOnResourceOpts := roles.ListAssignmentsOnResourceOpts{ - UserID: userID, - ProjectID: projectID, - } - - allPages, err := roles.ListAssignmentsOnResource(identityClient, listAssignmentsOnResourceOpts).AllPages() - if err != nil { - panic(err) - } - - allRoles, err := roles.ExtractRoles(allPages) - if err != nil { - panic(err) - } - - for _, role := range allRoles { - fmt.Printf("%+v\n", role) - } - -Example to Assign a Role to a User in a Project - - projectID := "a99e9b4e620e4db09a2dfb6e42a01e66" - userID := "9df1a02f5eb2416a9781e8b0c022d3ae" - roleID := "9fe2ff9ee4384b1894a90878d3e92bab" - - err := roles.Assign(identityClient, roleID, roles.AssignOpts{ - UserID: userID, - ProjectID: projectID, - }).ExtractErr() - - if err != nil { - panic(err) - } - -Example to Unassign a Role From a User in a Project - - projectID := "a99e9b4e620e4db09a2dfb6e42a01e66" - userID := "9df1a02f5eb2416a9781e8b0c022d3ae" - roleID := "9fe2ff9ee4384b1894a90878d3e92bab" - - err := roles.Unassign(identityClient, roleID, roles.UnassignOpts{ - UserID: userID, - ProjectID: projectID, - }).ExtractErr() - - if err != nil { - panic(err) - } -*/ -package roles diff --git a/v3/ecl/identity/v3/roles/errors.go b/v3/ecl/identity/v3/roles/errors.go deleted file mode 100644 index b60d7d1..0000000 --- a/v3/ecl/identity/v3/roles/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package roles - -import "fmt" - -// InvalidListFilter is returned by the ToUserListQuery method when validation of -// a filter does not pass -type InvalidListFilter struct { - FilterName string -} - -func (e InvalidListFilter) Error() string { - s := fmt.Sprintf( - "Invalid filter name [%s]: it must be in format of NAME__COMPARATOR", - e.FilterName, - ) - return s -} diff --git a/v3/ecl/identity/v3/roles/requests.go b/v3/ecl/identity/v3/roles/requests.go deleted file mode 100644 index 927a3ea..0000000 --- a/v3/ecl/identity/v3/roles/requests.go +++ /dev/null @@ -1,391 +0,0 @@ -package roles - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" - "net/url" - "strings" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToRoleListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - // DomainID filters the response by a domain ID. - DomainID string `q:"domain_id"` - - // Name filters the response by role name. - Name string `q:"name"` - - // Filters filters the response by custom filters such as - // 'name__contains=foo' - Filters map[string]string `q:"-"` -} - -// ToRoleListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToRoleListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - - params := q.Query() - for k, v := range opts.Filters { - i := strings.Index(k, "__") - if i > 0 && i < len(k)-2 { - params.Add(k, v) - } else { - return "", InvalidListFilter{FilterName: k} - } - } - - q = &url.URL{RawQuery: params.Encode()} - return q.String(), err -} - -// List enumerates the roles to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToRoleListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return RolePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single role, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToRoleCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a role. -type CreateOpts struct { - // Name is the name of the new role. - Name string `json:"name" required:"true"` - - // DomainID is the ID of the domain the role belongs to. - DomainID string `json:"domain_id,omitempty"` - - // Extra is free-form extra key/value pairs to describe the role. - Extra map[string]interface{} `json:"-"` -} - -// ToRoleCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToRoleCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "role") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["role"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Create creates a new Role. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToRoleCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToRoleUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts provides options for updating a role. -type UpdateOpts struct { - // Name is the name of the new role. - Name string `json:"name,omitempty"` - - // Extra is free-form extra key/value pairs to describe the role. - Extra map[string]interface{} `json:"-"` -} - -// ToRoleUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToRoleUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "role") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["role"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Update updates an existing Role. -func Update(client *eclcloud.ServiceClient, roleID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToRoleUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, roleID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a role. -func Delete(client *eclcloud.ServiceClient, roleID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, roleID), nil) - return -} - -// ListAssignmentsOptsBuilder allows extensions to add additional parameters to -// the ListAssignments request. -type ListAssignmentsOptsBuilder interface { - ToRolesListAssignmentsQuery() (string, error) -} - -// ListAssignmentsOpts allows you to query the ListAssignments method. -// Specify one of or a combination of GroupId, RoleId, ScopeDomainId, -// ScopeProjectId, and/or UserId to search for roles assigned to corresponding -// entities. -type ListAssignmentsOpts struct { - // GroupID is the group ID to query. - GroupID string `q:"group.id"` - - // RoleID is the specific role to query assignments to. - RoleID string `q:"role.id"` - - // ScopeDomainID filters the results by the given domain ID. - ScopeDomainID string `q:"scope.domain.id"` - - // ScopeProjectID filters the results by the given Project ID. - ScopeProjectID string `q:"scope.project.id"` - - // UserID filterst he results by the given User ID. - UserID string `q:"user.id"` - - // Effective lists effective assignments at the user, project, and domain - // level, allowing for the effects of group membership. - Effective *bool `q:"effective"` -} - -// ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string. -func (opts ListAssignmentsOpts) ToRolesListAssignmentsQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// ListAssignments enumerates the roles assigned to a specified resource. -func ListAssignments(client *eclcloud.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager { - url := listAssignmentsURL(client) - if opts != nil { - query, err := opts.ToRolesListAssignmentsQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return RoleAssignmentPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// ListAssignmentsOnResourceOpts provides options to list role assignments -// for a user/group on a project/domain -type ListAssignmentsOnResourceOpts struct { - // UserID is the ID of a user to assign a role - // Note: exactly one of UserID or GroupID must be provided - UserID string `xor:"GroupID"` - - // GroupID is the ID of a group to assign a role - // Note: exactly one of UserID or GroupID must be provided - GroupID string `xor:"UserID"` - - // ProjectID is the ID of a project to assign a role on - // Note: exactly one of ProjectID or DomainID must be provided - ProjectID string `xor:"DomainID"` - - // DomainID is the ID of a domain to assign a role on - // Note: exactly one of ProjectID or DomainID must be provided - DomainID string `xor:"ProjectID"` -} - -// AssignOpts provides options to assign a role -type AssignOpts struct { - // UserID is the ID of a user to assign a role - // Note: exactly one of UserID or GroupID must be provided - UserID string `xor:"GroupID"` - - // GroupID is the ID of a group to assign a role - // Note: exactly one of UserID or GroupID must be provided - GroupID string `xor:"UserID"` - - // ProjectID is the ID of a project to assign a role on - // Note: exactly one of ProjectID or DomainID must be provided - ProjectID string `xor:"DomainID"` - - // DomainID is the ID of a domain to assign a role on - // Note: exactly one of ProjectID or DomainID must be provided - DomainID string `xor:"ProjectID"` -} - -// UnassignOpts provides options to unassign a role -type UnassignOpts struct { - // UserID is the ID of a user to unassign a role - // Note: exactly one of UserID or GroupID must be provided - UserID string `xor:"GroupID"` - - // GroupID is the ID of a group to unassign a role - // Note: exactly one of UserID or GroupID must be provided - GroupID string `xor:"UserID"` - - // ProjectID is the ID of a project to unassign a role on - // Note: exactly one of ProjectID or DomainID must be provided - ProjectID string `xor:"DomainID"` - - // DomainID is the ID of a domain to unassign a role on - // Note: exactly one of ProjectID or DomainID must be provided - DomainID string `xor:"ProjectID"` -} - -// ListAssignmentsOnResource is the operation responsible for listing role -// assignments for a user/group on a project/domain. -func ListAssignmentsOnResource(client *eclcloud.ServiceClient, opts ListAssignmentsOnResourceOpts) pagination.Pager { - // Check xor conditions - _, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return pagination.Pager{Err: err} - } - - // Get corresponding URL - var targetID string - var targetType string - if opts.ProjectID != "" { - targetID = opts.ProjectID - targetType = "projects" - } else { - targetID = opts.DomainID - targetType = "domains" - } - - var actorID string - var actorType string - if opts.UserID != "" { - actorID = opts.UserID - actorType = "users" - } else { - actorID = opts.GroupID - actorType = "groups" - } - - url := listAssignmentsOnResourceURL(client, targetType, targetID, actorType, actorID) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return RolePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Assign is the operation responsible for assigning a role -// to a user/group on a project/domain. -func Assign(client *eclcloud.ServiceClient, roleID string, opts AssignOpts) (r AssignmentResult) { - // Check xor conditions - _, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - r.Err = err - return - } - - // Get corresponding URL - var targetID string - var targetType string - if opts.ProjectID != "" { - targetID = opts.ProjectID - targetType = "projects" - } else { - targetID = opts.DomainID - targetType = "domains" - } - - var actorID string - var actorType string - if opts.UserID != "" { - actorID = opts.UserID - actorType = "users" - } else { - actorID = opts.GroupID - actorType = "groups" - } - - _, r.Err = client.Put(assignURL(client, targetType, targetID, actorType, actorID, roleID), nil, nil, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// Unassign is the operation responsible for unassigning a role -// from a user/group on a project/domain. -func Unassign(client *eclcloud.ServiceClient, roleID string, opts UnassignOpts) (r UnassignmentResult) { - // Check xor conditions - _, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - r.Err = err - return - } - - // Get corresponding URL - var targetID string - var targetType string - if opts.ProjectID != "" { - targetID = opts.ProjectID - targetType = "projects" - } else { - targetID = opts.DomainID - targetType = "domains" - } - - var actorID string - var actorType string - if opts.UserID != "" { - actorID = opts.UserID - actorType = "users" - } else { - actorID = opts.GroupID - actorType = "groups" - } - - _, r.Err = client.Delete(assignURL(client, targetType, targetID, actorType, actorID, roleID), &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} diff --git a/v3/ecl/identity/v3/roles/results.go b/v3/ecl/identity/v3/roles/results.go deleted file mode 100644 index 6c3ad8b..0000000 --- a/v3/ecl/identity/v3/roles/results.go +++ /dev/null @@ -1,213 +0,0 @@ -package roles - -import ( - "encoding/json" - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/internal" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Role grants permissions to a user. -type Role struct { - // DomainID is the domain ID the role belongs to. - DomainID string `json:"domain_id"` - - // ID is the unique ID of the role. - ID string `json:"id"` - - // Links contains referencing links to the role. - Links map[string]interface{} `json:"links"` - - // Name is the role name - Name string `json:"name"` - - // Extra is a collection of miscellaneous key/values. - Extra map[string]interface{} `json:"-"` -} - -func (r *Role) UnmarshalJSON(b []byte) error { - type tmp Role - var s struct { - tmp - Extra map[string]interface{} `json:"extra"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Role(s.tmp) - - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. - if s.Extra != nil { - r.Extra = s.Extra - } else { - var result interface{} - err := json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - r.Extra = internal.RemainingKeys(Role{}, resultMap) - } - } - - return err -} - -type roleResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a Role. -type GetResult struct { - roleResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a Role -type CreateResult struct { - roleResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as a Role. -type UpdateResult struct { - roleResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// RolePage is a single page of Role results. -type RolePage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Roles contains any results. -func (r RolePage) IsEmpty() (bool, error) { - roles, err := ExtractRoles(r) - return len(roles) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r RolePage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractProjects returns a slice of Roles contained in a single page of -// results. -func ExtractRoles(r pagination.Page) ([]Role, error) { - var s struct { - Roles []Role `json:"roles"` - } - err := (r.(RolePage)).ExtractInto(&s) - return s.Roles, err -} - -// Extract interprets any roleResults as a Role. -func (r roleResult) Extract() (*Role, error) { - var s struct { - Role *Role `json:"role"` - } - err := r.ExtractInto(&s) - return s.Role, err -} - -// RoleAssignment is the result of a role assignments query. -type RoleAssignment struct { - Role AssignedRole `json:"role,omitempty"` - Scope Scope `json:"scope,omitempty"` - User User `json:"user,omitempty"` - Group Group `json:"group,omitempty"` -} - -// AssignedRole represents a Role in an assignment. -type AssignedRole struct { - ID string `json:"id,omitempty"` -} - -// Scope represents a scope in a Role assignment. -type Scope struct { - Domain Domain `json:"domain,omitempty"` - Project Project `json:"project,omitempty"` -} - -// Domain represents a domain in a role assignment scope. -type Domain struct { - ID string `json:"id,omitempty"` -} - -// Project represents a project in a role assignment scope. -type Project struct { - ID string `json:"id,omitempty"` -} - -// User represents a user in a role assignment scope. -type User struct { - ID string `json:"id,omitempty"` -} - -// Group represents a group in a role assignment scope. -type Group struct { - ID string `json:"id,omitempty"` -} - -// RoleAssignmentPage is a single page of RoleAssignments results. -type RoleAssignmentPage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if the RoleAssignmentPage contains no results. -func (r RoleAssignmentPage) IsEmpty() (bool, error) { - roleAssignments, err := ExtractRoleAssignments(r) - return len(roleAssignments) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to -// the next page of results. -func (r RoleAssignmentPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - } `json:"links"` - } - err := r.ExtractInto(&s) - return s.Links.Next, err -} - -// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection -// acquired from List. -func ExtractRoleAssignments(r pagination.Page) ([]RoleAssignment, error) { - var s struct { - RoleAssignments []RoleAssignment `json:"role_assignments"` - } - err := (r.(RoleAssignmentPage)).ExtractInto(&s) - return s.RoleAssignments, err -} - -// AssignmentResult represents the result of an assign operation. -// Call ExtractErr method to determine if the request succeeded or failed. -type AssignmentResult struct { - eclcloud.ErrResult -} - -// UnassignmentResult represents the result of an unassign operation. -// Call ExtractErr method to determine if the request succeeded or failed. -type UnassignmentResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/identity/v3/roles/urls.go b/v3/ecl/identity/v3/roles/urls.go deleted file mode 100644 index c2c2141..0000000 --- a/v3/ecl/identity/v3/roles/urls.go +++ /dev/null @@ -1,39 +0,0 @@ -package roles - -import "github.com/nttcom/eclcloud/v3" - -const ( - rolePath = "roles" -) - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL(rolePath) -} - -func getURL(client *eclcloud.ServiceClient, roleID string) string { - return client.ServiceURL(rolePath, roleID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL(rolePath) -} - -func updateURL(client *eclcloud.ServiceClient, roleID string) string { - return client.ServiceURL(rolePath, roleID) -} - -func deleteURL(client *eclcloud.ServiceClient, roleID string) string { - return client.ServiceURL(rolePath, roleID) -} - -func listAssignmentsURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("role_assignments") -} - -func listAssignmentsOnResourceURL(client *eclcloud.ServiceClient, targetType, targetID, actorType, actorID string) string { - return client.ServiceURL(targetType, targetID, actorType, actorID, rolePath) -} - -func assignURL(client *eclcloud.ServiceClient, targetType, targetID, actorType, actorID, roleID string) string { - return client.ServiceURL(targetType, targetID, actorType, actorID, rolePath, roleID) -} diff --git a/v3/ecl/identity/v3/services/doc.go b/v3/ecl/identity/v3/services/doc.go deleted file mode 100644 index 07cd7b7..0000000 --- a/v3/ecl/identity/v3/services/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Package services provides information and interaction with the services API -resource for the Enterprise Cloud Identity service. - -Example to List Services - - listOpts := services.ListOpts{ - ServiceType: "compute", - } - - allPages, err := services.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allServices, err := services.ExtractServices(allPages) - if err != nil { - panic(err) - } - - for _, service := range allServices { - fmt.Printf("%+v\n", service) - } - -Example to Create a Service - - createOpts := services.CreateOpts{ - Type: "compute", - Extra: map[string]interface{}{ - "name": "compute-service", - "description": "Compute Service", - }, - } - - service, err := services.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Service - - serviceID := "3c7bbe9a6ecb453ca1789586291380ed" - - var iFalse bool = false - updateOpts := services.UpdateOpts{ - Enabled: &iFalse, - Extra: map[string]interface{}{ - "description": "Disabled Compute Service" - }, - } - - service, err := services.Update(identityClient, serviceID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Service - - serviceID := "3c7bbe9a6ecb453ca1789586291380ed" - err := services.Delete(identityClient, serviceID).ExtractErr() - if err != nil { - panic(err) - } - -*/ -package services diff --git a/v3/ecl/identity/v3/services/requests.go b/v3/ecl/identity/v3/services/requests.go deleted file mode 100644 index 32ef0e1..0000000 --- a/v3/ecl/identity/v3/services/requests.go +++ /dev/null @@ -1,154 +0,0 @@ -package services - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToServiceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a service. -type CreateOpts struct { - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the service. - Extra map[string]interface{} `json:"-"` -} - -// ToServiceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToServiceCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "service") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["service"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Create adds a new service of the requested type to the catalog. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToServiceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// ListOptsBuilder enables extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToServiceListMap() (string, error) -} - -// ListOpts provides options for filtering the List results. -type ListOpts struct { - // ServiceType filter the response by a type of service. - ServiceType string `q:"type"` - - // Name filters the response by a service name. - Name string `q:"name"` -} - -// ToServiceListMap builds a list query from the list options. -func (opts ListOpts) ToServiceListMap() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the services available to a specific user. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToServiceListMap() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ServicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get returns additional information about a service, given its ID. -func Get(client *eclcloud.ServiceClient, serviceID string) (r GetResult) { - _, r.Err = client.Get(serviceURL(client, serviceID), &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToServiceUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts provides options for updating a service. -type UpdateOpts struct { - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the service. - Extra map[string]interface{} `json:"-"` -} - -// ToServiceUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToServiceUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "service") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["service"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Update updates an existing Service. -func Update(client *eclcloud.ServiceClient, serviceID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToServiceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, serviceID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete removes an existing service. -// It either deletes all associated endpoints, or fails until all endpoints -// are deleted. -func Delete(client *eclcloud.ServiceClient, serviceID string) (r DeleteResult) { - _, r.Err = client.Delete(serviceURL(client, serviceID), nil) - return -} diff --git a/v3/ecl/identity/v3/services/results.go b/v3/ecl/identity/v3/services/results.go deleted file mode 100644 index 70c5134..0000000 --- a/v3/ecl/identity/v3/services/results.go +++ /dev/null @@ -1,130 +0,0 @@ -package services - -import ( - "encoding/json" - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/internal" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type serviceResult struct { - eclcloud.Result -} - -// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete -// Service. An error is returned if the original call or the extraction failed. -func (r serviceResult) Extract() (*Service, error) { - var s struct { - Service *Service `json:"service"` - } - err := r.ExtractInto(&s) - return s.Service, err -} - -// CreateResult is the response from a Create request. Call its Extract method -// to interpret it as a Service. -type CreateResult struct { - serviceResult -} - -// GetResult is the response from a Get request. Call its Extract method -// to interpret it as a Service. -type GetResult struct { - serviceResult -} - -// UpdateResult is the response from an Update request. Call its Extract method -// to interpret it as a Service. -type UpdateResult struct { - serviceResult -} - -// DeleteResult is the response from a Delete request. Call its ExtractErr -// method to interpret it as a Service. -type DeleteResult struct { - eclcloud.ErrResult -} - -// Service represents an Enterprise Cloud Service. -type Service struct { - // ID is the unique ID of the service. - ID string `json:"id"` - - // Type is the type of the service. - Type string `json:"type"` - - // Enabled is whether or not the service is enabled. - Enabled bool `json:"enabled"` - - // Links contains referencing links to the service. - Links map[string]interface{} `json:"links"` - - // Extra is a collection of miscellaneous key/values. - Extra map[string]interface{} `json:"-"` -} - -func (r *Service) UnmarshalJSON(b []byte) error { - type tmp Service - var s struct { - tmp - Extra map[string]interface{} `json:"extra"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Service(s.tmp) - - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. - if s.Extra != nil { - r.Extra = s.Extra - } else { - var result interface{} - err := json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - r.Extra = internal.RemainingKeys(Service{}, resultMap) - } - } - - return err -} - -// ServicePage is a single page of Service results. -type ServicePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if the ServicePage contains no results. -func (r ServicePage) IsEmpty() (bool, error) { - services, err := ExtractServices(r) - return len(services) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r ServicePage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractServices extracts a slice of Services from a Collection acquired -// from List. -func ExtractServices(r pagination.Page) ([]Service, error) { - var s struct { - Services []Service `json:"services"` - } - err := (r.(ServicePage)).ExtractInto(&s) - return s.Services, err -} diff --git a/v3/ecl/identity/v3/services/urls.go b/v3/ecl/identity/v3/services/urls.go deleted file mode 100644 index 62c89a6..0000000 --- a/v3/ecl/identity/v3/services/urls.go +++ /dev/null @@ -1,19 +0,0 @@ -package services - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("services") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("services") -} - -func serviceURL(client *eclcloud.ServiceClient, serviceID string) string { - return client.ServiceURL("services", serviceID) -} - -func updateURL(client *eclcloud.ServiceClient, serviceID string) string { - return client.ServiceURL("services", serviceID) -} diff --git a/v3/ecl/identity/v3/tokens/doc.go b/v3/ecl/identity/v3/tokens/doc.go deleted file mode 100644 index 6c9f6b3..0000000 --- a/v3/ecl/identity/v3/tokens/doc.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Package tokens provides information and interaction with the token API -resource for the Enterprise Cloud Identity service. - -Example to Create a Token From a Username and Password - - authOptions := tokens.AuthOptions{ - UserID: "username", - Password: "password", - } - - token, err := tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -Example to Create a Token From a Username, Password, and Domain - - authOptions := tokens.AuthOptions{ - UserID: "username", - Password: "password", - DomainID: "default", - } - - token, err := tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - - authOptions = tokens.AuthOptions{ - UserID: "username", - Password: "password", - DomainName: "default", - } - - token, err = tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -Example to Create a Token From a Token - - authOptions := tokens.AuthOptions{ - TokenID: "token_id", - } - - token, err := tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -Example to Create a Token from a Username and Password with Project ID Scope - - scope := tokens.Scope{ - ProjectID: "0fe36e73809d46aeae6705c39077b1b3", - } - - authOptions := tokens.AuthOptions{ - Scope: &scope, - UserID: "username", - Password: "password", - } - - token, err = tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -Example to Create a Token from a Username and Password with Domain ID Scope - - scope := tokens.Scope{ - DomainID: "default", - } - - authOptions := tokens.AuthOptions{ - Scope: &scope, - UserID: "username", - Password: "password", - } - - token, err = tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -Example to Create a Token from a Username and Password with Project Name Scope - - scope := tokens.Scope{ - ProjectName: "project_name", - DomainID: "default", - } - - authOptions := tokens.AuthOptions{ - Scope: &scope, - UserID: "username", - Password: "password", - } - - token, err = tokens.Create(identityClient, authOptions).ExtractToken() - if err != nil { - panic(err) - } - -*/ -package tokens diff --git a/v3/ecl/identity/v3/tokens/requests.go b/v3/ecl/identity/v3/tokens/requests.go deleted file mode 100644 index 3898a56..0000000 --- a/v3/ecl/identity/v3/tokens/requests.go +++ /dev/null @@ -1,162 +0,0 @@ -package tokens - -import "github.com/nttcom/eclcloud/v3" - -// Scope allows a created token to be limited to a specific domain or project. -type Scope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string -} - -// AuthOptionsBuilder provides the ability for extensions to add additional -// parameters to AuthOptions. Extensions must satisfy all required methods. -type AuthOptionsBuilder interface { - // ToTokenV3CreateMap assembles the Create request body, returning an error - // if parameters are missing or inconsistent. - ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) - ToTokenV3ScopeMap() (map[string]interface{}, error) - CanReauth() bool -} - -// AuthOptions represents options for authenticating a user. -type AuthOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed - // by all of the identity services, it will often be populated by a - // provider-level function. - IdentityEndpoint string `json:"-"` - - // Username is required if using Identity V2 API. Consult with your provider's - // control panel to discover your account's username. In Identity V3, either - // UserID or a combination of Username and DomainID or DomainName are needed. - Username string `json:"username,omitempty"` - UserID string `json:"id,omitempty"` - - Password string `json:"password,omitempty"` - - // At most one of DomainID and DomainName must be provided if using Username - // with Identity V3. Otherwise, either are optional. - DomainID string `json:"-"` - DomainName string `json:"name,omitempty"` - - // AllowReauth should be set to true if you grant permission for Eclcloud - // to cache your credentials in memory, and to allow Eclcloud to attempt - // to re-authenticate automatically if/when your token expires. If you set - // it to false, it will not cache these settings, but re-authentication will - // not be possible. This setting defaults to false. - AllowReauth bool `json:"-"` - - // TokenID allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenID string `json:"-"` - - // Authentication through Application Credentials requires supplying name, project and secret - // For project we can use TenantID - ApplicationCredentialID string `json:"-"` - ApplicationCredentialName string `json:"-"` - ApplicationCredentialSecret string `json:"-"` - - Scope Scope `json:"-"` -} - -// ToTokenV3CreateMap builds a request body from AuthOptions. -func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { - eclcloudAuthOpts := eclcloud.AuthOptions{ - Username: opts.Username, - UserID: opts.UserID, - Password: opts.Password, - DomainID: opts.DomainID, - DomainName: opts.DomainName, - AllowReauth: opts.AllowReauth, - TokenID: opts.TokenID, - ApplicationCredentialID: opts.ApplicationCredentialID, - ApplicationCredentialName: opts.ApplicationCredentialName, - ApplicationCredentialSecret: opts.ApplicationCredentialSecret, - } - - return eclcloudAuthOpts.ToTokenV3CreateMap(scope) -} - -// ToTokenV3CreateMap builds a scope request body from AuthOptions. -func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - scope := eclcloud.AuthScope(opts.Scope) - - eclcloudAuthOpts := eclcloud.AuthOptions{ - Scope: &scope, - DomainID: opts.DomainID, - DomainName: opts.DomainName, - } - - return eclcloudAuthOpts.ToTokenV3ScopeMap() -} - -func (opts *AuthOptions) CanReauth() bool { - return opts.AllowReauth -} - -func subjectTokenHeaders(c *eclcloud.ServiceClient, subjectToken string) map[string]string { - return map[string]string{ - "X-Subject-Token": subjectToken, - } -} - -// Create authenticates and either generates a new token, or changes the Scope -// of an existing token. -func Create(c *eclcloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) { - scope, err := opts.ToTokenV3ScopeMap() - if err != nil { - r.Err = err - return - } - - b, err := opts.ToTokenV3CreateMap(scope) - if err != nil { - r.Err = err - return - } - - resp, err := c.Post(tokenURL(c), b, &r.Body, &eclcloud.RequestOpts{ - MoreHeaders: map[string]string{"X-Auth-Token": ""}, - }) - r.Err = err - if resp != nil { - r.Header = resp.Header - } - return -} - -// Get validates and retrieves information about another token. -func Get(c *eclcloud.ServiceClient, token string) (r GetResult) { - resp, err := c.Get(tokenURL(c), &r.Body, &eclcloud.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{200, 203}, - }) - if resp != nil { - r.Err = err - r.Header = resp.Header - } - return -} - -// Validate determines if a specified token is valid or not. -func Validate(c *eclcloud.ServiceClient, token string) (bool, error) { - resp, err := c.Head(tokenURL(c), &eclcloud.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - OkCodes: []int{200, 204, 404}, - }) - if err != nil { - return false, err - } - - return resp.StatusCode == 200 || resp.StatusCode == 204, nil -} - -// Revoke immediately makes specified token invalid. -func Revoke(c *eclcloud.ServiceClient, token string) (r RevokeResult) { - _, r.Err = c.Delete(tokenURL(c), &eclcloud.RequestOpts{ - MoreHeaders: subjectTokenHeaders(c, token), - }) - return -} diff --git a/v3/ecl/identity/v3/tokens/results.go b/v3/ecl/identity/v3/tokens/results.go deleted file mode 100644 index 10f5498..0000000 --- a/v3/ecl/identity/v3/tokens/results.go +++ /dev/null @@ -1,170 +0,0 @@ -package tokens - -import ( - "github.com/nttcom/eclcloud/v3" - "time" -) - -// Endpoint represents a single API endpoint offered by a service. -// It matches either a public, internal or admin URL. -// If supported, it contains a region specifier, again if provided. -// The significance of the Region field will depend upon your provider. -type Endpoint struct { - ID string `json:"id"` - Region string `json:"region"` - RegionID string `json:"region_id"` - Interface string `json:"interface"` - URL string `json:"url"` -} - -// CatalogEntry provides a type-safe interface to an Identity API V3 service -// catalog listing. Each class of service, such as cloud DNS or block storage -// services, could have multiple CatalogEntry representing it (one by interface -// type, e.g public, admin or internal). -// -// Note: when looking for the desired service, try, whenever possible, to key -// off the type field. Otherwise, you'll tie the representation of the service -// to a specific provider. -type CatalogEntry struct { - // Service ID - ID string `json:"id"` - - // Name will contain the provider-specified name for the service. - Name string `json:"name"` - - // Type will contain a type string if Enterprise Cloud defines a type for the - // service. Otherwise, for provider-specific services, the provider may - // assign their own type strings. - Type string `json:"type"` - - // Endpoints will let the caller iterate over all the different endpoints that - // may exist for the service. - Endpoints []Endpoint `json:"endpoints"` -} - -// ServiceCatalog provides a view into the service catalog from a previous, -// successful authentication. -type ServiceCatalog struct { - Entries []CatalogEntry `json:"catalog"` -} - -// Domain provides information about the domain to which this token grants -// access. -type Domain struct { - ID string `json:"id"` - Name string `json:"name"` -} - -// User represents a user resource that exists in the Identity Service. -type User struct { - Domain Domain `json:"domain"` - ID string `json:"id"` - Name string `json:"name"` -} - -// Role provides information about roles to which User is authorized. -type Role struct { - ID string `json:"id"` - Name string `json:"name"` -} - -// Project provides information about project to which User is authorized. -type Project struct { - Domain Domain `json:"domain"` - ID string `json:"id"` - Name string `json:"name"` -} - -// commonResult is the response from a request. A commonResult has various -// methods which can be used to extract different details about the result. -type commonResult struct { - eclcloud.Result -} - -// Extract is a shortcut for ExtractToken. -// This function is deprecated and still present for backward compatibility. -func (r commonResult) Extract() (*Token, error) { - return r.ExtractToken() -} - -// ExtractToken interprets a commonResult as a Token. -func (r commonResult) ExtractToken() (*Token, error) { - var s Token - err := r.ExtractInto(&s) - if err != nil { - return nil, err - } - - // Parse the token itself from the stored headers. - s.ID = r.Header.Get("X-Subject-Token") - - return &s, err -} - -// ExtractServiceCatalog returns the ServiceCatalog that was generated along -// with the user's Token. -func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) { - var s ServiceCatalog - err := r.ExtractInto(&s) - return &s, err -} - -// ExtractUser returns the User that is the owner of the Token. -func (r commonResult) ExtractUser() (*User, error) { - var s struct { - User *User `json:"user"` - } - err := r.ExtractInto(&s) - return s.User, err -} - -// ExtractRoles returns Roles to which User is authorized. -func (r commonResult) ExtractRoles() ([]Role, error) { - var s struct { - Roles []Role `json:"roles"` - } - err := r.ExtractInto(&s) - return s.Roles, err -} - -// ExtractProject returns Project to which User is authorized. -func (r commonResult) ExtractProject() (*Project, error) { - var s struct { - Project *Project `json:"project"` - } - err := r.ExtractInto(&s) - return s.Project, err -} - -// CreateResult is the response from a Create request. Use ExtractToken() -// to interpret it as a Token, or ExtractServiceCatalog() to interpret it -// as a service catalog. -type CreateResult struct { - commonResult -} - -// GetResult is the response from a Get request. Use ExtractToken() -// to interpret it as a Token, or ExtractServiceCatalog() to interpret it -// as a service catalog. -type GetResult struct { - commonResult -} - -// RevokeResult is response from a Revoke request. -type RevokeResult struct { - commonResult -} - -// Token is a string that grants a user access to a controlled set of services -// in an Enterprise Cloud provider. Each Token is valid for a set length of time. -type Token struct { - // ID is the issued token. - ID string `json:"id"` - - // ExpiresAt is the timestamp at which this token will no longer be accepted. - ExpiresAt time.Time `json:"expires_at"` -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.ExtractIntoStructPtr(v, "token") -} diff --git a/v3/ecl/identity/v3/tokens/urls.go b/v3/ecl/identity/v3/tokens/urls.go deleted file mode 100644 index 9792cc6..0000000 --- a/v3/ecl/identity/v3/tokens/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package tokens - -import "github.com/nttcom/eclcloud/v3" - -func tokenURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("auth", "tokens") -} diff --git a/v3/ecl/identity/v3/users/doc.go b/v3/ecl/identity/v3/users/doc.go deleted file mode 100644 index f72ed45..0000000 --- a/v3/ecl/identity/v3/users/doc.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Package users manages and retrieves Users in the Enterprise Cloud Identity Service. - -Example to List Users - - listOpts := users.ListOpts{ - DomainID: "default", - } - - allPages, err := users.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allUsers, err := users.ExtractUsers(allPages) - if err != nil { - panic(err) - } - - for _, user := range allUsers { - fmt.Printf("%+v\n", user) - } - -Example to Create a User - - projectID := "a99e9b4e620e4db09a2dfb6e42a01e66" - - createOpts := users.CreateOpts{ - Name: "username", - DomainID: "default", - DefaultProjectID: projectID, - Enabled: eclcloud.Enabled, - Password: "supersecret", - Extra: map[string]interface{}{ - "email": "username@example.com", - } - } - - user, err := users.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a User - - userID := "0fe36e73809d46aeae6705c39077b1b3" - - updateOpts := users.UpdateOpts{ - Enabled: eclcloud.Disabled, - } - - user, err := users.Update(identityClient, userID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Change Password of a User - - userID := "0fe36e73809d46aeae6705c39077b1b3" - originalPassword := "secretsecret" - password := "new_secretsecret" - - changePasswordOpts := users.ChangePasswordOpts{ - OriginalPassword: originalPassword, - Password: password, - } - - err := users.ChangePassword(identityClient, userID, changePasswordOpts).ExtractErr() - if err != nil { - panic(err) - } - -Example to Delete a User - - userID := "0fe36e73809d46aeae6705c39077b1b3" - err := users.Delete(identityClient, userID).ExtractErr() - if err != nil { - panic(err) - } - -Example to List Groups a User Belongs To - - userID := "0fe36e73809d46aeae6705c39077b1b3" - - allPages, err := users.ListGroups(identityClient, userID).AllPages() - if err != nil { - panic(err) - } - - allGroups, err := groups.ExtractGroups(allPages) - if err != nil { - panic(err) - } - - for _, group := range allGroups { - fmt.Printf("%+v\n", group) - } - -Example to Add a User to a Group - - groupID := "bede500ee1124ae9b0006ff859758b3a" - userID := "0fe36e73809d46aeae6705c39077b1b3" - err := users.AddToGroup(identityClient, groupID, userID).ExtractErr() - - if err != nil { - panic(err) - } - -Example to Check Whether a User Belongs to a Group - - groupID := "bede500ee1124ae9b0006ff859758b3a" - userID := "0fe36e73809d46aeae6705c39077b1b3" - ok, err := users.IsMemberOfGroup(identityClient, groupID, userID).Extract() - if err != nil { - panic(err) - } - - if ok { - fmt.Printf("user %s is a member of group %s\n", userID, groupID) - } - -Example to Remove a User from a Group - - groupID := "bede500ee1124ae9b0006ff859758b3a" - userID := "0fe36e73809d46aeae6705c39077b1b3" - err := users.RemoveFromGroup(identityClient, groupID, userID).ExtractErr() - - if err != nil { - panic(err) - } - -Example to List Projects a User Belongs To - - userID := "0fe36e73809d46aeae6705c39077b1b3" - - allPages, err := users.ListProjects(identityClient, userID).AllPages() - if err != nil { - panic(err) - } - - allProjects, err := projects.ExtractProjects(allPages) - if err != nil { - panic(err) - } - - for _, project := range allProjects { - fmt.Printf("%+v\n", project) - } - -Example to List Users in a Group - - groupID := "bede500ee1124ae9b0006ff859758b3a" - listOpts := users.ListOpts{ - DomainID: "default", - } - - allPages, err := users.ListInGroup(identityClient, groupID, listOpts).AllPages() - if err != nil { - panic(err) - } - - allUsers, err := users.ExtractUsers(allPages) - if err != nil { - panic(err) - } - - for _, user := range allUsers { - fmt.Printf("%+v\n", user) - } - -*/ -package users diff --git a/v3/ecl/identity/v3/users/errors.go b/v3/ecl/identity/v3/users/errors.go deleted file mode 100644 index 0f0b798..0000000 --- a/v3/ecl/identity/v3/users/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package users - -import "fmt" - -// InvalidListFilter is returned by the ToUserListQuery method when validation of -// a filter does not pass -type InvalidListFilter struct { - FilterName string -} - -func (e InvalidListFilter) Error() string { - s := fmt.Sprintf( - "Invalid filter name [%s]: it must be in format of NAME__COMPARATOR", - e.FilterName, - ) - return s -} diff --git a/v3/ecl/identity/v3/users/requests.go b/v3/ecl/identity/v3/users/requests.go deleted file mode 100644 index 915d7ba..0000000 --- a/v3/ecl/identity/v3/users/requests.go +++ /dev/null @@ -1,337 +0,0 @@ -package users - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/identity/v3/groups" - "github.com/nttcom/eclcloud/v3/ecl/identity/v3/projects" - "github.com/nttcom/eclcloud/v3/pagination" - "net/http" - "net/url" - "strings" -) - -// Option is a specific option defined at the API to enable features -// on a user account. -type Option string - -const ( - IgnoreChangePasswordUponFirstUse Option = "ignore_change_password_upon_first_use" - IgnorePasswordExpiry Option = "ignore_password_expiry" - IgnoreLockoutFailureAttempts Option = "ignore_lockout_failure_attempts" - MultiFactorAuthRules Option = "multi_factor_auth_rules" - MultiFactorAuthEnabled Option = "multi_factor_auth_enabled" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToUserListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - // DomainID filters the response by a domain ID. - DomainID string `q:"domain_id"` - - // Enabled filters the response by enabled users. - Enabled *bool `q:"enabled"` - - // IdpID filters the response by an Identity Provider ID. - IdPID string `q:"idp_id"` - - // Name filters the response by username. - Name string `q:"name"` - - // PasswordExpiresAt filters the response based on expiring passwords. - PasswordExpiresAt string `q:"password_expires_at"` - - // ProtocolID filters the response by protocol ID. - ProtocolID string `q:"protocol_id"` - - // UniqueID filters the response by unique ID. - UniqueID string `q:"unique_id"` - - // Filters filters the response by custom filters such as - // 'name__contains=foo' - Filters map[string]string `q:"-"` -} - -// ToUserListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToUserListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - - params := q.Query() - for k, v := range opts.Filters { - i := strings.Index(k, "__") - if i > 0 && i < len(k)-2 { - params.Add(k, v) - } else { - return "", InvalidListFilter{FilterName: k} - } - } - - q = &url.URL{RawQuery: params.Encode()} - return q.String(), err -} - -// List enumerates the Users to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToUserListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return UserPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single user, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToUserCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a user. -type CreateOpts struct { - // Name is the name of the new user. - Name string `json:"name" required:"true"` - - // DefaultProjectID is the ID of the default project of the user. - DefaultProjectID string `json:"default_project_id,omitempty"` - - // Description is a description of the user. - Description string `json:"description,omitempty"` - - // DomainID is the ID of the domain the user belongs to. - DomainID string `json:"domain_id,omitempty"` - - // Enabled sets the user status to enabled or disabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the user. - Extra map[string]interface{} `json:"-"` - - // Options are defined options in the API to enable certain features. - Options map[Option]interface{} `json:"options,omitempty"` - - // Password is the password of the new user. - Password string `json:"password,omitempty"` -} - -// ToUserCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "user") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["user"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Create creates a new User. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToUserCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToUserUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts provides options for updating a user account. -type UpdateOpts struct { - // Name is the name of the new user. - Name string `json:"name,omitempty"` - - // DefaultProjectID is the ID of the default project of the user. - DefaultProjectID string `json:"default_project_id,omitempty"` - - // Description is a description of the user. - Description string `json:"description,omitempty"` - - // DomainID is the ID of the domain the user belongs to. - DomainID string `json:"domain_id,omitempty"` - - // Enabled sets the user status to enabled or disabled. - Enabled *bool `json:"enabled,omitempty"` - - // Extra is free-form extra key/value pairs to describe the user. - Extra map[string]interface{} `json:"-"` - - // Options are defined options in the API to enable certain features. - Options map[Option]interface{} `json:"options,omitempty"` - - // Password is the password of the new user. - Password string `json:"password,omitempty"` -} - -// ToUserUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToUserUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "user") - if err != nil { - return nil, err - } - - if opts.Extra != nil { - if v, ok := b["user"].(map[string]interface{}); ok { - for key, value := range opts.Extra { - v[key] = value - } - } - } - - return b, nil -} - -// Update updates an existing User. -func Update(client *eclcloud.ServiceClient, userID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToUserUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Patch(updateURL(client, userID), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// ChangePasswordOptsBuilder allows extensions to add additional parameters to -// the ChangePassword request. -type ChangePasswordOptsBuilder interface { - ToUserChangePasswordMap() (map[string]interface{}, error) -} - -// ChangePasswordOpts provides options for changing password for a user. -type ChangePasswordOpts struct { - // OriginalPassword is the original password of the user. - OriginalPassword string `json:"original_password"` - - // Password is the new password of the user. - Password string `json:"password"` -} - -// ToUserChangePasswordMap formats a ChangePasswordOpts into a ChangePassword request. -func (opts ChangePasswordOpts) ToUserChangePasswordMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "user") - if err != nil { - return nil, err - } - - return b, nil -} - -// ChangePassword changes password for a user. -func ChangePassword(client *eclcloud.ServiceClient, userID string, opts ChangePasswordOptsBuilder) (r ChangePasswordResult) { - b, err := opts.ToUserChangePasswordMap() - if err != nil { - r.Err = err - return - } - - _, r.Err = client.Post(changePasswordURL(client, userID), &b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// Delete deletes a user. -func Delete(client *eclcloud.ServiceClient, userID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, userID), nil) - return -} - -// ListGroups enumerates groups user belongs to. -func ListGroups(client *eclcloud.ServiceClient, userID string) pagination.Pager { - url := listGroupsURL(client, userID) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return groups.GroupPage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}} - }) -} - -// AddToGroup adds a user to a group. -func AddToGroup(client *eclcloud.ServiceClient, groupID, userID string) (r AddToGroupResult) { - url := addToGroupURL(client, groupID, userID) - _, r.Err = client.Put(url, nil, nil, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// IsMemberOfGroup checks whether a user belongs to a group. -func IsMemberOfGroup(client *eclcloud.ServiceClient, groupID, userID string) (r IsMemberOfGroupResult) { - url := isMemberOfGroupURL(client, groupID, userID) - var response *http.Response - response, r.Err = client.Head(url, &eclcloud.RequestOpts{ - OkCodes: []int{204, 404}, - }) - if r.Err == nil && response != nil { - if (*response).StatusCode == 204 { - r.isMember = true - } - } - - return -} - -// RemoveFromGroup removes a user from a group. -func RemoveFromGroup(client *eclcloud.ServiceClient, groupID, userID string) (r RemoveFromGroupResult) { - url := removeFromGroupURL(client, groupID, userID) - _, r.Err = client.Delete(url, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// ListProjects enumerates groups user belongs to. -func ListProjects(client *eclcloud.ServiceClient, userID string) pagination.Pager { - url := listProjectsURL(client, userID) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return projects.ProjectPage{LinkedPageBase: pagination.LinkedPageBase{PageResult: r}} - }) -} - -// ListInGroup enumerates users that belong to a group. -func ListInGroup(client *eclcloud.ServiceClient, groupID string, opts ListOptsBuilder) pagination.Pager { - url := listInGroupURL(client, groupID) - if opts != nil { - query, err := opts.ToUserListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return UserPage{pagination.LinkedPageBase{PageResult: r}} - }) -} diff --git a/v3/ecl/identity/v3/users/results.go b/v3/ecl/identity/v3/users/results.go deleted file mode 100644 index 78106fc..0000000 --- a/v3/ecl/identity/v3/users/results.go +++ /dev/null @@ -1,178 +0,0 @@ -package users - -import ( - "encoding/json" - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/internal" - "github.com/nttcom/eclcloud/v3/pagination" - "time" -) - -// User represents a User in the Enterprise Cloud Identity Service. -type User struct { - // DefaultProjectID is the ID of the default project of the user. - DefaultProjectID string `json:"default_project_id"` - - // Description is the description of the user. - Description string `json:"description"` - - // DomainID is the domain ID the user belongs to. - DomainID string `json:"domain_id"` - - // Enabled is whether or not the user is enabled. - Enabled bool `json:"enabled"` - - // Extra is a collection of miscellaneous key/values. - Extra map[string]interface{} `json:"-"` - - // ID is the unique ID of the user. - ID string `json:"id"` - - // Links contains referencing links to the user. - Links map[string]interface{} `json:"links"` - - // Name is the name of the user. - Name string `json:"name"` - - // Options are a set of defined options of the user. - Options map[string]interface{} `json:"options"` - - // PasswordExpiresAt is the timestamp when the user's password expires. - PasswordExpiresAt time.Time `json:"-"` -} - -func (r *User) UnmarshalJSON(b []byte) error { - type tmp User - var s struct { - tmp - Extra map[string]interface{} `json:"extra"` - PasswordExpiresAt eclcloud.JSONRFC3339MilliNoZ `json:"password_expires_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = User(s.tmp) - - r.PasswordExpiresAt = time.Time(s.PasswordExpiresAt) - - // Collect other fields and bundle them into Extra - // but only if a field titled "extra" wasn't sent. - if s.Extra != nil { - r.Extra = s.Extra - } else { - var result interface{} - err := json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - delete(resultMap, "password_expires_at") - r.Extra = internal.RemainingKeys(User{}, resultMap) - } - } - - return err -} - -type userResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a User. -type GetResult struct { - userResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a User. -type CreateResult struct { - userResult -} - -// UpdateResult is the response from an Update operation. Call its Extract -// method to interpret it as a User. -type UpdateResult struct { - userResult -} - -// ChangePasswordResult is the response from a ChangePassword operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type ChangePasswordResult struct { - eclcloud.ErrResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// AddToGroupResult is the response from a AddToGroup operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type AddToGroupResult struct { - eclcloud.ErrResult -} - -// IsMemberOfGroupResult is the response from a IsMemberOfGroup operation. Call its -// Extract method to determine if the request succeeded or failed. -type IsMemberOfGroupResult struct { - isMember bool - eclcloud.Result -} - -// RemoveFromGroupResult is the response from a RemoveFromGroup operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type RemoveFromGroupResult struct { - eclcloud.ErrResult -} - -// UserPage is a single page of User results. -type UserPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a UserPage contains any results. -func (r UserPage) IsEmpty() (bool, error) { - users, err := ExtractUsers(r) - return len(users) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r UserPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractUsers returns a slice of Users contained in a single page of results. -func ExtractUsers(r pagination.Page) ([]User, error) { - var s struct { - Users []User `json:"users"` - } - err := (r.(UserPage)).ExtractInto(&s) - return s.Users, err -} - -// Extract interprets any user results as a User. -func (r userResult) Extract() (*User, error) { - var s struct { - User *User `json:"user"` - } - err := r.ExtractInto(&s) - return s.User, err -} - -// Extract extracts IsMemberOfGroupResult as bool and error values -func (r IsMemberOfGroupResult) Extract() (bool, error) { - return r.isMember, r.Err -} diff --git a/v3/ecl/identity/v3/users/urls.go b/v3/ecl/identity/v3/users/urls.go deleted file mode 100644 index 697fa39..0000000 --- a/v3/ecl/identity/v3/users/urls.go +++ /dev/null @@ -1,51 +0,0 @@ -package users - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func getURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func updateURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} - -func changePasswordURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID, "password") -} - -func deleteURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} - -func listGroupsURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID, "groups") -} - -func addToGroupURL(client *eclcloud.ServiceClient, groupID, userID string) string { - return client.ServiceURL("groups", groupID, "users", userID) -} - -func isMemberOfGroupURL(client *eclcloud.ServiceClient, groupID, userID string) string { - return client.ServiceURL("groups", groupID, "users", userID) -} - -func removeFromGroupURL(client *eclcloud.ServiceClient, groupID, userID string) string { - return client.ServiceURL("groups", groupID, "users", userID) -} - -func listProjectsURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID, "projects") -} - -func listInGroupURL(client *eclcloud.ServiceClient, groupID string) string { - return client.ServiceURL("groups", groupID, "users") -} diff --git a/v3/ecl/imagestorage/v2/imagedata/doc.go b/v3/ecl/imagestorage/v2/imagedata/doc.go deleted file mode 100644 index 0c12bf2..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/doc.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Package imagedata enables management of image data. - -Example to Upload Image Data - - imageID := "da3b75d9-3f4a-40e7-8a2c-bfab23927dea" - - imageData, err := os.Open("/path/to/image/file") - if err != nil { - panic(err) - } - defer imageData.Close() - - err = imagedata.Upload(imageClient, imageID, imageData).ExtractErr() - if err != nil { - panic(err) - } - -Example to Stage Image Data - - imageID := "da3b75d9-3f4a-40e7-8a2c-bfab23927dea" - - imageData, err := os.Open("/path/to/image/file") - if err != nil { - panic(err) - } - defer imageData.Close() - - err = imagedata.Stage(imageClient, imageID, imageData).ExtractErr() - if err != nil { - panic(err) - } - -Example to Download Image Data - - imageID := "da3b75d9-3f4a-40e7-8a2c-bfab23927dea" - - image, err := imagedata.Download(imageClient, imageID).Extract() - if err != nil { - panic(err) - } - - imageData, err := ioutil.ReadAll(image) - if err != nil { - panic(err) - } -*/ -package imagedata diff --git a/v3/ecl/imagestorage/v2/imagedata/requests.go b/v3/ecl/imagestorage/v2/imagedata/requests.go deleted file mode 100644 index c80bfdc..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/requests.go +++ /dev/null @@ -1,28 +0,0 @@ -package imagedata - -import ( - "io" - "net/http" - - "github.com/nttcom/eclcloud/v3" -) - -// Upload uploads an image file. -func Upload(client *eclcloud.ServiceClient, id string, data io.Reader) (r UploadResult) { - _, r.Err = client.Put(uploadURL(client, id), data, nil, &eclcloud.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/octet-stream"}, - OkCodes: []int{204}, - }) - return -} - -// Download retrieves an image. -func Download(client *eclcloud.ServiceClient, id string) (r DownloadResult) { - var resp *http.Response - resp, r.Err = client.Get(downloadURL(client, id), nil, nil) - if resp != nil { - r.Body = resp.Body - r.Header = resp.Header - } - return -} diff --git a/v3/ecl/imagestorage/v2/imagedata/results.go b/v3/ecl/imagestorage/v2/imagedata/results.go deleted file mode 100644 index a227351..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/results.go +++ /dev/null @@ -1,34 +0,0 @@ -package imagedata - -import ( - "fmt" - "io" - - "github.com/nttcom/eclcloud/v3" -) - -// UploadResult is the result of an upload image operation. Call its ExtractErr -// method to determine if the request succeeded or failed. -type UploadResult struct { - eclcloud.ErrResult -} - -// StageResult is the result of a stage image operation. Call its ExtractErr -// method to determine if the request succeeded or failed. -type StageResult struct { - eclcloud.ErrResult -} - -// DownloadResult is the result of a download image operation. Call its Extract -// method to gain access to the image data. -type DownloadResult struct { - eclcloud.Result -} - -// Extract builds images model from io.Reader -func (r DownloadResult) Extract() (io.Reader, error) { - if r, ok := r.Body.(io.Reader); ok { - return r, nil - } - return nil, fmt.Errorf("expected io.Reader but got: %T(%#v)", r.Body, r.Body) -} diff --git a/v3/ecl/imagestorage/v2/imagedata/testing/doc.go b/v3/ecl/imagestorage/v2/imagedata/testing/doc.go deleted file mode 100644 index 5a9db1b..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// imagedata unit tests -package testing diff --git a/v3/ecl/imagestorage/v2/imagedata/testing/fixtures.go b/v3/ecl/imagestorage/v2/imagedata/testing/fixtures.go deleted file mode 100644 index bfd216a..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/testing/fixtures.go +++ /dev/null @@ -1,40 +0,0 @@ -package testing - -import ( - "io/ioutil" - "net/http" - "testing" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// HandlePutImageDataSuccessfully setup -func HandlePutImageDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/0cb9328d-dd8c-41bb-b378-404b854b93b9/file", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Errorf("Unable to read request body: %v", err) - } - - th.AssertByteArrayEquals(t, []byte{5, 3, 7, 24}, b) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleGetImageDataSuccessfully setup -func HandleGetImageDataSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/100f4d2d-dcb5-472e-b93f-b4e13d888604/file", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusOK) - - _, err := w.Write([]byte{34, 87, 0, 23, 23, 23, 56, 255, 254, 0}) - th.AssertNoErr(t, err) - }) -} diff --git a/v3/ecl/imagestorage/v2/imagedata/testing/requests_test.go b/v3/ecl/imagestorage/v2/imagedata/testing/requests_test.go deleted file mode 100644 index 23f232d..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/testing/requests_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package testing - -import ( - "fmt" - "io" - "io/ioutil" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/imagestorage/v2/imagedata" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestUpload(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandlePutImageDataSuccessfully(t) - - err := imagedata.Upload( - fakeclient.ServiceClient(), - "0cb9328d-dd8c-41bb-b378-404b854b93b9", - readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() - - th.AssertNoErr(t, err) -} - -/* -func TestStage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleStageImageDataSuccessfully(t) - - err := imagedata.Stage( - fakeclient.ServiceClient(), - "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - readSeekerOfBytes([]byte{5, 3, 7, 24})).ExtractErr() - - th.AssertNoErr(t, err) -} -*/ - -func readSeekerOfBytes(bs []byte) io.ReadSeeker { - return &RS{bs: bs} -} - -// implements io.ReadSeeker -type RS struct { - bs []byte - offset int -} - -func (rs *RS) Read(p []byte) (int, error) { - leftToRead := len(rs.bs) - rs.offset - - if 0 < leftToRead { - bytesToWrite := min(leftToRead, len(p)) - for i := 0; i < bytesToWrite; i++ { - p[i] = rs.bs[rs.offset] - rs.offset++ - } - return bytesToWrite, nil - } - return 0, io.EOF -} - -func min(a int, b int) int { - if a < b { - return a - } - return b -} - -func (rs *RS) Seek(offset int64, whence int) (int64, error) { - var offsetInt = int(offset) - if whence == 0 { - rs.offset = offsetInt - } else if whence == 1 { - rs.offset = rs.offset + offsetInt - } else if whence == 2 { - rs.offset = len(rs.bs) - offsetInt - } else { - return 0, fmt.Errorf("for parameter `whence`, expected value in {0,1,2} but got: %#v", whence) - } - - return int64(rs.offset), nil -} - -func TestDownload(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleGetImageDataSuccessfully(t) - - rdr, err := imagedata.Download(fakeclient.ServiceClient(), "100f4d2d-dcb5-472e-b93f-b4e13d888604").Extract() - th.AssertNoErr(t, err) - - bs, err := ioutil.ReadAll(rdr) - th.AssertNoErr(t, err) - - th.AssertByteArrayEquals(t, []byte{34, 87, 0, 23, 23, 23, 56, 255, 254, 0}, bs) -} diff --git a/v3/ecl/imagestorage/v2/imagedata/urls.go b/v3/ecl/imagestorage/v2/imagedata/urls.go deleted file mode 100644 index e66db63..0000000 --- a/v3/ecl/imagestorage/v2/imagedata/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package imagedata - -import "github.com/nttcom/eclcloud/v3" - -const ( - rootPath = "images" - uploadPath = "file" - stagePath = "stage" -) - -// `imageDataURL(c,i)` is the URL for the binary image data for the -// image identified by ID `i` in the service `c`. -func uploadURL(c *eclcloud.ServiceClient, imageID string) string { - return c.ServiceURL(rootPath, imageID, uploadPath) -} - -func stageURL(c *eclcloud.ServiceClient, imageID string) string { - return c.ServiceURL(rootPath, imageID, stagePath) -} - -func downloadURL(c *eclcloud.ServiceClient, imageID string) string { - return uploadURL(c, imageID) -} diff --git a/v3/ecl/imagestorage/v2/images/doc.go b/v3/ecl/imagestorage/v2/images/doc.go deleted file mode 100644 index cd3f5e2..0000000 --- a/v3/ecl/imagestorage/v2/images/doc.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Package images enables management and retrieval of images from the Enterprise Cloud -Image Service. - -Example to List Images - - images.ListOpts{ - Owner: "a7509e1ae65945fda83f3e52c6296017", - } - - allPages, err := images.List(imagesClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allImages, err := images.ExtractImages(allPages) - if err != nil { - panic(err) - } - - for _, image := range allImages { - fmt.Printf("%+v\n", image) - } - -Example to Create an Image - - createOpts := images.CreateOpts{ - Name: "image_name", - Visibility: images.ImageVisibilityPrivate, - } - - image, err := images.Create(imageClient, createOpts) - if err != nil { - panic(err) - } - -Example to Update an Image - - imageID := "1bea47ed-f6a9-463b-b423-14b9cca9ad27" - - updateOpts := images.UpdateOpts{ - images.ReplaceImageName{ - NewName: "new_name", - }, - } - - image, err := images.Update(imageClient, imageID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete an Image - - imageID := "1bea47ed-f6a9-463b-b423-14b9cca9ad27" - err := images.Delete(imageClient, imageID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package images diff --git a/v3/ecl/imagestorage/v2/images/requests.go b/v3/ecl/imagestorage/v2/images/requests.go deleted file mode 100644 index 78ff19f..0000000 --- a/v3/ecl/imagestorage/v2/images/requests.go +++ /dev/null @@ -1,349 +0,0 @@ -package images - -import ( - "fmt" - "net/url" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToImageListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // ID is the ID of the image. - // Multiple IDs can be specified by constructing a string - // such as "in:uuid1,uuid2,uuid3". - ID string `q:"id"` - - // Integer value for the limit of values to return. - Limit int `q:"limit"` - - // UUID of the server at which you want to set a marker. - Marker string `q:"marker"` - - // Name filters on the name of the image. - // Multiple names can be specified by constructing a string - // such as "in:name1,name2,name3". - Name string `q:"name"` - - // Visibility filters on the visibility of the image. - Visibility ImageVisibility `q:"visibility"` - - // MemberStatus filters on the member status of the image. - MemberStatus ImageMemberStatus `q:"member_status"` - - // Owner filters on the project ID of the image. - Owner string `q:"owner"` - - // Status filters on the status of the image. - // Multiple statuses can be specified by constructing a string - // such as "in:saving,queued". - Status ImageStatus `q:"status"` - - // SizeMin filters on the size_min image property. - SizeMin int64 `q:"size_min"` - - // SizeMax filters on the size_max image property. - SizeMax int64 `q:"size_max"` - - // Sort sorts the results using the new style of sorting. See the Enterprise Cloud - // Image API reference for the exact syntax. - // - // Sort cannot be used with the classic sort options (sort_key and sort_dir). - Sort string `q:"sort"` - - // SortKey will sort the results based on a specified image property. - SortKey string `q:"sort_key"` - - // SortDir will sort the list results either ascending or decending. - SortDir string `q:"sort_dir"` - - // Tags filters on specific image tags. - Tags []string `q:"tag"` - - // CreatedAtQuery filters images based on their creation date. - CreatedAtQuery *ImageDateQuery - - // UpdatedAtQuery filters images based on their updated date. - UpdatedAtQuery *ImageDateQuery - - // ContainerFormat filters images based on the container_format. - // Multiple container formats can be specified by constructing a - // string such as "in:bare,ami". - ContainerFormat string `q:"container_format"` - - // DiskFormat filters images based on the disk_format. - // Multiple disk formats can be specified by constructing a string - // such as "in:qcow2,iso". - DiskFormat string `q:"disk_format"` -} - -// ToImageListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToImageListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - params := q.Query() - - if opts.CreatedAtQuery != nil { - createdAt := opts.CreatedAtQuery.Date.Format(time.RFC3339) - if v := opts.CreatedAtQuery.Filter; v != "" { - createdAt = fmt.Sprintf("%s:%s", v, createdAt) - } - - params.Add("created_at", createdAt) - } - - if opts.UpdatedAtQuery != nil { - updatedAt := opts.UpdatedAtQuery.Date.Format(time.RFC3339) - if v := opts.UpdatedAtQuery.Filter; v != "" { - updatedAt = fmt.Sprintf("%s:%s", v, updatedAt) - } - - params.Add("updated_at", updatedAt) - } - - q = &url.URL{RawQuery: params.Encode()} - - return q.String(), err -} - -// List implements image list request. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToImageListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - imagePage := ImagePage{ - serviceURL: c.ServiceURL(), - LinkedPageBase: pagination.LinkedPageBase{PageResult: r}, - } - - return imagePage - }) -} - -// CreateOptsBuilder allows extensions to add parameters to the Create request. -type CreateOptsBuilder interface { - // Returns value that can be passed to json.Marshal - ToImageCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents options used to create an image. -type CreateOpts struct { - // Name is the name of the new image. - Name string `json:"name,omitempty"` - - // Id is the the image ID. - ID string `json:"id,omitempty"` - - // Visibility defines who can see/use the image. - Visibility *ImageVisibility `json:"visibility,omitempty"` - - // Tags is a set of image tags. - Tags []string `json:"tags,omitempty"` - - // ContainerFormat is the format of the - // container. Valid values are ami, ari, aki, bare, and ovf. - ContainerFormat string `json:"container_format,omitempty"` - - // DiskFormat is the format of the disk. If set, - // valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, - // and iso. - DiskFormat string `json:"disk_format,omitempty"` - - // MinDisk is the amount of disk space in - // GB that is required to boot the image. - MinDisk int `json:"min_disk,omitempty"` - - // MinRAM is the amount of RAM in MB that - // is required to boot the image. - MinRAM int `json:"min_ram,omitempty"` - - // protected is whether the image is not deletable. - Protected *bool `json:"protected,omitempty"` - - // properties is a set of properties, if any, that - // are associated with the image. - Properties map[string]string `json:"-"` -} - -// ToImageCreateMap assembles a request body based on the contents of -// a CreateOpts. -func (opts CreateOpts) ToImageCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - if opts.Properties != nil { - for k, v := range opts.Properties { - b[k] = v - } - } - return b, nil -} - -// Create implements create image request. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToImageCreateMap() - if err != nil { - r.Err = err - return r - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{OkCodes: []int{201}}) - return -} - -// Delete implements image delete request. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// Get implements image get request. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// Update implements image updated request. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToImageUpdateMap() - if err != nil { - r.Err = err - return r - } - _, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - MoreHeaders: map[string]string{"Content-Type": "application/openstack-images-v2.1-json-patch"}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - // returns value implementing json.Marshaler which when marshaled matches - // the patch schema. - ToImageUpdateMap() ([]interface{}, error) -} - -// UpdateOpts implements UpdateOpts -type UpdateOpts []Patch - -// ToImageUpdateMap assembles a request body based on the contents of -// UpdateOpts. -func (opts UpdateOpts) ToImageUpdateMap() ([]interface{}, error) { - m := make([]interface{}, len(opts)) - for i, patch := range opts { - patchJSON := patch.ToImagePatchMap() - m[i] = patchJSON - } - return m, nil -} - -// Patch represents a single update to an existing image. Multiple updates -// to an image can be submitted at the same time. -type Patch interface { - ToImagePatchMap() map[string]interface{} -} - -// UpdateVisibility represents an updated visibility property request. -type UpdateVisibility struct { - Visibility ImageVisibility -} - -// ToImagePatchMap assembles a request body based on UpdateVisibility. -func (r UpdateVisibility) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/visibility", - "value": r.Visibility, - } -} - -// ReplaceImageName represents an updated image_name property request. -type ReplaceImageName struct { - NewName string -} - -// ToImagePatchMap assembles a request body based on ReplaceImageName. -func (r ReplaceImageName) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/name", - "value": r.NewName, - } -} - -// ReplaceImageChecksum represents an updated checksum property request. -type ReplaceImageChecksum struct { - Checksum string -} - -// ReplaceImageChecksum assembles a request body based on ReplaceImageChecksum. -func (r ReplaceImageChecksum) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/checksum", - "value": r.Checksum, - } -} - -// ReplaceImageTags represents an updated tags property request. -type ReplaceImageTags struct { - NewTags []string -} - -// ToImagePatchMap assembles a request body based on ReplaceImageTags. -func (r ReplaceImageTags) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/tags", - "value": r.NewTags, - } -} - -// UpdateOp represents a valid update operation. -type UpdateOp string - -const ( - AddOp UpdateOp = "add" - ReplaceOp UpdateOp = "replace" - RemoveOp UpdateOp = "remove" -) - -// UpdateImageProperty represents an update property request. -type UpdateImageProperty struct { - Op UpdateOp - Name string - Value string -} - -// ToImagePatchMap assembles a request body based on UpdateImageProperty. -func (r UpdateImageProperty) ToImagePatchMap() map[string]interface{} { - updateMap := map[string]interface{}{ - "op": r.Op, - "path": fmt.Sprintf("/%s", r.Name), - } - - if r.Value != "" { - updateMap["value"] = r.Value - } - - return updateMap -} diff --git a/v3/ecl/imagestorage/v2/images/results.go b/v3/ecl/imagestorage/v2/images/results.go deleted file mode 100644 index f373fdc..0000000 --- a/v3/ecl/imagestorage/v2/images/results.go +++ /dev/null @@ -1,201 +0,0 @@ -package images - -import ( - "encoding/json" - "fmt" - "reflect" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/internal" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Image represents an image found in the Enterprise Cloud Image service. -type Image struct { - // ID is the image UUID. - ID string `json:"id"` - - // Name is the human-readable display name for the image. - Name string `json:"name"` - - // Status is the image status. It can be "queued" or "active" - // See imageservice/v2/images/type.go - Status ImageStatus `json:"status"` - - // Tags is a list of image tags. Tags are arbitrarily defined strings - // attached to an image. - Tags []string `json:"tags"` - - // ContainerFormat is the format of the container. - // Valid values are ami, ari, aki, bare, and ovf. - ContainerFormat string `json:"container_format"` - - // DiskFormat is the format of the disk. - // If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, - // and iso. - DiskFormat string `json:"disk_format"` - - // MinDiskGigabytes is the amount of disk space in GB that is required to - // boot the image. - MinDiskGigabytes int `json:"min_disk"` - - // MinRAMMegabytes [optional] is the amount of RAM in MB that is required to - // boot the image. - MinRAMMegabytes int `json:"min_ram"` - - // Owner is the tenant ID the image belongs to. - Owner string `json:"owner"` - - // Protected is whether the image is deletable or not. - Protected bool `json:"protected"` - - // Visibility defines who can see/use the image. - Visibility ImageVisibility `json:"visibility"` - - // Checksum is the checksum of the data that's associated with the image. - Checksum string `json:"checksum"` - - // SizeBytes is the size of the data that's associated with the image. - SizeBytes int64 `json:"-"` - - // Metadata is a set of metadata associated with the image. - // Image metadata allow for meaningfully define the image properties - // and tags. - Metadata map[string]string `json:"metadata"` - - // Properties is a set of key-value pairs, if any, that are associated with - // the image. - Properties map[string]interface{} - - // CreatedAt is the date when the image has been created. - CreatedAt time.Time `json:"created_at"` - - // UpdatedAt is the date when the last change has been made to the image or - // it's properties. - UpdatedAt time.Time `json:"updated_at"` - - // File is the trailing path after the glance endpoint that represent the - // location of the image or the path to retrieve it. - File string `json:"file"` - - // Schema is the path to the JSON-schema that represent the image or image - // entity. - Schema string `json:"schema"` - - // VirtualSize is the virtual size of the image - VirtualSize int64 `json:"virtual_size"` -} - -func (r *Image) UnmarshalJSON(b []byte) error { - type tmp Image - var s struct { - tmp - SizeBytes interface{} `json:"size"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Image(s.tmp) - - switch t := s.SizeBytes.(type) { - case nil: - r.SizeBytes = 0 - case float32: - r.SizeBytes = int64(t) - case float64: - r.SizeBytes = int64(t) - default: - return fmt.Errorf("unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t) - } - - // Bundle all other fields into Properties - var result interface{} - err = json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - delete(resultMap, "self") - delete(resultMap, "size") - r.Properties = internal.RemainingKeys(Image{}, resultMap) - } - - return err -} - -type commonResult struct { - eclcloud.Result -} - -// Extract interprets any commonResult as an Image. -func (r commonResult) Extract() (*Image, error) { - var s *Image - err := r.ExtractInto(&s) - return s, err -} - -// CreateResult represents the result of a Create operation. Call its Extract -// method to interpret it as an Image. -type CreateResult struct { - commonResult -} - -// UpdateResult represents the result of an Update operation. Call its Extract -// method to interpret it as an Image. -type UpdateResult struct { - commonResult -} - -// GetResult represents the result of a Get operation. Call its Extract -// method to interpret it as an Image. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a Delete operation. Call its -// ExtractErr method to interpret it as an Image. -type DeleteResult struct { - eclcloud.ErrResult -} - -// ImagePage represents the results of a List request. -type ImagePage struct { - serviceURL string - pagination.LinkedPageBase -} - -// IsEmpty returns true if an ImagePage contains no Images results. -func (r ImagePage) IsEmpty() (bool, error) { - images, err := ExtractImages(r) - return len(images) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to -// the next page of results. -func (r ImagePage) NextPageURL() (string, error) { - var s struct { - Next string `json:"next"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - - if s.Next == "" { - return "", nil - } - - return nextPageURL(r.serviceURL, s.Next) -} - -// ExtractImages interprets the results of a single page from a List() call, -// producing a slice of Image entities. -func ExtractImages(r pagination.Page) ([]Image, error) { - var s struct { - Images []Image `json:"images"` - } - err := (r.(ImagePage)).ExtractInto(&s) - return s.Images, err -} diff --git a/v3/ecl/imagestorage/v2/images/testing/doc.go b/v3/ecl/imagestorage/v2/images/testing/doc.go deleted file mode 100644 index d4bd4f3..0000000 --- a/v3/ecl/imagestorage/v2/images/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains images unit tests -package testing diff --git a/v3/ecl/imagestorage/v2/images/testing/fixtures.go b/v3/ecl/imagestorage/v2/images/testing/fixtures.go deleted file mode 100644 index 1cb4411..0000000 --- a/v3/ecl/imagestorage/v2/images/testing/fixtures.go +++ /dev/null @@ -1,447 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "strconv" - "strings" - "testing" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -type imageEntry struct { - ID string - JSON string -} - -// HandleImageListSuccessfully test setup -func HandleImageListSuccessfully(t *testing.T) { - - images := make([]imageEntry, 3) - - images[0] = imageEntry{"cirros-0.3.4-x86_64-uec", - `{ - "status": "active", - "name": "cirros-0.3.4-x86_64-uec", - "tags": [], - "kernel_id": "e1b6edd4-bd9b-40ac-b010-8a6c16de4ba4", - "container_format": "ami", - "created_at": "2015-07-15T11:43:35Z", - "ramdisk_id": "8c64f48a-45a3-4eaa-adff-a8106b6c005b", - "disk_format": "ami", - "updated_at": "2015-07-15T11:43:35Z", - "visibility": "public", - "self": "/v2/images/07aa21a9-fa1a-430e-9a33-185be5982431", - "min_disk": 0, - "protected": false, - "id": "07aa21a9-fa1a-430e-9a33-185be5982431", - "size": 25165824, - "file": "/v2/images/07aa21a9-fa1a-430e-9a33-185be5982431/file", - "checksum": "eb9139e4942121f22bbc2afc0400b2a4", - "owner": "cba624273b8344e59dd1fd18685183b0", - "virtual_size": null, - "min_ram": 0, - "schema": "/v2/schemas/image", - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`} - images[1] = imageEntry{"cirros-0.3.4-x86_64-uec-ramdisk", - `{ - "status": "active", - "name": "cirros-0.3.4-x86_64-uec-ramdisk", - "tags": [], - "container_format": "ari", - "created_at": "2015-07-15T11:43:32Z", - "size": 3740163, - "disk_format": "ari", - "updated_at": "2015-07-15T11:43:32Z", - "visibility": "public", - "self": "/v2/images/8c64f48a-45a3-4eaa-adff-a8106b6c005b", - "min_disk": 0, - "protected": false, - "id": "8c64f48a-45a3-4eaa-adff-a8106b6c005b", - "file": "/v2/images/8c64f48a-45a3-4eaa-adff-a8106b6c005b/file", - "checksum": "be575a2b939972276ef675752936977f", - "owner": "cba624273b8344e59dd1fd18685183b0", - "virtual_size": null, - "min_ram": 0, - "schema": "/v2/schemas/image", - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`} - images[2] = imageEntry{"cirros-0.3.4-x86_64-uec-kernel", - `{ - "status": "active", - "name": "cirros-0.3.4-x86_64-uec-kernel", - "tags": [], - "container_format": "aki", - "created_at": "2015-07-15T11:43:29Z", - "size": 4979632, - "disk_format": "aki", - "updated_at": "2015-07-15T11:43:30Z", - "visibility": "public", - "self": "/v2/images/e1b6edd4-bd9b-40ac-b010-8a6c16de4ba4", - "min_disk": 0, - "protected": false, - "id": "e1b6edd4-bd9b-40ac-b010-8a6c16de4ba4", - "file": "/v2/images/e1b6edd4-bd9b-40ac-b010-8a6c16de4ba4/file", - "checksum": "8a40c862b5735975d82605c1dd395796", - "owner": "cba624273b8344e59dd1fd18685183b0", - "virtual_size": null, - "min_ram": 0, - "schema": "/v2/schemas/image", - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`} - - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - - w.WriteHeader(http.StatusOK) - - limit := 10 - var err error - if r.FormValue("limit") != "" { - limit, err = strconv.Atoi(r.FormValue("limit")) - if err != nil { - t.Errorf("Error value for 'limit' parameter %v (error: %v)", r.FormValue("limit"), err) - } - - } - - marker := "" - newMarker := "" - - if r.Form["marker"] != nil { - marker = r.Form["marker"][0] - } - - t.Logf("limit = %v marker = %v", limit, marker) - - selected := 0 - addNext := false - var imageJSON []string - - fmt.Fprintf(w, `{"images": [`) - - for _, i := range images { - if marker == "" || addNext { - t.Logf("Adding image %v to page", i.ID) - imageJSON = append(imageJSON, i.JSON) - newMarker = i.ID - selected++ - } else { - if strings.Contains(i.JSON, marker) { - addNext = true - } - } - - if selected == limit { - break - } - } - t.Logf("Writing out %v image(s)", len(imageJSON)) - fmt.Fprintf(w, strings.Join(imageJSON, ",")) - - fmt.Fprintf(w, `], - "next": "/images?marker=%s&limit=%v", - "schema": "/schemas/images", - "first": "/images?limit=%v"}`, newMarker, limit, limit) - - }) -} - -// HandleImageCreationSuccessfully test setup -func HandleImageCreationSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, `{ - "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "name": "Ubuntu 12.10", - "architecture": "x86_64", - "tags": [ - "ubuntu", - "quantal" - ] - }`) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "status": "queued", - "name": "Ubuntu 12.10", - "protected": false, - "tags": ["ubuntu","quantal"], - "container_format": "bare", - "created_at": "2014-11-11T20:47:55Z", - "disk_format": "qcow2", - "updated_at": "2014-11-11T20:47:55Z", - "visibility": "private", - "self": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "min_disk": 0, - "protected": false, - "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "file": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/file", - "owner": "b4eedccc6fb74fa8a7ad6b08382b852b", - "min_ram": 0, - "schema": "/v2/schemas/image", - "size": 0, - "checksum": "", - "virtual_size": 0, - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`) - }) -} - -// HandleImageCreationSuccessfullyNulls test setup -// JSON null values could be also returned according to behaviour https://bugs.launchpad.net/glance/+bug/1481512 -func HandleImageCreationSuccessfullyNulls(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, `{ - "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "architecture": "x86_64", - "name": "Ubuntu 12.10", - "tags": [ - "ubuntu", - "quantal" - ] - }`) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "architecture": "x86_64", - "status": "queued", - "name": "Ubuntu 12.10", - "protected": false, - "tags": ["ubuntu","quantal"], - "container_format": "bare", - "created_at": "2014-11-11T20:47:55Z", - "disk_format": "qcow2", - "updated_at": "2014-11-11T20:47:55Z", - "visibility": "private", - "self": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "min_disk": 0, - "protected": false, - "id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - "file": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/file", - "owner": "b4eedccc6fb74fa8a7ad6b08382b852b", - "min_ram": 0, - "schema": "/v2/schemas/image", - "size": null, - "checksum": null, - "virtual_size": null - }`) - }) -} - -// HandleImageGetSuccessfully test setup -func HandleImageGetSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "status": "active", - "name": "cirros-0.3.2-x86_64-disk", - "tags": [], - "container_format": "bare", - "created_at": "2014-05-05T17:15:10Z", - "disk_format": "qcow2", - "updated_at": "2014-05-05T17:15:11Z", - "visibility": "public", - "self": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", - "min_disk": 0, - "protected": false, - "id": "1bea47ed-f6a9-463b-b423-14b9cca9ad27", - "file": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27/file", - "checksum": "64d7c1cd2b6f60c92c14662941cb7913", - "owner": "5ef70662f8b34079a6eddb8da9d75fe8", - "size": 13167616, - "min_ram": 0, - "schema": "/v2/schemas/image", - "virtual_size": null, - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`) - }) -} - -// HandleImageDeleteSuccessfully test setup -func HandleImageDeleteSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleImageUpdateSuccessfully setup -func HandleImageUpdateSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - th.TestJSONRequest(t, r, `[ - { - "op": "replace", - "path": "/name", - "value": "Fedora 17" - }, - { - "op": "replace", - "path": "/tags", - "value": [ - "fedora", - "beefy" - ] - } - ]`) - - th.AssertEquals(t, "application/openstack-images-v2.1-json-patch", r.Header.Get("Content-Type")) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - "name": "Fedora 17", - "status": "active", - "visibility": "public", - "size": 2254249, - "checksum": "2cec138d7dae2aa59038ef8c9aec2390", - "tags": [ - "fedora", - "beefy" - ], - "created_at": "2012-08-10T19:23:50Z", - "updated_at": "2012-08-12T11:11:33Z", - "self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - "file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", - "schema": "/v2/schemas/image", - "owner": "", - "min_ram": 0, - "min_disk": 0, - "disk_format": "", - "virtual_size": 0, - "container_format": "", - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`) - }) -} - -// HandleImageListByTagsSuccessfully tests a list operation with tags. -func HandleImageListByTagsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, `{ - "images": [ - { - "status": "active", - "name": "cirros-0.3.2-x86_64-disk", - "tags": ["foo", "bar"], - "container_format": "bare", - "created_at": "2014-05-05T17:15:10Z", - "disk_format": "qcow2", - "updated_at": "2014-05-05T17:15:11Z", - "visibility": "public", - "self": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", - "min_disk": 0, - "protected": false, - "id": "1bea47ed-f6a9-463b-b423-14b9cca9ad27", - "file": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27/file", - "checksum": "64d7c1cd2b6f60c92c14662941cb7913", - "owner": "5ef70662f8b34079a6eddb8da9d75fe8", - "size": 13167616, - "min_ram": 0, - "schema": "/v2/schemas/image", - "virtual_size": null, - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - } - ] - }`) - }) -} - -// HandleImageUpdatePropertiesSuccessfully setup -func HandleImageUpdatePropertiesSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - th.TestJSONRequest(t, r, `[ - { - "op": "add", - "path": "/hw_disk_bus", - "value": "scsi" - }, - { - "op": "add", - "path": "/hw_disk_bus_model", - "value": "virtio-scsi" - }, - { - "op": "add", - "path": "/hw_scsi_model", - "value": "virtio-scsi" - } - ]`) - - th.AssertEquals(t, "application/openstack-images-v2.1-json-patch", r.Header.Get("Content-Type")) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - "name": "Fedora 17", - "status": "active", - "visibility": "public", - "size": 2254249, - "checksum": "2cec138d7dae2aa59038ef8c9aec2390", - "tags": [ - "fedora", - "beefy" - ], - "created_at": "2012-08-10T19:23:50Z", - "updated_at": "2012-08-12T11:11:33Z", - "self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - "file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", - "schema": "/v2/schemas/image", - "owner": "", - "min_ram": 0, - "min_disk": 0, - "disk_format": "", - "virtual_size": 0, - "container_format": "", - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi" - }`) - }) -} diff --git a/v3/ecl/imagestorage/v2/images/testing/requests_test.go b/v3/ecl/imagestorage/v2/images/testing/requests_test.go deleted file mode 100644 index 741cefd..0000000 --- a/v3/ecl/imagestorage/v2/images/testing/requests_test.go +++ /dev/null @@ -1,458 +0,0 @@ -package testing - -import ( - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/imagestorage/v2/images" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageListSuccessfully(t) - - t.Logf("Test setup %+v\n", th.Server) - - t.Logf("Id\tName\tOwner\tChecksum\tSizeBytes") - - pager := images.List(fakeclient.ServiceClient(), images.ListOpts{Limit: 1}) - t.Logf("Pager state %v", pager) - count, pages := 0, 0 - err := pager.EachPage(func(page pagination.Page) (bool, error) { - pages++ - t.Logf("Page %v", page) - images, err := images.ExtractImages(page) - if err != nil { - return false, err - } - - for _, i := range images { - t.Logf("%s\t%s\t%s\t%s\t%v\t\n", i.ID, i.Name, i.Owner, i.Checksum, i.SizeBytes) - count++ - } - - return true, nil - }) - th.AssertNoErr(t, err) - - t.Logf("--------\n%d images listed on %d pages.\n", count, pages) - th.AssertEquals(t, 3, pages) - th.AssertEquals(t, 3, count) -} - -func TestAllPagesImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageListSuccessfully(t) - - pages, err := images.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - images, err := images.ExtractImages(pages) - th.AssertNoErr(t, err) - th.AssertEquals(t, 3, len(images)) -} - -func TestCreateImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageCreationSuccessfully(t) - - id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" - name := "Ubuntu 12.10" - - actualImage, err := images.Create(fakeclient.ServiceClient(), images.CreateOpts{ - ID: id, - Name: name, - Properties: map[string]string{ - "architecture": "x86_64", - }, - Tags: []string{"ubuntu", "quantal"}, - }).Extract() - - th.AssertNoErr(t, err) - - containerFormat := "bare" - diskFormat := "qcow2" - owner := "b4eedccc6fb74fa8a7ad6b08382b852b" - minDiskGigabytes := 0 - minRAMMegabytes := 0 - file := actualImage.File - createdDate := actualImage.CreatedAt - lastUpdate := actualImage.UpdatedAt - schema := "/v2/schemas/image" - - expectedImage := images.Image{ - ID: "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - Name: "Ubuntu 12.10", - Tags: []string{"ubuntu", "quantal"}, - - Status: images.ImageStatusQueued, - - ContainerFormat: containerFormat, - DiskFormat: diskFormat, - - MinDiskGigabytes: minDiskGigabytes, - MinRAMMegabytes: minRAMMegabytes, - - Owner: owner, - - Visibility: images.ImageVisibilityPrivate, - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - VirtualSize: 0, - Properties: map[string]interface{}{ - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi", - }, - } - - th.AssertDeepEquals(t, &expectedImage, actualImage) -} - -func TestCreateImageNulls(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageCreationSuccessfullyNulls(t) - - id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd" - name := "Ubuntu 12.10" - - actualImage, err := images.Create(fakeclient.ServiceClient(), images.CreateOpts{ - ID: id, - Name: name, - Tags: []string{"ubuntu", "quantal"}, - Properties: map[string]string{ - "architecture": "x86_64", - }, - }).Extract() - - th.AssertNoErr(t, err) - - containerFormat := "bare" - diskFormat := "qcow2" - owner := "b4eedccc6fb74fa8a7ad6b08382b852b" - minDiskGigabytes := 0 - minRAMMegabytes := 0 - file := actualImage.File - createdDate := actualImage.CreatedAt - lastUpdate := actualImage.UpdatedAt - schema := "/v2/schemas/image" - properties := map[string]interface{}{ - "architecture": "x86_64", - } - sizeBytes := int64(0) - - expectedImage := images.Image{ - ID: "e7db3b45-8db7-47ad-8109-3fb55c2c24fd", - Name: "Ubuntu 12.10", - Tags: []string{"ubuntu", "quantal"}, - - Status: images.ImageStatusQueued, - - ContainerFormat: containerFormat, - DiskFormat: diskFormat, - - MinDiskGigabytes: minDiskGigabytes, - MinRAMMegabytes: minRAMMegabytes, - - Owner: owner, - - Visibility: images.ImageVisibilityPrivate, - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - Properties: properties, - SizeBytes: sizeBytes, - } - - th.AssertDeepEquals(t, &expectedImage, actualImage) -} - -func TestGetImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageGetSuccessfully(t) - - actualImage, err := images.Get(fakeclient.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27").Extract() - - th.AssertNoErr(t, err) - - checksum := "64d7c1cd2b6f60c92c14662941cb7913" - sizeBytes := int64(13167616) - containerFormat := "bare" - diskFormat := "qcow2" - minDiskGigabytes := 0 - minRAMMegabytes := 0 - owner := "5ef70662f8b34079a6eddb8da9d75fe8" - file := actualImage.File - createdDate := actualImage.CreatedAt - lastUpdate := actualImage.UpdatedAt - schema := "/v2/schemas/image" - - expectedImage := images.Image{ - ID: "1bea47ed-f6a9-463b-b423-14b9cca9ad27", - Name: "cirros-0.3.2-x86_64-disk", - Tags: []string{}, - - Status: images.ImageStatusActive, - - ContainerFormat: containerFormat, - DiskFormat: diskFormat, - - MinDiskGigabytes: minDiskGigabytes, - MinRAMMegabytes: minRAMMegabytes, - - Owner: owner, - - Protected: false, - Visibility: images.ImageVisibilityPublic, - - Checksum: checksum, - SizeBytes: sizeBytes, - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - VirtualSize: 0, - Properties: map[string]interface{}{ - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi", - }, - } - - th.AssertDeepEquals(t, &expectedImage, actualImage) -} - -func TestDeleteImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageDeleteSuccessfully(t) - - result := images.Delete(fakeclient.ServiceClient(), "1bea47ed-f6a9-463b-b423-14b9cca9ad27") - th.AssertNoErr(t, result.Err) -} - -func TestUpdateImage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageUpdateSuccessfully(t) - - actualImage, err := images.Update(fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ - images.ReplaceImageName{NewName: "Fedora 17"}, - images.ReplaceImageTags{NewTags: []string{"fedora", "beefy"}}, - }).Extract() - - th.AssertNoErr(t, err) - - sizebytes := int64(2254249) - checksum := "2cec138d7dae2aa59038ef8c9aec2390" - file := actualImage.File - createdDate := actualImage.CreatedAt - lastUpdate := actualImage.UpdatedAt - schema := "/v2/schemas/image" - - expectedImage := images.Image{ - ID: "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - Name: "Fedora 17", - Status: images.ImageStatusActive, - Visibility: images.ImageVisibilityPublic, - - SizeBytes: sizebytes, - Checksum: checksum, - - Tags: []string{ - "fedora", - "beefy", - }, - - Owner: "", - MinRAMMegabytes: 0, - MinDiskGigabytes: 0, - - DiskFormat: "", - ContainerFormat: "", - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - VirtualSize: 0, - Properties: map[string]interface{}{ - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi", - }, - } - - th.AssertDeepEquals(t, &expectedImage, actualImage) -} - -func TestImageDateQuery(t *testing.T) { - date := time.Date(2014, 1, 1, 1, 1, 1, 0, time.UTC) - - listOpts := images.ListOpts{ - CreatedAtQuery: &images.ImageDateQuery{ - Date: date, - Filter: images.FilterGTE, - }, - UpdatedAtQuery: &images.ImageDateQuery{ - Date: date, - }, - } - - expectedQueryString := "?created_at=gte%3A2014-01-01T01%3A01%3A01Z&updated_at=2014-01-01T01%3A01%3A01Z" - actualQueryString, err := listOpts.ToImageListQuery() - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedQueryString, actualQueryString) -} - -func TestImageListByTags(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageListByTagsSuccessfully(t) - - listOpts := images.ListOpts{ - Tags: []string{"foo", "bar"}, - } - - expectedQueryString := "?tag=foo&tag=bar" - actualQueryString, err := listOpts.ToImageListQuery() - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedQueryString, actualQueryString) - - pages, err := images.List(fakeclient.ServiceClient(), listOpts).AllPages() - th.AssertNoErr(t, err) - allImages, err := images.ExtractImages(pages) - th.AssertNoErr(t, err) - - checksum := "64d7c1cd2b6f60c92c14662941cb7913" - sizeBytes := int64(13167616) - containerFormat := "bare" - diskFormat := "qcow2" - minDiskGigabytes := 0 - minRAMMegabytes := 0 - owner := "5ef70662f8b34079a6eddb8da9d75fe8" - file := allImages[0].File - createdDate := allImages[0].CreatedAt - lastUpdate := allImages[0].UpdatedAt - schema := "/v2/schemas/image" - tags := []string{"foo", "bar"} - - expectedImage := images.Image{ - ID: "1bea47ed-f6a9-463b-b423-14b9cca9ad27", - Name: "cirros-0.3.2-x86_64-disk", - Tags: tags, - - Status: images.ImageStatusActive, - - ContainerFormat: containerFormat, - DiskFormat: diskFormat, - - MinDiskGigabytes: minDiskGigabytes, - MinRAMMegabytes: minRAMMegabytes, - - Owner: owner, - - Protected: false, - Visibility: images.ImageVisibilityPublic, - - Checksum: checksum, - SizeBytes: sizeBytes, - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - VirtualSize: 0, - Properties: map[string]interface{}{ - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi", - }, - } - - th.AssertDeepEquals(t, expectedImage, allImages[0]) -} - -func TestUpdateImageProperties(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageUpdatePropertiesSuccessfully(t) - - actualImage, err := images.Update(fakeclient.ServiceClient(), "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", images.UpdateOpts{ - images.UpdateImageProperty{ - Op: images.AddOp, - Name: "hw_disk_bus", - Value: "scsi", - }, - images.UpdateImageProperty{ - Op: images.AddOp, - Name: "hw_disk_bus_model", - Value: "virtio-scsi", - }, - images.UpdateImageProperty{ - Op: images.AddOp, - Name: "hw_scsi_model", - Value: "virtio-scsi", - }, - }).Extract() - - th.AssertNoErr(t, err) - - sizebytes := int64(2254249) - checksum := "2cec138d7dae2aa59038ef8c9aec2390" - file := actualImage.File - createdDate := actualImage.CreatedAt - lastUpdate := actualImage.UpdatedAt - schema := "/v2/schemas/image" - - expectedImage := images.Image{ - ID: "da3b75d9-3f4a-40e7-8a2c-bfab23927dea", - Name: "Fedora 17", - Status: images.ImageStatusActive, - Visibility: images.ImageVisibilityPublic, - - SizeBytes: sizebytes, - Checksum: checksum, - - Tags: []string{ - "fedora", - "beefy", - }, - - Owner: "", - MinRAMMegabytes: 0, - MinDiskGigabytes: 0, - - DiskFormat: "", - ContainerFormat: "", - File: file, - CreatedAt: createdDate, - UpdatedAt: lastUpdate, - Schema: schema, - VirtualSize: 0, - Properties: map[string]interface{}{ - "hw_disk_bus": "scsi", - "hw_disk_bus_model": "virtio-scsi", - "hw_scsi_model": "virtio-scsi", - }, - } - - th.AssertDeepEquals(t, &expectedImage, actualImage) -} diff --git a/v3/ecl/imagestorage/v2/images/types.go b/v3/ecl/imagestorage/v2/images/types.go deleted file mode 100644 index 5005b34..0000000 --- a/v3/ecl/imagestorage/v2/images/types.go +++ /dev/null @@ -1,101 +0,0 @@ -package images - -import ( - "time" -) - -// ImageStatus image statuses -type ImageStatus string - -const ( - // ImageStatusQueued is a status for an image which identifier has - // been reserved for an image in the image registry. - ImageStatusQueued ImageStatus = "queued" - - // ImageStatusSaving denotes that an image’s raw data is currently being - // uploaded to Glance - ImageStatusSaving ImageStatus = "saving" - - // ImageStatusActive denotes an image that is fully available in Glance. - ImageStatusActive ImageStatus = "active" - - // ImageStatusKilled denotes that an error occurred during the uploading - // of an image’s data, and that the image is not readable. - ImageStatusKilled ImageStatus = "killed" - - // ImageStatusDeleted is used for an image that is no longer available to use. - // The image information is retained in the image registry. - ImageStatusDeleted ImageStatus = "deleted" - - // ImageStatusPendingDelete is similar to Delete, but the image is not yet - // deleted. - ImageStatusPendingDelete ImageStatus = "pending_delete" - - // ImageStatusDeactivated denotes that access to image data is not allowed to - // any non-admin user. - ImageStatusDeactivated ImageStatus = "deactivated" -) - -// ImageVisibility denotes an image that is fully available in Glance. -// This occurs when the image data is uploaded, or the image size is explicitly -// set to zero on creation. -type ImageVisibility string - -const ( - // ImageVisibilityPublic all users - ImageVisibilityPublic ImageVisibility = "public" - - // ImageVisibilityPrivate users with tenantId == tenantId(owner) - ImageVisibilityPrivate ImageVisibility = "private" - - // ImageVisibilityShared images are visible to: - // - users with tenantId == tenantId(owner) - // - users with tenantId in the member-list of the image - // - users with tenantId in the member-list with member_status == 'accepted' - ImageVisibilityShared ImageVisibility = "shared" - - // ImageVisibilityCommunity images: - // - all users can see and boot it - // - users with tenantId in the member-list of the image with - // member_status == 'accepted' have this image in their default image-list. - ImageVisibilityCommunity ImageVisibility = "community" -) - -// MemberStatus is a status for adding a new member (tenant) to an image -// member list. -type ImageMemberStatus string - -const ( - // ImageMemberStatusAccepted is the status for an accepted image member. - ImageMemberStatusAccepted ImageMemberStatus = "accepted" - - // ImageMemberStatusPending shows that the member addition is pending - ImageMemberStatusPending ImageMemberStatus = "pending" - - // ImageMemberStatusAccepted is the status for a rejected image member - ImageMemberStatusRejected ImageMemberStatus = "rejected" - - // ImageMemberStatusAll - ImageMemberStatusAll ImageMemberStatus = "all" -) - -// ImageDateFilter represents a valid filter to use for filtering -// images by their date during a List. -type ImageDateFilter string - -const ( - FilterGT ImageDateFilter = "gt" - FilterGTE ImageDateFilter = "gte" - FilterLT ImageDateFilter = "lt" - FilterLTE ImageDateFilter = "lte" - FilterNEQ ImageDateFilter = "neq" - FilterEQ ImageDateFilter = "eq" -) - -// ImageDateQuery represents a date field to be used for listing images. -// If no filter is specified, the query will act as though FilterEQ was -// set. -type ImageDateQuery struct { - Date time.Time - Filter ImageDateFilter -} diff --git a/v3/ecl/imagestorage/v2/images/urls.go b/v3/ecl/imagestorage/v2/images/urls.go deleted file mode 100644 index ecc40e4..0000000 --- a/v3/ecl/imagestorage/v2/images/urls.go +++ /dev/null @@ -1,64 +0,0 @@ -package images - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/utils" - "net/url" - "strings" -) - -// `listURL` is a pure function. `listURL(c)` is a URL for which a GET -// request will respond with a list of images in the service `c`. -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("images") -} - -func createURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("images") -} - -// `imageURL(c,i)` is the URL for the image identified by ID `i` in -// the service `c`. -func imageURL(c *eclcloud.ServiceClient, imageID string) string { - return c.ServiceURL("images", imageID) -} - -// `getURL(c,i)` is a URL for which a GET request will respond with -// information about the image identified by ID `i` in the service -// `c`. -func getURL(c *eclcloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -func updateURL(c *eclcloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -func deleteURL(c *eclcloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -// builds next page full url based on current url -func nextPageURL(serviceURL, requestedNext string) (string, error) { - base, err := utils.BaseEndpoint(serviceURL) - if err != nil { - return "", err - } - - requestedNextURL, err := url.Parse(requestedNext) - if err != nil { - return "", err - } - - base = eclcloud.NormalizeURL(base) - nextPath := base + strings.TrimPrefix(requestedNextURL.Path, "/") - - nextURL, err := url.Parse(nextPath) - if err != nil { - return "", err - } - - nextURL.RawQuery = requestedNextURL.RawQuery - - return nextURL.String(), nil -} diff --git a/v3/ecl/imagestorage/v2/members/doc.go b/v3/ecl/imagestorage/v2/members/doc.go deleted file mode 100644 index acb4272..0000000 --- a/v3/ecl/imagestorage/v2/members/doc.go +++ /dev/null @@ -1 +0,0 @@ -package members diff --git a/v3/ecl/imagestorage/v2/members/requests.go b/v3/ecl/imagestorage/v2/members/requests.go deleted file mode 100644 index 753b682..0000000 --- a/v3/ecl/imagestorage/v2/members/requests.go +++ /dev/null @@ -1,80 +0,0 @@ -package members - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -/* - Create member for specific image - - Preconditions - - * The specified images must exist. - * You can only add a new member to an image which 'visibility' attribute is - private. - * You must be the owner of the specified image. - - Synchronous Postconditions - - With correct permissions, you can see the member status of the image as - pending through API calls. - -*/ - -func Create(client *eclcloud.ServiceClient, id string, member string) (r CreateResult) { - b := map[string]interface{}{"member": member} - _, r.Err = client.Post(createMemberURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// List members returns list of members for specifed image id. -func List(client *eclcloud.ServiceClient, id string) pagination.Pager { - return pagination.NewPager(client, listMembersURL(client, id), func(r pagination.PageResult) pagination.Page { - return MemberPage{pagination.SinglePageBase(r)} - }) -} - -// Get image member details. -func Get(client *eclcloud.ServiceClient, imageID string, memberID string) (r DetailsResult) { - _, r.Err = client.Get(getMemberURL(client, imageID, memberID), &r.Body, &eclcloud.RequestOpts{OkCodes: []int{200}}) - return -} - -// Delete membership for given image. Callee should be image owner. -func Delete(client *eclcloud.ServiceClient, imageID string, memberID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteMemberURL(client, imageID, memberID), &eclcloud.RequestOpts{OkCodes: []int{204}}) - return -} - -// UpdateOptsBuilder allows extensions to add additional attributes to the -// Update request. -type UpdateOptsBuilder interface { - ToImageMemberUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents options to an Update request. -type UpdateOpts struct { - Status string `json:"status,omitempty" required:"true1"` -} - -// ToMemberUpdateMap formats an UpdateOpts structure into a request body. -func (opts UpdateOpts) ToImageMemberUpdateMap() (map[string]interface{}, error) { - return map[string]interface{}{ - "status": opts.Status, - }, nil -} - -// Update function updates member. -func Update(client *eclcloud.ServiceClient, imageID string, memberID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToImageMemberUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateMemberURL(client, imageID, memberID), b, &r.Body, - &eclcloud.RequestOpts{OkCodes: []int{200}}) - return -} diff --git a/v3/ecl/imagestorage/v2/members/results.go b/v3/ecl/imagestorage/v2/members/results.go deleted file mode 100644 index a033264..0000000 --- a/v3/ecl/imagestorage/v2/members/results.go +++ /dev/null @@ -1,74 +0,0 @@ -package members - -import ( - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Member represents a member of an Image. -type Member struct { - CreatedAt time.Time `json:"created_at"` - ImageID string `json:"image_id"` - MemberID string `json:"member_id"` - Schema string `json:"schema"` - Status string `json:"status"` - UpdatedAt time.Time `json:"updated_at"` -} - -// Extract Member model from a request. -func (r commonResult) Extract() (*Member, error) { - var s *Member - err := r.ExtractInto(&s) - return s, err -} - -// MemberPage is a single page of Members results. -type MemberPage struct { - pagination.SinglePageBase -} - -// ExtractMembers returns a slice of Members contained in a single page -// of results. -func ExtractMembers(r pagination.Page) ([]Member, error) { - var s struct { - Members []Member `json:"members"` - } - err := r.(MemberPage).ExtractInto(&s) - return s.Members, err -} - -// IsEmpty determines whether or not a MemberPage contains any results. -func (r MemberPage) IsEmpty() (bool, error) { - members, err := ExtractMembers(r) - return len(members) == 0, err -} - -type commonResult struct { - eclcloud.Result -} - -// CreateResult represents the result of a Create operation. Call its Extract -// method to interpret it as a Member. -type CreateResult struct { - commonResult -} - -// DetailsResult represents the result of a Get operation. Call its Extract -// method to interpret it as a Member. -type DetailsResult struct { - commonResult -} - -// UpdateResult represents the result of an Update operation. Call its Extract -// method to interpret it as a Member. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a Delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/imagestorage/v2/members/testing/doc.go b/v3/ecl/imagestorage/v2/members/testing/doc.go deleted file mode 100644 index 1afbc43..0000000 --- a/v3/ecl/imagestorage/v2/members/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// members unit tests -package testing diff --git a/v3/ecl/imagestorage/v2/members/testing/fixtures.go b/v3/ecl/imagestorage/v2/members/testing/fixtures.go deleted file mode 100644 index 69df704..0000000 --- a/v3/ecl/imagestorage/v2/members/testing/fixtures.go +++ /dev/null @@ -1,138 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// HandleCreateImageMemberSuccessfully setup -func HandleCreateImageMemberSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - th.TestJSONRequest(t, r, `{"member": "f6a818c3d4aa458798ed86892e7150c0"}`) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "created_at": "2013-09-20T19:22:19Z", - "image_id": "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "member_id": "f6a818c3d4aa458798ed86892e7150c0", - "schema": "/v2/schemas/member", - "status": "pending", - "updated_at": "2013-09-20T19:25:31Z" - }`) - - }) -} - -// HandleImageMemberList happy path setup -func HandleImageMemberList(t *testing.T) { - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "members": [ - { - "created_at": "2013-10-07T17:58:03Z", - "image_id": "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "member_id": "f6a818c3d4aa458798ed86892e7150c0", - "schema": "/v2/schemas/member", - "status": "pending", - "updated_at": "2013-10-07T17:58:03Z" - }, - { - "created_at": "2013-10-07T17:58:55Z", - "image_id": "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "member_id": "1efb79fe4437490aab966b57da5b9f05", - "schema": "/v2/schemas/member", - "status": "accepted", - "updated_at": "2013-10-08T12:08:55Z" - } - ], - "schema": "/v2/schemas/members" - }`) - }) -} - -// HandleImageMemberEmptyList happy path setup -func HandleImageMemberEmptyList(t *testing.T) { - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ - "members": [], - "schema": "/v2/schemas/members" - }`) - }) -} - -// HandleImageMemberDetails setup -func HandleImageMemberDetails(t *testing.T) { - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members/f6a818c3d4aa458798ed86892e7150c0", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{ - "status": "pending", - "created_at": "2013-11-26T07:21:21Z", - "updated_at": "2013-11-26T07:21:21Z", - "image_id": "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "member_id": "f6a818c3d4aa458798ed86892e7150c0", - "schema": "/v2/schemas/member" - }`) - }) -} - -// HandleImageMemberDeleteSuccessfully setup -func HandleImageMemberDeleteSuccessfully(t *testing.T) *CallsCounter { - var counter CallsCounter - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members/f6a818c3d4aa458798ed86892e7150c0", func(w http.ResponseWriter, r *http.Request) { - counter.Counter = counter.Counter + 1 - - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - return &counter -} - -// HandleImageMemberUpdate setup -func HandleImageMemberUpdate(t *testing.T) *CallsCounter { - var counter CallsCounter - th.Mux.HandleFunc("/images/54d63e39-4ee1-4a62-8704-0ae5025a0deb/members/f6a818c3d4aa458798ed86892e7150c0", func(w http.ResponseWriter, r *http.Request) { - counter.Counter = counter.Counter + 1 - - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - th.TestJSONRequest(t, r, `{"status": "accepted"}`) - - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, `{ - "status": "accepted", - "created_at": "2013-11-26T07:21:21Z", - "updated_at": "2013-11-26T07:21:21Z", - "image_id": "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "member_id": "f6a818c3d4aa458798ed86892e7150c0", - "schema": "/v2/schemas/member" - }`) - }) - return &counter -} - -// CallsCounter for checking if request handler was called at all -type CallsCounter struct { - Counter int -} diff --git a/v3/ecl/imagestorage/v2/members/testing/requests_test.go b/v3/ecl/imagestorage/v2/members/testing/requests_test.go deleted file mode 100644 index 9cb05f9..0000000 --- a/v3/ecl/imagestorage/v2/members/testing/requests_test.go +++ /dev/null @@ -1,172 +0,0 @@ -package testing - -import ( - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/imagestorage/v2/members" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -const createdAtString = "2013-09-20T19:22:19Z" -const updatedAtString = "2013-09-20T19:25:31Z" - -func TestCreateMemberSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleCreateImageMemberSuccessfully(t) - im, err := members.Create(fakeclient.ServiceClient(), "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "f6a818c3d4aa458798ed86892e7150c0").Extract() - th.AssertNoErr(t, err) - - createdAt, err := time.Parse(time.RFC3339, createdAtString) - th.AssertNoErr(t, err) - - updatedAt, err := time.Parse(time.RFC3339, updatedAtString) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, members.Member{ - CreatedAt: createdAt, - ImageID: "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - MemberID: "f6a818c3d4aa458798ed86892e7150c0", - Schema: "/v2/schemas/member", - Status: "pending", - UpdatedAt: updatedAt, - }, *im) - -} - -func TestMemberListSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageMemberList(t) - - pager := members.List(fakeclient.ServiceClient(), "54d63e39-4ee1-4a62-8704-0ae5025a0deb") - t.Logf("Pager state %v", pager) - count, pages := 0, 0 - err := pager.EachPage(func(page pagination.Page) (bool, error) { - pages++ - t.Logf("Page %v", page) - members, err := members.ExtractMembers(page) - if err != nil { - return false, err - } - - for _, i := range members { - t.Logf("%s\t%s\t%s\t%s\t\n", i.ImageID, i.MemberID, i.Status, i.Schema) - count++ - } - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 1, pages) - th.AssertEquals(t, 2, count) -} - -func TestMemberListEmpty(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageMemberEmptyList(t) - - pager := members.List(fakeclient.ServiceClient(), "54d63e39-4ee1-4a62-8704-0ae5025a0deb") - t.Logf("Pager state %v", pager) - count, pages := 0, 0 - err := pager.EachPage(func(page pagination.Page) (bool, error) { - pages++ - t.Logf("Page %v", page) - members, err := members.ExtractMembers(page) - if err != nil { - return false, err - } - - for _, i := range members { - t.Logf("%s\t%s\t%s\t%s\t\n", i.ImageID, i.MemberID, i.Status, i.Schema) - count++ - } - - return true, nil - }) - - th.AssertNoErr(t, err) - th.AssertEquals(t, 0, pages) - th.AssertEquals(t, 0, count) -} - -func TestShowMemberDetails(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - HandleImageMemberDetails(t) - md, err := members.Get(fakeclient.ServiceClient(), - "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "f6a818c3d4aa458798ed86892e7150c0").Extract() - - th.AssertNoErr(t, err) - if md == nil { - t.Errorf("Expected non-nil value for md") - } - - createdAt, err := time.Parse(time.RFC3339, "2013-11-26T07:21:21Z") - th.AssertNoErr(t, err) - - updatedAt, err := time.Parse(time.RFC3339, "2013-11-26T07:21:21Z") - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, members.Member{ - CreatedAt: createdAt, - ImageID: "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - MemberID: "f6a818c3d4aa458798ed86892e7150c0", - Schema: "/v2/schemas/member", - Status: "pending", - UpdatedAt: updatedAt, - }, *md) -} - -func TestDeleteMember(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - counter := HandleImageMemberDeleteSuccessfully(t) - - result := members.Delete(fakeclient.ServiceClient(), "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "f6a818c3d4aa458798ed86892e7150c0") - th.AssertEquals(t, 1, counter.Counter) - th.AssertNoErr(t, result.Err) -} - -func TestMemberUpdateSuccessfully(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - counter := HandleImageMemberUpdate(t) - im, err := members.Update(fakeclient.ServiceClient(), "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - "f6a818c3d4aa458798ed86892e7150c0", - members.UpdateOpts{ - Status: "accepted", - }).Extract() - th.AssertEquals(t, 1, counter.Counter) - th.AssertNoErr(t, err) - - createdAt, err := time.Parse(time.RFC3339, "2013-11-26T07:21:21Z") - th.AssertNoErr(t, err) - - updatedAt, err := time.Parse(time.RFC3339, "2013-11-26T07:21:21Z") - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, members.Member{ - CreatedAt: createdAt, - ImageID: "54d63e39-4ee1-4a62-8704-0ae5025a0deb", - MemberID: "f6a818c3d4aa458798ed86892e7150c0", - Schema: "/v2/schemas/member", - Status: "accepted", - UpdatedAt: updatedAt, - }, *im) - -} diff --git a/v3/ecl/imagestorage/v2/members/urls.go b/v3/ecl/imagestorage/v2/members/urls.go deleted file mode 100644 index 53a92c6..0000000 --- a/v3/ecl/imagestorage/v2/members/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package members - -import "github.com/nttcom/eclcloud/v3" - -func imageMembersURL(c *eclcloud.ServiceClient, imageID string) string { - return c.ServiceURL("images", imageID, "members") -} - -func listMembersURL(c *eclcloud.ServiceClient, imageID string) string { - return imageMembersURL(c, imageID) -} - -func createMemberURL(c *eclcloud.ServiceClient, imageID string) string { - return imageMembersURL(c, imageID) -} - -func imageMemberURL(c *eclcloud.ServiceClient, imageID string, memberID string) string { - return c.ServiceURL("images", imageID, "members", memberID) -} - -func getMemberURL(c *eclcloud.ServiceClient, imageID string, memberID string) string { - return imageMemberURL(c, imageID, memberID) -} - -func updateMemberURL(c *eclcloud.ServiceClient, imageID string, memberID string) string { - return imageMemberURL(c, imageID, memberID) -} - -func deleteMemberURL(c *eclcloud.ServiceClient, imageID string, memberID string) string { - return imageMemberURL(c, imageID, memberID) -} diff --git a/v3/ecl/managed_load_balancer/v1/certificates/requests.go b/v3/ecl/managed_load_balancer/v1/certificates/requests.go index eb3b635..01a34b4 100644 --- a/v3/ecl/managed_load_balancer/v1/certificates/requests.go +++ b/v3/ecl/managed_load_balancer/v1/certificates/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - ID of the owner tenant of the resource @@ -77,13 +79,17 @@ Create Certificate type CreateOpts struct { // - Name of the certificate + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the certificate + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the certificate - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` } @@ -134,13 +140,17 @@ Update Certificate type UpdateOpts struct { // - Name of the certificate + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the certificate + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the certificate - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -195,9 +205,9 @@ type UploadFileOpts struct { Type string `json:"type"` // - Content of the certificate file to be uploaded - // - Size of the file before encoding by Base64 must be less than or equal to 16KB - // - Must be specified the content of the file that encoded by Base64 format - // - Format of the file before encoding by Base64 must be PEM + // - Content must be Base64 encoded + // - The file size before encoding must be less than or equal to 16KB + // - The file format before encoding must be PEM // - DER can be converted to PEM by using OpenSSL command Content string `json:"content"` } diff --git a/v3/ecl/managed_load_balancer/v1/health_monitors/requests.go b/v3/ecl/managed_load_balancer/v1/health_monitors/requests.go index e735b49..74c475f 100644 --- a/v3/ecl/managed_load_balancer/v1/health_monitors/requests.go +++ b/v3/ecl/managed_load_balancer/v1/health_monitors/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -100,17 +102,21 @@ Create Health Monitor type CreateOpts struct { // - Name of the health monitor + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the health monitor + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the health monitor - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port int `json:"port"` // - Protocol of the health monitor for healthchecking @@ -121,20 +127,22 @@ type CreateOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` @@ -175,7 +183,7 @@ Show Health Monitor // ShowOpts represents options used to show a health monitor. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -215,13 +223,17 @@ Update Health Monitor Attributes type UpdateOpts struct { // - Name of the health monitor + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the health monitor + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the health monitor - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -272,7 +284,7 @@ Create Staged Health Monitor Configurations type CreateStagedOpts struct { // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -283,20 +295,22 @@ type CreateStagedOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` } @@ -348,7 +362,7 @@ Update Staged Health Monitor Configurations type UpdateStagedOpts struct { // - Port number of the health monitor for healthchecking - // - Must be specified `0` when `protocol` is `"icmp"` + // - If 'protocol' is 'icmp', value must be set `0` Port *int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -359,20 +373,22 @@ type UpdateStagedOpts struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry *int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) - // - Must be specified a number less than or equal to `interval` + // - Value must be less than or equal to `interval` Timeout *int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Can be specified path to monitor when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, URL path can be set + // - If `protocol` is neither `"http"` nor `"https"`, URL path must not be set // - Must be started with / Path *string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Can be specified HTTP status code (or range) when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, HTTP status code (or range) can be set + // - If `protocol` is neither `"http"` nor `"https"`, HTTP status code (or range) must not be set // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode *string `json:"http_status_code,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/health_monitors/results.go b/v3/ecl/managed_load_balancer/v1/health_monitors/results.go index 3a7a2df..d89a301 100644 --- a/v3/ecl/managed_load_balancer/v1/health_monitors/results.go +++ b/v3/ecl/managed_load_balancer/v1/health_monitors/results.go @@ -64,7 +64,7 @@ type CancelStagedResult struct { type ConfigurationInResponse struct { // - Port number of the health monitor for healthchecking - // - Returns `0` when `protocol` is `"icmp"` + // - If `protocol` is `"icmp"`, returns `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -75,18 +75,18 @@ type ConfigurationInResponse struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` } @@ -144,7 +144,7 @@ type HealthMonitor struct { TenantID string `json:"tenant_id"` // - Port number of the health monitor for healthchecking - // - Returns `0` when `protocol` is `"icmp"` + // - If `protocol` is `"icmp"`, returns `0` Port int `json:"port,omitempty"` // - Protocol of the health monitor for healthchecking @@ -155,29 +155,29 @@ type HealthMonitor struct { // - Retry count of healthchecking // - Initial monitoring is not included - // - Retry is executed at the interval specified by `interval` + // - Retry is executed at the interval set in `interval` Retry int `json:"retry,omitempty"` // - Timeout of healthchecking (in seconds) Timeout int `json:"timeout,omitempty"` // - URL path of healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter Path string `json:"path,omitempty"` // - HTTP status codes expected in healthchecking - // - Used when `protocol` is `"http"` or `"https"` + // - If `protocol` is `"http"` or `"https"`, uses this parameter // - Format: `"xxx"` or `"xxx-xxx"` ( `xxx` between [100, 599]) HttpStatusCode string `json:"http_status_code,omitempty"` // - Running configurations of the health monitor - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the health monitor that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/listeners/requests.go b/v3/ecl/managed_load_balancer/v1/listeners/requests.go index fa60b0d..193d212 100644 --- a/v3/ecl/managed_load_balancer/v1/listeners/requests.go +++ b/v3/ecl/managed_load_balancer/v1/listeners/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -86,22 +88,27 @@ Create Listener type CreateOpts struct { // - Name of the listener + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the listener + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the listener - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port int `json:"port"` // - Protocol of the listener for listening @@ -144,7 +151,7 @@ Show Listener // ShowOpts represents options used to show a listener. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -184,13 +191,17 @@ Update Listener Attribute type UpdateOpts struct { // - Name of the listener + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the listener + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the listener - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -241,12 +252,13 @@ Create Staged Listener Configurations type CreateStagedOpts struct { // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address,omitempty"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port int `json:"port,omitempty"` // - Protocol of the listener for listening @@ -300,12 +312,13 @@ Update Staged Listener Configurations type UpdateStagedOpts struct { // - IP address of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer - // - Must be specified the ip address which is not included in subnet of load balancer interfaces that the listener belongs to + // - Set an unique combination of IP address and port in all listeners which belong to the same load balancer + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the listener belongs to + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address,omitempty"` // - Port number of the listener for listening - // - Must be specified the unique combination of ip address and port in all listeners belongs to the same load balancer + // - Combination of IP address and port must be unique for all listeners which belong to the same load balancer Port *int `json:"port,omitempty"` // - Protocol of the listener for listening diff --git a/v3/ecl/managed_load_balancer/v1/listeners/results.go b/v3/ecl/managed_load_balancer/v1/listeners/results.go index c2f2807..2b27ee1 100644 --- a/v3/ecl/managed_load_balancer/v1/listeners/results.go +++ b/v3/ecl/managed_load_balancer/v1/listeners/results.go @@ -135,13 +135,13 @@ type Listener struct { Protocol string `json:"protocol,omitempty"` // - Running configurations of the listener - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the listener that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/load_balancers/requests.go b/v3/ecl/managed_load_balancer/v1/load_balancers/requests.go index 4ee009d..cda93f5 100644 --- a/v3/ecl/managed_load_balancer/v1/load_balancers/requests.go +++ b/v3/ecl/managed_load_balancer/v1/load_balancers/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -93,8 +95,9 @@ type CreateOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` } @@ -102,20 +105,19 @@ type CreateOptsReservedFixedIP struct { type CreateOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces ReservedFixedIPs *[]CreateOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -130,7 +132,7 @@ type CreateOptsSyslogServer struct { Port int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol string `json:"protocol,omitempty"` } @@ -138,25 +140,30 @@ type CreateOptsSyslogServer struct { type CreateOpts struct { // - Name of the load balancer + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the load balancer + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the load balancer - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - ID of the plan PlanID string `json:"plan_id,omitempty"` // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]CreateOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -198,7 +205,7 @@ Show Load Balancer // ShowOpts represents options used to show a load balancer. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -238,13 +245,17 @@ Update Load Balancer Attributes type UpdateOpts struct { // - Name of the load balancer + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the load balancer + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the load balancer - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -353,8 +364,9 @@ type CreateStagedOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` } @@ -362,20 +374,21 @@ type CreateStagedOptsReservedFixedIP struct { type CreateStagedOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `virtual_ip_address` value + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `reserved_fixed_ips` value ReservedFixedIPs *[]CreateStagedOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -390,7 +403,7 @@ type CreateStagedOptsSyslogServer struct { Port int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol string `json:"protocol,omitempty"` } @@ -398,12 +411,13 @@ type CreateStagedOptsSyslogServer struct { type CreateStagedOpts struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]CreateStagedOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -460,8 +474,9 @@ type UpdateStagedOptsReservedFixedIP struct { // - The IP address assign to this interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address"` } @@ -469,20 +484,21 @@ type UpdateStagedOptsReservedFixedIP struct { type UpdateStagedOptsInterface struct { // - ID of the network that this interface belongs to - // - Must be specified the unique network ID in `interfaces` - // - Must be specified the network that plane is data - // - Must not be specified the network that uses ISP shared address (RFC 6598) + // - Set a unique network ID in `interfaces` + // - Set a network of which plane is data + // - Must not set ID of a network that uses ISP shared address (RFC 6598) NetworkID *string `json:"network_id"` // - Virtual IP address of the interface within subnet // - Do not use this IP address at the interface of other devices, allowed address pairs, etc - // - Must be specified the unique IP address in `virtual_ip_address` and `reserved_fixed_ips` - // - Must not be specified the network IP address and broadcast IP address - // - Must not be specified for existing interfaces + // - Set an unique IP address in `virtual_ip_address` and `reserved_fixed_ips` + // - Must not set a network IP address and broadcast IP address + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `virtual_ip_address` value + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway VirtualIPAddress *string `json:"virtual_ip_address"` // - IP addresses that are pre-reserved for applying configurations of load balancer to be performed without losing redundancy - // - Must not be specified for existing interfaces + // - If there are no changes to the `network_id` within the `interfaces[]` , set the current `reserved_fixed_ips` value ReservedFixedIPs *[]UpdateStagedOptsReservedFixedIP `json:"reserved_fixed_ips"` } @@ -497,7 +513,7 @@ type UpdateStagedOptsSyslogServer struct { Port *int `json:"port,omitempty"` // - Protocol of the syslog server - // - Must be specified same protocol in all syslog servers belongs to the same load balancer + // - Set same protocol in all syslog servers which belong to the same load balancer Protocol *string `json:"protocol,omitempty"` } @@ -505,12 +521,13 @@ type UpdateStagedOptsSyslogServer struct { type UpdateStagedOpts struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers *[]UpdateStagedOptsSyslogServer `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer diff --git a/v3/ecl/managed_load_balancer/v1/load_balancers/results.go b/v3/ecl/managed_load_balancer/v1/load_balancers/results.go index 4bace7d..8a2afcd 100644 --- a/v3/ecl/managed_load_balancer/v1/load_balancers/results.go +++ b/v3/ecl/managed_load_balancer/v1/load_balancers/results.go @@ -78,12 +78,13 @@ type ReservedFixedIPInResponse struct { type ConfigurationInResponse struct { // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers []SyslogServerInResponse `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer @@ -178,7 +179,7 @@ type LoadBalancer struct { SecondaryAvailabilityZone string `json:"secondary_availability_zone,omitempty"` // - Primary or secondary availability zone where the load balancer is currently running - // - Return `"UNDEFINED"` if can not define active availability zone + // - If can not define active availability zone, returns `"UNDEFINED"` ActiveAvailabilityZone string `json:"active_availability_zone"` // - Revision of the load balancer @@ -194,25 +195,26 @@ type LoadBalancer struct { TenantID string `json:"tenant_id"` // - Syslog servers to which access logs are transferred + // - The facility code of syslog is 0 (kern), and the severity level is 6 (info) // - Only access logs to listeners which `protocol` is either `"http"` or `"https"` are transferred - // - When `protocol` of `syslog_servers` is `"tcp"` - // - Access logs are transferred to all healthy syslog servers specified in `syslog_servers` - // - When `protocol` of `syslog_servers` is `"udp"` - // - Access logs are transferred to the syslog server specified first in `syslog_servers` as long as it is healthy - // - Access logs are transferred to the syslog server specified second (last) in `syslog_servers` when the first syslog server is not healthy + // - If `protocol` of `syslog_servers` is `"tcp"` + // - Access logs are transferred to all healthy syslog servers set in `syslog_servers` + // - If `protocol` of `syslog_servers` is `"udp"` + // - Access logs are transferred to the syslog server set first in `syslog_servers` as long as it is healthy + // - Access logs are transferred to the syslog server set second (last) in `syslog_servers` if the first syslog server is not healthy SyslogServers []SyslogServerInResponse `json:"syslog_servers,omitempty"` // - Interfaces that attached to the load balancer Interfaces []InterfaceInResponse `json:"interfaces,omitempty"` // - Running configurations of the load balancer - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the load balancer that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/operations/requests.go b/v3/ecl/managed_load_balancer/v1/operations/requests.go index 07933eb..f6bb3a8 100644 --- a/v3/ecl/managed_load_balancer/v1/operations/requests.go +++ b/v3/ecl/managed_load_balancer/v1/operations/requests.go @@ -38,10 +38,10 @@ type ListOpts struct { // - ID of the owner tenant of the resource TenantID string `q:"tenant_id"` - // - When `true` is specified, operations of deleted resource is not displayed + // - If `true` is set, operations of deleted resource is not displayed NoDeleted bool `q:"no_deleted"` - // - When `true` is specified, only the latest operation of each resource is displayed + // - If `true` is set, only the latest operation of each resource is displayed Latest bool `q:"latest"` } diff --git a/v3/ecl/managed_load_balancer/v1/plans/requests.go b/v3/ecl/managed_load_balancer/v1/plans/requests.go index a75e679..f0cd487 100644 --- a/v3/ecl/managed_load_balancer/v1/plans/requests.go +++ b/v3/ecl/managed_load_balancer/v1/plans/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Bandwidth of the plan diff --git a/v3/ecl/managed_load_balancer/v1/policies/doc.go b/v3/ecl/managed_load_balancer/v1/policies/doc.go index fc217d1..28e6272 100644 --- a/v3/ecl/managed_load_balancer/v1/policies/doc.go +++ b/v3/ecl/managed_load_balancer/v1/policies/doc.go @@ -37,6 +37,7 @@ Example to create a policy Tags: tags, Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -105,6 +106,7 @@ Example to create staged policy configurations createStagedOpts := policies.CreateStagedOpts{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -136,6 +138,7 @@ Example to update staged policy configurations algorithm := "round-robin" persistence := "cookie" + idleTimeout := 600 sorryPageUrl := "https://example.com/sorry" sourceNat := "enable" certificateID := "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -146,6 +149,7 @@ Example to update staged policy configurations updateStagedOpts := policies.UpdateStagedOpts{ Algorithm: &algorithm, Persistence: &persistence, + IdleTimeout: &idleTimeout, SorryPageUrl: &sorryPageUrl, SourceNat: &sourceNat, CertificateID: &certificateID, diff --git a/v3/ecl/managed_load_balancer/v1/policies/requests.go b/v3/ecl/managed_load_balancer/v1/policies/requests.go index 58dd6b6..a60182f 100644 --- a/v3/ecl/managed_load_balancer/v1/policies/requests.go +++ b/v3/ecl/managed_load_balancer/v1/policies/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -37,8 +39,10 @@ type ListOpts struct { // - Persistence setting of the policy Persistence string `q:"persistence"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Must be specified as URL format + // - The duration (in seconds) during which a session is allowed to remain inactive + IdleTimeout int `q:"idle_timeout"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down SorryPageUrl string `q:"sorry_page_url"` // - Source NAT setting of the policy @@ -105,56 +109,69 @@ Create Policy type CreateOpts struct { // - Name of the policy + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the policy + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the policy - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Load balancing algorithm (method) of the policy Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID string `json:"health_monitor_id"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID string `json:"listener_id"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID string `json:"default_target_group_id"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` // - ID of the load balancer which the policy belongs to @@ -194,7 +211,7 @@ Show Policy // ShowOpts represents options used to show a policy. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -234,13 +251,17 @@ Update Policy Attributes type UpdateOpts struct { // - Name of the policy + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the policy + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the policy - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -294,46 +315,55 @@ type CreateStagedOpts struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"http"` or `"https"` to others + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"http"` or `"https"` to others, set `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID string `json:"health_monitor_id,omitempty"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID string `json:"listener_id,omitempty"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` } @@ -387,46 +417,55 @@ type UpdateStagedOpts struct { Algorithm *string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence *string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Can be specified when `listener.protocol` is `"http"` or `"https"` - // - Must be specified as URL format - // - Must not be specified or be specified as `""` when `listener.protocol` is neither `"http"` nor `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"http"` or `"https"` to others + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout *int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If `listener.protocol` is `"http"` or `"https"`, this parameter can be set + // - If `listener.protocol` is neither `"http"` nor `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"http"` or `"https"` to others, set `""` SorryPageUrl *string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat *string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Can be specified the certificate which `ca_cert.status` , `ssl_cert.status` and `ssl_key.status` is `"UPLOADED"` - // - Must be specified `certificate.id` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - You can set a ID of the certificate in which `ca_cert.status`, `ssl_cert.status` and `ssl_key.status` are all `"UPLOADED"` + // - If `listener.protocol` is `"https"`, set `certificate.id` + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` CertificateID *string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy - // - Must not be specified the ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the health monitor that `configuration_status` is `"DELETE_STAGED"` HealthMonitorID *string `json:"health_monitor_id,omitempty"` // - ID of the listener that assigned to the policy - // - Must not be specified the ID of the listener that `configuration_status` is `"DELETE_STAGED"` - // - Must not be specified the ID of the listener that already assigned to the other policy + // - Must not set ID of the listener that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the listener that already assigned to the other policy ListenerID *string `json:"listener_id,omitempty"` // - ID of the default target group that assigned to the policy - // - Must not be specified the ID of the target group that `configuration_status` is `"DELETE_STAGED"` + // - Must not set ID of the target group that `configuration_status` is `"DELETE_STAGED"` DefaultTargetGroupID *string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Can be specified or will be set `tls_policy.id` which `default` is `true` when `listener.protocol` is `"https"` - // - Must not be specified or be specified as `""` when `listener.protocol` is not `"https"` - // - Must be specified as `""` when changing `listener.protocol` from `"https"` to others + // - If `listener.protocol` is `"https"`, you can set this parameter explicitly + // - If not set this parameter, the ID of the `tls_policy` with `default: true` will be automatically set + // - If `listener.protocol` is not `"https"`, must not set this parameter or set `""` + // - If you change `listener.protocol` from `"https"` to others, set `""` TLSPolicyID *string `json:"tls_policy_id,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/policies/results.go b/v3/ecl/managed_load_balancer/v1/policies/results.go index 9576da5..066daf0 100644 --- a/v3/ecl/managed_load_balancer/v1/policies/results.go +++ b/v3/ecl/managed_load_balancer/v1/policies/results.go @@ -67,21 +67,30 @@ type ConfigurationInResponse struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Returns `""` when protocol is not `"http"` or `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If protocol is not `"http"` or `"https"`, returns `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy @@ -94,7 +103,7 @@ type ConfigurationInResponse struct { DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` } @@ -154,21 +163,30 @@ type Policy struct { Algorithm string `json:"algorithm,omitempty"` // - Persistence setting of the policy - // - `"cookie"` is used when `listener.protocol` is `"http"` or `"https"` + // - If `listener.protocol` is `"http"` or `"https"`, `"cookie"` is available Persistence string `json:"persistence,omitempty"` - // - URL of the sorry page to which accesses are redirected when all members in the target group are down - // - Returns `""` when protocol is not `"http"` or `"https"` + // - The duration (in seconds) during which a session is allowed to remain inactive + // - There may be a time difference up to 60 seconds, between the set value and the actual timeout + // - If `listener.protocol` is `"tcp"` or `"udp"` + // - Default value is 120 + // - If `listener.protocol` is `"http"` or `"https"` + // - Default value is 600 + // - On session timeout, the load balancer sends TCP RST packets to both the client and the real server + IdleTimeout int `json:"idle_timeout,omitempty"` + + // - URL of the sorry page to which accesses are redirected if all members in the target group are down + // - If protocol is not `"http"` or `"https"`, returns `""` SorryPageUrl string `json:"sorry_page_url,omitempty"` // - Source NAT setting of the policy - // - When `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , + // - If `source_nat` is `"enable"` and `listener.protocol` is `"http"` or `"https"` , // - The source IP address of the request is replaced with `virtual_ip_address` which is assigned to the interface from which the request was sent // - `X-Forwarded-For` header with the IP address of the client is added SourceNat string `json:"source_nat,omitempty"` // - ID of the certificate that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` CertificateID string `json:"certificate_id,omitempty"` // - ID of the health monitor that assigned to the policy @@ -181,17 +199,17 @@ type Policy struct { DefaultTargetGroupID string `json:"default_target_group_id,omitempty"` // - ID of the TLS policy that assigned to the policy - // - Returns `""` when protocol is not `"https"` + // - If protocol is not `"https"`, returns `""` TLSPolicyID string `json:"tls_policy_id,omitempty"` // - Running configurations of the policy - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the policy that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/policies/testing/fixtures.go b/v3/ecl/managed_load_balancer/v1/policies/testing/fixtures.go index 334f865..0ea647f 100644 --- a/v3/ecl/managed_load_balancer/v1/policies/testing/fixtures.go +++ b/v3/ecl/managed_load_balancer/v1/policies/testing/fixtures.go @@ -28,6 +28,7 @@ var listResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -59,6 +60,7 @@ func listResult() []policies.Policy { policy1.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy1.Algorithm = "round-robin" policy1.Persistence = "cookie" + policy1.IdleTimeout = 600 policy1.SorryPageUrl = "https://example.com/sorry" policy1.SourceNat = "enable" policy1.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -80,6 +82,7 @@ var createRequest = fmt.Sprintf(` }, "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -106,6 +109,7 @@ var createResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": null, "persistence": null, + "idle_timeout": null, "sorry_page_url": null, "source_nat": null, "certificate_id": null, @@ -136,6 +140,7 @@ func createResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "" policy.Persistence = "" + policy.IdleTimeout = 0 policy.SorryPageUrl = "" policy.SourceNat = "" policy.CertificateID = "" @@ -162,6 +167,7 @@ var showResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -172,6 +178,7 @@ var showResponse = fmt.Sprintf(` "current": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -191,6 +198,7 @@ func showResult() *policies.Policy { current := policies.ConfigurationInResponse{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -217,6 +225,7 @@ func showResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -256,6 +265,7 @@ var updateResponse = fmt.Sprintf(` "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", "algorithm": null, "persistence": null, + "idle_timeout": null, "sorry_page_url": null, "source_nat": null, "certificate_id": null, @@ -286,6 +296,7 @@ func updateResult() *policies.Policy { policy.TenantID = "34f5c98ef430457ba81292637d0c6fd0" policy.Algorithm = "" policy.Persistence = "" + policy.IdleTimeout = 0 policy.SorryPageUrl = "" policy.SourceNat = "" policy.CertificateID = "" @@ -302,6 +313,7 @@ var createStagedRequest = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -317,6 +329,7 @@ var createStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -332,6 +345,7 @@ func createStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -348,6 +362,7 @@ var showStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -363,6 +378,7 @@ func showStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -379,6 +395,7 @@ var updateStagedRequest = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -394,6 +411,7 @@ var updateStagedResponse = fmt.Sprintf(` "policy": { "algorithm": "round-robin", "persistence": "cookie", + "idle_timeout": 600, "sorry_page_url": "https://example.com/sorry", "source_nat": "enable", "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -409,6 +427,7 @@ func updateStagedResult() *policies.Policy { policy.Algorithm = "round-robin" policy.Persistence = "cookie" + policy.IdleTimeout = 600 policy.SorryPageUrl = "https://example.com/sorry" policy.SourceNat = "enable" policy.CertificateID = "f57a98fe-d63e-4048-93a0-51fe163f30d7" diff --git a/v3/ecl/managed_load_balancer/v1/policies/testing/requests_test.go b/v3/ecl/managed_load_balancer/v1/policies/testing/requests_test.go index 7c8c0d8..552bdd6 100644 --- a/v3/ecl/managed_load_balancer/v1/policies/testing/requests_test.go +++ b/v3/ecl/managed_load_balancer/v1/policies/testing/requests_test.go @@ -97,6 +97,7 @@ func TestCreatePolicy(t *testing.T) { Tags: tags, Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -223,6 +224,7 @@ func TestCreateStagedPolicy(t *testing.T) { createStagedOpts := policies.CreateStagedOpts{ Algorithm: "round-robin", Persistence: "cookie", + IdleTimeout: 600, SorryPageUrl: "https://example.com/sorry", SourceNat: "enable", CertificateID: "f57a98fe-d63e-4048-93a0-51fe163f30d7", @@ -284,6 +286,7 @@ func TestUpdateStagedPolicy(t *testing.T) { algorithm := "round-robin" persistence := "cookie" + idleTimeout := 600 sorryPageUrl := "https://example.com/sorry" sourceNat := "enable" certificateID := "f57a98fe-d63e-4048-93a0-51fe163f30d7" @@ -294,6 +297,7 @@ func TestUpdateStagedPolicy(t *testing.T) { updateStagedOpts := policies.UpdateStagedOpts{ Algorithm: &algorithm, Persistence: &persistence, + IdleTimeout: &idleTimeout, SorryPageUrl: &sorryPageUrl, SourceNat: &sourceNat, CertificateID: &certificateID, diff --git a/v3/ecl/managed_load_balancer/v1/routes/requests.go b/v3/ecl/managed_load_balancer/v1/routes/requests.go index de442b3..b88875d 100644 --- a/v3/ecl/managed_load_balancer/v1/routes/requests.go +++ b/v3/ecl/managed_load_balancer/v1/routes/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -83,26 +85,31 @@ Create Route type CreateOpts struct { // - Name of the (static) route + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the (static) route + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the (static) route - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - CIDR of destination for the (static) route - // - Can be specified as `0.0.0.0/0` to configure default gateway + // - If you configure `destination_cidr` as default gateway, set `0.0.0.0/0` // - `destination_cidr` can not be changed once configured - // - To change `destination_cidr` , recreating the (static) route is needed - // - Must be specified the unique CIDR in all (static) routes belongs to the same load balancer - // - Must be specified the CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - If you want to change `destination_cidr`, recreate the (static) route again + // - Set a unique CIDR for all (static) routes which belong to the same load balancer + // - Set a CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a link-local CIDR (RFC 3927) which includes Common Function Gateway DestinationCidr string `json:"destination_cidr"` // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is not included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress string `json:"next_hop_ip_address"` // - ID of the load balancer which the (static) route belongs to @@ -142,7 +149,7 @@ Show Route // ShowOpts represents options used to show a route. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -182,13 +189,17 @@ Update Route Attributes type UpdateOpts struct { // - Name of the (static) route + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the (static) route + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the (static) route - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -239,8 +250,8 @@ Create Staged Route Configurations type CreateStagedOpts struct { // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress string `json:"next_hop_ip_address,omitempty"` } @@ -291,8 +302,8 @@ Update Staged Route Configurations type UpdateStagedOpts struct { // - ID of the load balancer which the (static) route belongs to - // - Must be specified the CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to - // - Must not be specified the network IP address and broadcast IP address + // - Set a CIDR which is included in subnet of load balancer interfaces that the (static) route belongs to + // - Must not set a network IP address and broadcast IP address NextHopIPAddress *string `json:"next_hop_ip_address,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/routes/results.go b/v3/ecl/managed_load_balancer/v1/routes/results.go index b14b412..ebe17d5 100644 --- a/v3/ecl/managed_load_balancer/v1/routes/results.go +++ b/v3/ecl/managed_load_balancer/v1/routes/results.go @@ -126,13 +126,13 @@ type Route struct { NextHopIPAddress string `json:"next_hop_ip_address,omitempty"` // - Running configurations of the (static) route - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the (static) route that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/rules/requests.go b/v3/ecl/managed_load_balancer/v1/rules/requests.go index a1cba6b..d4d2813 100644 --- a/v3/ecl/managed_load_balancer/v1/rules/requests.go +++ b/v3/ecl/managed_load_balancer/v1/rules/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -86,8 +88,8 @@ Create Rule type CreateOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns []string `json:"path_patterns,omitempty"` } @@ -96,29 +98,33 @@ type CreateOptsCondition struct { type CreateOpts struct { // - Name of the rule + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the rule + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the rule - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID string `json:"target_group_id,omitempty"` // - ID of the policy which the rule belongs to - // - Must be specified a policy which has a listener of which protocol is either `"http"` or `"https"` + // - Set ID of the policy which has a listener in which protocol is either `"http"` or `"https"` PolicyID string `json:"policy_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *CreateOptsCondition `json:"conditions,omitempty"` } @@ -155,7 +161,7 @@ Show Rule // ShowOpts represents options used to show a rule. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -195,13 +201,17 @@ Update Rule Attributes type UpdateOpts struct { // - Name of the rule + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the rule + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the rule - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -252,8 +262,8 @@ Create Staged Rule Configurations type CreateStagedOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns []string `json:"path_patterns,omitempty"` } @@ -262,15 +272,15 @@ type CreateStagedOptsCondition struct { type CreateStagedOpts struct { // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID string `json:"target_group_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *CreateStagedOptsCondition `json:"conditions,omitempty"` } @@ -321,8 +331,8 @@ Update Staged Rule Configurations type UpdateStagedOptsCondition struct { // - URL path patterns (regular expressions) of the condition - // - Must be specified the unique string in all path patterns belongs to the same policy - // - Must be specified as PCRE (Perl Compatible Regular Expressions) format + // - Set a path pattern as unique string in all path patterns which belong to the same policy + // - Set a path pattern in PCRE (Perl Compatible Regular Expressions) format // - Capturing groups and backreferences are not supported PathPatterns *[]string `json:"path_patterns,omitempty"` } @@ -331,15 +341,15 @@ type UpdateStagedOptsCondition struct { type UpdateStagedOpts struct { // - Priority of the rule - // - Must be specified the unique number in all rules belongs to the same policy + // - Set an unique number in all rules which belong to the same policy Priority *int `json:"priority,omitempty"` // - ID of the target group that assigned to the rule - // - Must be specified the different target group from `"default_target_group_id"` of the policy + // - Set a different target group from `"default_target_group_id"` of the policy TargetGroupID *string `json:"target_group_id,omitempty"` // - Conditions of the rules to distribute accesses to the target groups - // - Must be specified one or more condition + // - Set one or more condition Conditions *UpdateStagedOptsCondition `json:"conditions,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/rules/results.go b/v3/ecl/managed_load_balancer/v1/rules/results.go index 24fb4fa..90fa531 100644 --- a/v3/ecl/managed_load_balancer/v1/rules/results.go +++ b/v3/ecl/managed_load_balancer/v1/rules/results.go @@ -145,13 +145,13 @@ type Rule struct { Conditions ConditionInResponse `json:"conditions,omitempty"` // - Running configurations of the rule - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the rule that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/system_updates/requests.go b/v3/ecl/managed_load_balancer/v1/system_updates/requests.go index d036122..e0cec5a 100644 --- a/v3/ecl/managed_load_balancer/v1/system_updates/requests.go +++ b/v3/ecl/managed_load_balancer/v1/system_updates/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - URL of announcement for the system update (for example, Knowledge Center news) @@ -37,7 +39,7 @@ type ListOpts struct { // - Whether the system update can be applied to the load balancer Applicable bool `q:"applicable"` - // - When `true` is specified, only the latest resource is displayed + // - If `true` is set, only the latest resource is displayed Latest bool `q:"latest"` } diff --git a/v3/ecl/managed_load_balancer/v1/target_groups/requests.go b/v3/ecl/managed_load_balancer/v1/target_groups/requests.go index a7e7ef3..8c5d34e 100644 --- a/v3/ecl/managed_load_balancer/v1/target_groups/requests.go +++ b/v3/ecl/managed_load_balancer/v1/target_groups/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Configuration status of the resource @@ -77,16 +79,19 @@ Create Target Group type CreateOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight int `json:"weight,omitempty"` } @@ -94,13 +99,17 @@ type CreateOptsMember struct { type CreateOpts struct { // - Name of the target group + // - This field accepts single-byte characters only Name string `json:"name,omitempty"` // - Description of the target group + // - This field accepts single-byte characters only Description string `json:"description,omitempty"` // - Tags of the target group - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags map[string]interface{} `json:"tags,omitempty"` // - ID of the load balancer which the target group belongs to @@ -143,7 +152,7 @@ Show Target Group // ShowOpts represents options used to show a target group. type ShowOpts struct { - // - When `true` is specified, `current` and `staged` are returned in response body + // - If `true` is set, `current` and `staged` are returned in response body Changes bool `q:"changes"` } @@ -183,13 +192,17 @@ Update Target Group Attributes type UpdateOpts struct { // - Name of the target group + // - This field accepts single-byte characters only Name *string `json:"name,omitempty"` // - Description of the target group + // - This field accepts single-byte characters only Description *string `json:"description,omitempty"` // - Tags of the target group - // - Must be specified as JSON object + // - Set JSON object up to 32,768 characters + // - Nested structure is permitted + // - This field accepts single-byte characters only Tags *map[string]interface{} `json:"tags,omitempty"` } @@ -240,16 +253,19 @@ Create Staged Target Group Configurations type CreateStagedOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight int `json:"weight,omitempty"` } @@ -307,16 +323,19 @@ Update Staged Target Group Configurations type UpdateStagedOptsMember struct { // - IP address of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group + // - Must not set a IP address which is included in `virtual_ip_address` and `reserved_fixed_ips` of load balancer interfaces that the target group belongs to + // - Must not set a IP address of listeners which belong to the same load balancer as the target group + // - Must not set a link-local IP address (RFC 3927) which includes Common Function Gateway IPAddress *string `json:"ip_address"` // - Port number of the member (real server) - // - Must be specified the unique combination of ip address and port in all members belongs to the same target group + // - Set an unique combination of IP address and port in all members which belong to the same target group Port *int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` - // - Must be specified same weight for the combination of ip address and port in all members belongs to the same load balancer + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, use this parameter + // - Set same weight for the combination of IP address and port in all members which belong to the same load balancer Weight *int `json:"weight,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/target_groups/results.go b/v3/ecl/managed_load_balancer/v1/target_groups/results.go index 6a21332..92ddf9e 100644 --- a/v3/ecl/managed_load_balancer/v1/target_groups/results.go +++ b/v3/ecl/managed_load_balancer/v1/target_groups/results.go @@ -77,7 +77,7 @@ type MemberInResponse struct { Port int `json:"port"` // - Weight for the member (real server) - // - Used when `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"` + // - If `policy.algorithm` is `"weighted-round-robin"` or `"weighted-least-connection"`, uses this parameter Weight int `json:"weight"` } @@ -137,13 +137,13 @@ type TargetGroup struct { Members []MemberInResponse `json:"members,omitempty"` // - Running configurations of the target group - // - Return object when `changes` is `true` - // - Return `null` when current configuration does not exist + // - If `changes` is `true`, return object + // - If current configuration does not exist, return `null` Current ConfigurationInResponse `json:"current,omitempty"` // - Added or changed configurations of the target group that waiting to be applied - // - Return object when `changes` is `true` - // - Return `null` when staged configuration does not exist + // - If `changes` is `true`, return object + // - If staged configuration does not exist, return `null` Staged ConfigurationInResponse `json:"staged,omitempty"` } diff --git a/v3/ecl/managed_load_balancer/v1/tls_policies/requests.go b/v3/ecl/managed_load_balancer/v1/tls_policies/requests.go index eabd43e..cb7cf0c 100644 --- a/v3/ecl/managed_load_balancer/v1/tls_policies/requests.go +++ b/v3/ecl/managed_load_balancer/v1/tls_policies/requests.go @@ -20,9 +20,11 @@ type ListOpts struct { ID string `q:"id"` // - Name of the resource + // - This field accepts single-byte characters only Name string `q:"name"` // - Description of the resource + // - This field accepts single-byte characters only Description string `q:"description"` // - Whether the TLS policy will be set `policy.tls_policy_id` when that is not specified diff --git a/v3/ecl/network/v2/common/common_tests.go b/v3/ecl/network/v2/common/common_tests.go deleted file mode 100644 index 52db36b..0000000 --- a/v3/ecl/network/v2/common/common_tests.go +++ /dev/null @@ -1,14 +0,0 @@ -package common - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -const TokenID = client.TokenID - -func ServiceClient() *eclcloud.ServiceClient { - sc := client.ServiceClient() - sc.ResourceBase = sc.Endpoint + "v2.0/" - return sc -} diff --git a/v3/ecl/network/v2/common_function_gateways/doc.go b/v3/ecl/network/v2/common_function_gateways/doc.go deleted file mode 100644 index 766c6e0..0000000 --- a/v3/ecl/network/v2/common_function_gateways/doc.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Package common_function_gateways contains functionality for working with -ECL Commnon Function Gateway resources. - -Example to List CommonFunctionGateways - - listOpts := common_function_gateways.ListOpts{ - TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", - } - - allPages, err := common_function_gateways.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allCommonFunctionGateways, err := common_function_gateways.ExtractCommonFunctionGateways(allPages) - if err != nil { - panic(err) - } - - for _, common_function_gateways := range allCommonFunctionGateways { - fmt.Printf("%+v", common_function_gateways) - } - -Example to Create a common_function_gateways - - createOpts := common_function_gateways.CreateOpts{ - Name: "network_1", - } - - common_function_gateways, err := common_function_gateways.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a common_function_gateways - - commonFunctionGatewayID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - - updateOpts := common_function_gateways.UpdateOpts{ - Name: "new_name", - } - - common_function_gateways, err := common_function_gateways.Update(networkClient, commonFunctionGatewayID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a common_function_gateways - - commonFunctionGatewayID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - err := common_function_gateways.Delete(networkClient, commonFunctionGatewayID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package common_function_gateways diff --git a/v3/ecl/network/v2/common_function_gateways/requests.go b/v3/ecl/network/v2/common_function_gateways/requests.go deleted file mode 100644 index 2fa70f7..0000000 --- a/v3/ecl/network/v2/common_function_gateways/requests.go +++ /dev/null @@ -1,169 +0,0 @@ -package common_function_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToCommonFunctionGatewayListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the common function gateway attributes you want to see returned. -type ListOpts struct { - CommonFunctionPoolID string `q:"common_function_pool_id"` - Description string `q:"description"` - ID string `q:"id"` - Name string `q:"name"` - NetworkID string `q:"network_id"` - Status string `q:"status"` - SubnetID string `q:"subnet_id"` - TenantID string `q:"tenant_id"` -} - -// ToCommonFunctionGatewayListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToCommonFunctionGatewayListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// common function gateways. -// It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToCommonFunctionGatewayListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return CommonFunctionGatewayPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific common function gateway based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToCommonFunctionGatewayCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents options used to create a common function gateway. -type CreateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - CommonFunctionPoolID string `json:"common_function_pool_id,omitempty"` - TenantID string `json:"tenant_id,omitempty"` -} - -// ToCommonFunctionGatewayCreateMap builds a request body from CreateOpts. -// func (opts CreateOpts) ToCommonFunctionGatewayCreateMap() (map[string]interface{}, error) { -func (opts CreateOpts) ToCommonFunctionGatewayCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "common_function_gateway") -} - -// Create accepts a CreateOpts struct and creates a new common function gateway -// using the values provided. -// This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// common function gateway. -// An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToCommonFunctionGatewayCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToCommonFunctionGatewayUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents options used to update a common function gateway. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` -} - -// ToCommonFunctionGatewayUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToCommonFunctionGatewayUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "common_function_gateway") -} - -// Update accepts a UpdateOpts struct and updates an existing common function gateway -// using the values provided. For more information, see the Create function. -func Update(c *eclcloud.ServiceClient, commonFunctionGatewayID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToCommonFunctionGatewayUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, commonFunctionGatewayID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -// Delete accepts a unique ID and deletes the common function gateway associated with it. -func Delete(c *eclcloud.ServiceClient, commonFunctionGatewayID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, commonFunctionGatewayID), nil) - return -} - -// IDFromName is a convenience function that returns a common function gateway's -// ID, given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractCommonFunctionGateways(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "common_function_gateway"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "common_function_gateway"} - } -} diff --git a/v3/ecl/network/v2/common_function_gateways/results.go b/v3/ecl/network/v2/common_function_gateways/results.go deleted file mode 100644 index 997df56..0000000 --- a/v3/ecl/network/v2/common_function_gateways/results.go +++ /dev/null @@ -1,108 +0,0 @@ -package common_function_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a common function gateway resource. -func (r commonResult) Extract() (*CommonFunctionGateway, error) { - var cfgw CommonFunctionGateway - err := r.ExtractInto(&cfgw) - return &cfgw, err -} - -// Extract interprets any commonResult as a Common Function Gateway, if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "common_function_gateway") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Common Function Gateway. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Common Function Gateway. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Common Function Gateway. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// CommonFunctionGateway represents, well, a common function gateway. -type CommonFunctionGateway struct { - // UUID for the network - ID string `json:"id"` - - // Human-readable name for the network. Might not be unique. - Name string `json:"name"` - - Description string `json:"description"` - - CommonFunctionPoolID string `json:"common_function_pool_id"` - - NetworkID string `json:"network_id"` - - SubnetID string `json:"subnet_id"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` -} - -// CommonFunctionGatewayPage is the page returned by a pager -// when traversing over a collection of common function gateway. -type CommonFunctionGatewayPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of common function gateway -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r CommonFunctionGatewayPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"common_function_gateways_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a CommonFunctionGatewayPage struct is empty. -func (r CommonFunctionGatewayPage) IsEmpty() (bool, error) { - is, err := ExtractCommonFunctionGateways(r) - return len(is) == 0, err -} - -// ExtractCommonFunctionGateways accepts a Page struct, -// specifically a NetworkPage struct, and extracts the elements -// into a slice of Common Function Gateway structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractCommonFunctionGateways(r pagination.Page) ([]CommonFunctionGateway, error) { - var s []CommonFunctionGateway - err := ExtractCommonFunctionGatewaysInto(r, &s) - return s, err -} - -// ExtractCommonFunctionGatewaysInto interprets the results of a single page from a List() call, -// producing a slice of Server entities. -func ExtractCommonFunctionGatewaysInto(r pagination.Page, v interface{}) error { - return r.(CommonFunctionGatewayPage).Result.ExtractIntoSlicePtr(v, "common_function_gateways") -} diff --git a/v3/ecl/network/v2/common_function_gateways/testing/doc.go b/v3/ecl/network/v2/common_function_gateways/testing/doc.go deleted file mode 100644 index c8a2e0c..0000000 --- a/v3/ecl/network/v2/common_function_gateways/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains common function gateways unit tests -package testing diff --git a/v3/ecl/network/v2/common_function_gateways/testing/fixtures.go b/v3/ecl/network/v2/common_function_gateways/testing/fixtures.go deleted file mode 100644 index 002ff66..0000000 --- a/v3/ecl/network/v2/common_function_gateways/testing/fixtures.go +++ /dev/null @@ -1,178 +0,0 @@ -package testing - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/common_function_gateways" -) - -// Define parameters which are used in assertion. -// Additionally, kind of IDs are defined here. -const idCommonFunctionGatway1 = "fb3efc23-ca8c-4eb5-b7f6-6fc66ff24f9c" -const idCommonFunctionGatway2 = "3535de20-192d-4f5a-a74a-cd1a9c1bf747" -const idCommonFunctionPool = "4f4971a5-899d-42b4-8442-24f17eac9683" - -const nameCommonFunctionGateway1 = "common_function_gateway_name_1" -const descriptionCommonFunctionGateway1 = "common_function_gateway_description_1" - -const nameCommonFunctionGateway1Update = "common_function_gateway_name_1-update" -const descriptionCommonFunctionGateway1Update = "common_function_gateway_description_1-update" - -const tenantID = "2d5b878c-147a-4d7c-87fd-90a8be9d255f" - -const networkID = "511f266e-a8bf-4547-ab2a-fc4d2bda9f81" -const subnetID = "9f3fd369-e4d4-4c3a-84f1-9c5ba7686297" - -// ListResponse is mocked response of common_function_gateways.List -var ListResponse = fmt.Sprintf(` -{ - "common_function_gateways": [ - { - "id": "%s", - "common_function_pool_id": "%s", - "name": "%s", - "description": "%s", - "tenant_id": "%s", - "network_id": "%s", - "subnet_id": "%s", - "status": "ACTIVE" - }, - { - "id": "%s", - "common_function_pool_id": "%s", - "tenant_id": "%s", - "name": "common_function_gateway_name_2", - "description": "common_function_gateway_description_2", - "network_id": "%s", - "subnet_id": "%s", - "status": "ACTIVE" - } - ] -}`, - // for common function gateway1 - idCommonFunctionGatway1, - idCommonFunctionPool, - nameCommonFunctionGateway1, - descriptionCommonFunctionGateway1, - tenantID, - networkID, - subnetID, - // for common function gateway2 - idCommonFunctionGatway2, - idCommonFunctionPool, - tenantID, - networkID, - subnetID) - -// GetResponse is mocked format of common_function_gateways.Get -var GetResponse = fmt.Sprintf(` -{ - "common_function_gateway": { - "id": "%s", - "common_function_pool_id": "%s", - "name": "%s", - "description": "%s", - "tenant_id": "%s", - "network_id": "%s", - "subnet_id": "%s", - "status": "ACTIVE" - } -}`, idCommonFunctionGatway1, - idCommonFunctionPool, - nameCommonFunctionGateway1, - descriptionCommonFunctionGateway1, - tenantID, - networkID, - subnetID) - -// CreateRequest is mocked request for common_function_gateways.Create -var CreateRequest = fmt.Sprintf(` -{ - "common_function_gateway": { - "name": "%s", - "description": "%s", - "common_function_pool_id": "%s", - "tenant_id": "%s" - } -}`, nameCommonFunctionGateway1, - descriptionCommonFunctionGateway1, - idCommonFunctionPool, - tenantID) - -// CreateResponse is mocked response of common_function_gateways.Create -var CreateResponse = fmt.Sprintf(` -{ - "common_function_gateway": { - "id": "%s", - "common_function_pool_id": "%s", - "name": "%s", - "description": "%s", - "tenant_id": "%s", - "network_id": "%s", - "subnet_id": "%s", - "status": "ACTIVE" - } -}`, idCommonFunctionGatway1, - idCommonFunctionPool, - nameCommonFunctionGateway1, - descriptionCommonFunctionGateway1, - tenantID, - networkID, - subnetID) - -// UpdateRequest is mocked request of common_function_gateways.Update -var UpdateRequest = fmt.Sprintf(` -{ - "common_function_gateway": { - "name": "%s", - "description": "%s" - } -}`, nameCommonFunctionGateway1Update, - descriptionCommonFunctionGateway1Update) - -// UpdateResponse is mocked response of common_function_gateways.Update -var UpdateResponse = fmt.Sprintf(` -{ - "common_function_gateway": { - "id": "%s", - "common_function_pool_id": "%s", - "name": "%s", - "description": "%s", - "tenant_id": "%s", - "network_id": "%s", - "subnet_id": "%s" - } -}`, idCommonFunctionGatway1, - idCommonFunctionPool, - nameCommonFunctionGateway1Update, - descriptionCommonFunctionGateway1Update, - tenantID, - networkID, - subnetID) - -var commonFunctionGateway1 = common_function_gateways.CommonFunctionGateway{ - ID: idCommonFunctionGatway1, - CommonFunctionPoolID: idCommonFunctionPool, - TenantID: tenantID, - Name: nameCommonFunctionGateway1, - Description: descriptionCommonFunctionGateway1, - Status: "ACTIVE", - NetworkID: networkID, - SubnetID: subnetID, -} - -var commonFunctionGateway2 = common_function_gateways.CommonFunctionGateway{ - ID: idCommonFunctionGatway2, - CommonFunctionPoolID: idCommonFunctionPool, - TenantID: tenantID, - Name: "common_function_gateway_name_2", - Description: "common_function_gateway_description_2", - Status: "ACTIVE", - NetworkID: networkID, - SubnetID: subnetID, -} - -// ExpectedCommonFunctionGatewaysSlice is expected assertion target -var ExpectedCommonFunctionGatewaysSlice = []common_function_gateways.CommonFunctionGateway{ - commonFunctionGateway1, - commonFunctionGateway2, -} diff --git a/v3/ecl/network/v2/common_function_gateways/testing/requests_test.go b/v3/ecl/network/v2/common_function_gateways/testing/requests_test.go deleted file mode 100644 index 7529089..0000000 --- a/v3/ecl/network/v2/common_function_gateways/testing/requests_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/common_function_gateways" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListCommonFunctionGatway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/v2.0/common_function_gateways", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - common_function_gateways.List(client, common_function_gateways.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := common_function_gateways.ExtractCommonFunctionGateways(page) - if err != nil { - t.Errorf("Failed to extract common function gateways: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedCommonFunctionGatewaysSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetCommonFunctionGatway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v2.0/common_function_gateways/%s", idCommonFunctionGatway1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - cfGw, err := common_function_gateways.Get(fake.ServiceClient(), idCommonFunctionGatway1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &commonFunctionGateway1, cfGw) -} - -func TestCreateCommonFunctionGatway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/common_function_gateways", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - createOpts := common_function_gateways.CreateOpts{ - Name: nameCommonFunctionGateway1, - Description: descriptionCommonFunctionGateway1, - CommonFunctionPoolID: idCommonFunctionPool, - TenantID: tenantID, - } - cfGw, err := common_function_gateways.Create(fake.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, cfGw.Status, "ACTIVE") - th.AssertDeepEquals(t, &commonFunctionGateway1, cfGw) -} - -func TestUpdateCommonFunctionGatway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v2.0/common_function_gateways/%s", idCommonFunctionGatway1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - name := nameCommonFunctionGateway1Update - description := descriptionCommonFunctionGateway1Update - updateOpts := common_function_gateways.UpdateOpts{ - Name: &name, - Description: &description, - } - cfGw, err := common_function_gateways.Update( - fake.ServiceClient(), idCommonFunctionGatway1, updateOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, cfGw.Name, nameCommonFunctionGateway1Update) - th.AssertEquals(t, cfGw.Description, descriptionCommonFunctionGateway1Update) - th.AssertEquals(t, cfGw.ID, idCommonFunctionGatway1) -} - -func TestDeleteCommonFunctionGatway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v2.0/common_function_gateways/%s", idCommonFunctionGatway1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := common_function_gateways.Delete(fake.ServiceClient(), idCommonFunctionGatway1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/common_function_gateways/urls.go b/v3/ecl/network/v2/common_function_gateways/urls.go deleted file mode 100644 index 22da343..0000000 --- a/v3/ecl/network/v2/common_function_gateways/urls.go +++ /dev/null @@ -1,33 +0,0 @@ -package common_function_gateways - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("common_function_gateways", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("common_function_gateways") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/common_function_pool/doc.go b/v3/ecl/network/v2/common_function_pool/doc.go deleted file mode 100644 index 1873e2a..0000000 --- a/v3/ecl/network/v2/common_function_pool/doc.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Package common_function_pool contains functionality for working with -ECL Common Function Pool resources. - -Example to List Common Function Pools - - listOpts := common_function_pool.ListOpts{ - Description: "general", - } - - allPages, err := common_function_pool.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allCommonFunctionPools, err := common_function_pool.ExtractCommonFunctionPools(allPages) - if err != nil { - panic(err) - } - - for _, commonFunctionPool := range allCommonFunctionPools { - fmt.Printf("%+v\n", commonFunctionPool) - } - -Example to Show Common Function Pool - - commonFunctionPoolID := "c57066cc-9553-43a6-90de-asfdfesfffff" - - commonFunctionPool, err := common_function_pool.Get(networkClient, commonFunctionPoolID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", commonFunctionPool) - -Example to look for Common Function Pool's ID by its name - - commonFunctionPoolName := "CF_Pool1" - - commonFunctionPoolID, err := common_function_pool.IDFromName(networkClient, commonFunctionPoolName) - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", commonFunctionPoolID) -*/ -package common_function_pool diff --git a/v3/ecl/network/v2/common_function_pool/requests.go b/v3/ecl/network/v2/common_function_pool/requests.go deleted file mode 100644 index 6513f13..0000000 --- a/v3/ecl/network/v2/common_function_pool/requests.go +++ /dev/null @@ -1,93 +0,0 @@ -package common_function_pool - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToCommonFunctionPoolListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Common Function Pool attributes you want to see returned. SortKey allows you to sort -// by a particular Common Function Pool attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - Name string `q:"name"` -} - -// ToCommonFunctionPoolsListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToCommonFunctionPoolListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Common Function Pools. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those Common Function Pools that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToCommonFunctionPoolListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return CommonFunctionPoolPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific Common Function Pool based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// IDFromName is a convenience function that returns a Common Function Pool's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractCommonFunctionPools(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "common_function_pool"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "common_function_pool"} - } -} diff --git a/v3/ecl/network/v2/common_function_pool/results.go b/v3/ecl/network/v2/common_function_pool/results.go deleted file mode 100644 index 333e3a0..0000000 --- a/v3/ecl/network/v2/common_function_pool/results.go +++ /dev/null @@ -1,62 +0,0 @@ -package common_function_pool - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CommonFunctionPool represents a Common Function Pool. See package documentation for a top-level -// description of what this is. -type CommonFunctionPool struct { - - // Description is description - Description string `json:"description"` - - // UUID representing the Common Function Pool. - ID string `json:"id"` - - // Name of Common Function Pool - Name string `json:"name"` -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Common Function Pool. -type GetResult struct { - commonResult -} - -// CommonFunctionPoolPage is the page returned by a pager when traversing over a collection -// of common function pools. -type CommonFunctionPoolPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a CommonFunctionPoolPage struct is empty. -func (r CommonFunctionPoolPage) IsEmpty() (bool, error) { - is, err := ExtractCommonFunctionPools(r) - return len(is) == 0, err -} - -// ExtractCommonFunctionPools accepts a Page struct, specifically a CommonFunctionPoolPage struct, -// and extracts the elements into a slice of Common Function Pool structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractCommonFunctionPools(r pagination.Page) ([]CommonFunctionPool, error) { - var s struct { - CommonFunctionPools []CommonFunctionPool `json:"common_function_pools"` - } - err := (r.(CommonFunctionPoolPage)).ExtractInto(&s) - return s.CommonFunctionPools, err -} - -// Extract is a function that accepts a result and extracts a Common Function Pool resource. -func (r commonResult) Extract() (*CommonFunctionPool, error) { - var s struct { - CommonFunctionPool *CommonFunctionPool `json:"common_function_pool"` - } - err := r.ExtractInto(&s) - return s.CommonFunctionPool, err -} diff --git a/v3/ecl/network/v2/common_function_pool/testing/doc.go b/v3/ecl/network/v2/common_function_pool/testing/doc.go deleted file mode 100644 index 16d9a64..0000000 --- a/v3/ecl/network/v2/common_function_pool/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Common Function Pool unit tests -package testing diff --git a/v3/ecl/network/v2/common_function_pool/testing/fixtures.go b/v3/ecl/network/v2/common_function_pool/testing/fixtures.go deleted file mode 100644 index 4ea96b6..0000000 --- a/v3/ecl/network/v2/common_function_pool/testing/fixtures.go +++ /dev/null @@ -1,69 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/common_function_pool" -) - -const ListResponse = ` -{ - "common_function_pools": [ - { - "description": "Common Function Pool 1", - "id": "c57066cc-9553-43a6-90de-asfdfesfffff", - "name": "CF_Pool1" - }, - { - "description": "Common Function Pool 2", - "id": "fesg66cc-9553-43a6-90de-c8472fdsafedf", - "name": "CF_Pool2" - } - ] -} -` - -const GetResponse = ` -{ - "common_function_pool": { - "description": "Common Function Pool Description", - "id": "c57066cc-9553-43a6-90de-c847231bc70b", - "name": "CF_Pool1" - } -} -` - -var CommonFunctionPool1 = common_function_pool.CommonFunctionPool{ - Description: "Common Function Pool 1", - ID: "c57066cc-9553-43a6-90de-asfdfesfffff", - Name: "CF_Pool1", -} - -var CommonFunctionPool2 = common_function_pool.CommonFunctionPool{ - Description: "Common Function Pool 2", - ID: "fesg66cc-9553-43a6-90de-c8472fdsafedf", - Name: "CF_Pool2", -} - -var CommonFunctionDetail = common_function_pool.CommonFunctionPool{ - Description: "Common Function Pool Description", - ID: "c57066cc-9553-43a6-90de-c847231bc70b", - Name: "CF_Pool1", -} - -var ExpectedCommonFunctionPoolSlice = []common_function_pool.CommonFunctionPool{CommonFunctionPool1, CommonFunctionPool2} - -const ListResponseDuplicatedNames = ` -{ - "common_function_pools": [ - { - "description": "Common Function Pool Description 1", - "id": "c57066cc-9553-43a6-90de-asfdfesfffff", - "name": "CF_Pool1" - }, - { - "description": "Common Function Pool Description 2", - "id": "fesg66cc-9553-43a6-90de-c8472fdsafedf", - "name": "CF_Pool1" - } - ] -} -` diff --git a/v3/ecl/network/v2/common_function_pool/testing/requests_test.go b/v3/ecl/network/v2/common_function_pool/testing/requests_test.go deleted file mode 100644 index ee0c59b..0000000 --- a/v3/ecl/network/v2/common_function_pool/testing/requests_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/common_function_pool" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListCommonFunctionPool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/v2.0/common_function_pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - common_function_pool.List(client, common_function_pool.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := common_function_pool.ExtractCommonFunctionPools(page) - if err != nil { - t.Errorf("Failed to extract Common Function Pools: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedCommonFunctionPoolSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetCommonFunctionPool(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/common_function_pools/c57066cc-9553-43a6-90de-c847231bc70b", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := common_function_pool.Get(fake.ServiceClient(), "c57066cc-9553-43a6-90de-c847231bc70b").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &CommonFunctionDetail, s) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/common_function_pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - expectedID := "c57066cc-9553-43a6-90de-asfdfesfffff" - actualID, err := common_function_pool.IDFromName(client, "CF_Pool1") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/common_function_pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - _, err := common_function_pool.IDFromName(client, "CF_PoolX") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/common_function_pools", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := fake.ServiceClient() - - _, err := common_function_pool.IDFromName(client, "CF_Pool1") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/common_function_pool/urls.go b/v3/ecl/network/v2/common_function_pool/urls.go deleted file mode 100644 index 1cffd1d..0000000 --- a/v3/ecl/network/v2/common_function_pool/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package common_function_pool - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("common_function_pools", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("common_function_pools") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} diff --git a/v3/ecl/network/v2/fic_gateways/doc.go b/v3/ecl/network/v2/fic_gateways/doc.go deleted file mode 100644 index 15f0fb6..0000000 --- a/v3/ecl/network/v2/fic_gateways/doc.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Package fic_gateways provides information of several service -in the Enterprise Cloud Compute service - -Example to List FIC Gateways - - listOpts := fic_gateways.ListOpts{ - Status: "ACTIVE", - } - - allPages, err := fic_gateways.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allFICGateways, err := fic_gateways.ExtractFICGateways(allPages) - if err != nil { - panic(err) - } - - for _, ficGateway := range allFICGateways { - fmt.Printf("%+v", ficGateway) - } - -Example to Show FIC Gateway - - id := "02dc9a22-129c-4b12-9936-4080f6a7ae44" - ficGateway, err := fic_gateways.Get(client, id).Extract() - if err != nil { - panic(err) - } - fmt.Print(ficGateway) - -*/ -package fic_gateways diff --git a/v3/ecl/network/v2/fic_gateways/requests.go b/v3/ecl/network/v2/fic_gateways/requests.go deleted file mode 100644 index 3ac78d2..0000000 --- a/v3/ecl/network/v2/fic_gateways/requests.go +++ /dev/null @@ -1,66 +0,0 @@ -package fic_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToFICGatewaysListQuery() (string, error) -} - -// ListOpts allows the filtering of paginated collections through the API. -// Filtering is achieved by passing in struct field values that map to -// the FIC Gateway attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // Description of the FIC Gateway resource. - Description string `q:"description"` - - // FIC Service instantiated by this Gateway. - FICServiceID string `q:"fic_service_id"` - - //Unique ID of the FIC Gateway resource. - ID string `q:"id"` - - //Name of the FIC Gateway resource. - Name string `q:"name"` - - // Quality of Service options selected for this Gateway. - QoSOptionID string `q:"qos_option_id"` - - // The FIC Gateway status. - Status string `q:"status"` - - // Tenant ID of the owner (UUID). - TenantID string `q:"tenant_id"` -} - -// ToFICGatewaysListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToFICGatewaysListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List makes a request against the API to list FIC Gateways accessible to you. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToFICGatewaysListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return FICGatewayPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific FIC Gateway based on its unique ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} diff --git a/v3/ecl/network/v2/fic_gateways/results.go b/v3/ecl/network/v2/fic_gateways/results.go deleted file mode 100644 index 6f2f2e8..0000000 --- a/v3/ecl/network/v2/fic_gateways/results.go +++ /dev/null @@ -1,53 +0,0 @@ -package fic_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type FICGatewayPage struct { - pagination.LinkedPageBase -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the result of Get operations. Call its Extract method to -// interpret it as a FICGateway. -type GetResult struct { - commonResult -} - -// FICGateway represents a FIC Gateway. -type FICGateway struct { - Description string `json:"description"` - FICServiceID string `json:"fic_service_id"` - ID string `json:"id"` - Name string `json:"name"` - QoSOptionID string `json:"qos_option_id"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` -} - -// IsEmpty checks whether a FICGatewayPage struct is empty. -func (r FICGatewayPage) IsEmpty() (bool, error) { - is, err := ExtractFICGateways(r) - return len(is) == 0, err -} - -// ExtractFICGateways accepts a Page struct, specifically a FICGatewayPage struct, -// and extracts the elements into a slice of ListOpts structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractFICGateways(r pagination.Page) ([]FICGateway, error) { - var s []FICGateway - err := r.(FICGatewayPage).Result.ExtractIntoSlicePtr(&s, "fic_gateways") - return s, err -} - -// Extract is a function that accepts a result and extracts a FICGateway. -func (r GetResult) Extract() (*FICGateway, error) { - var l FICGateway - err := r.Result.ExtractIntoStructPtr(&l, "fic_gateway") - return &l, err -} diff --git a/v3/ecl/network/v2/fic_gateways/testing/doc.go b/v3/ecl/network/v2/fic_gateways/testing/doc.go deleted file mode 100644 index bf82f4e..0000000 --- a/v3/ecl/network/v2/fic_gateways/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// ports unit tests -package testing diff --git a/v3/ecl/network/v2/fic_gateways/testing/fixtures.go b/v3/ecl/network/v2/fic_gateways/testing/fixtures.go deleted file mode 100644 index 8b4ba0f..0000000 --- a/v3/ecl/network/v2/fic_gateways/testing/fixtures.go +++ /dev/null @@ -1,64 +0,0 @@ -package testing - -import "github.com/nttcom/eclcloud/v3/ecl/network/v2/fic_gateways" - -const ListResponse = ` -{ - "fic_gateways": [ - { - "description": "fic_gateway_inet_test, 10M-BE, member role", - "fic_service_id": "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "id": "07f97269-e616-4dff-a73f-ca80bc5682dc", - "name": "lab3-test-member-user-fic-gateway", - "qos_option_id": "e41f6a2f-e197-41c8-9f71-ef19cfd2a85a", - "status": "ACTIVE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - }, - { - "description": "", - "fic_service_id": "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "id": "4c842674-60e4-48eb-b5a3-b902f832d0af", - "name": "N000001996_V15000001", - "qos_option_id": "aa776ce4-08a8-4cc1-9a2c-bb95e547916b", - "status": "ACTIVE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - } - ] -} -` - -const GetResponse = ` -{ - "fic_gateway": { - "description": "fic_gateway_inet_test, 10M-BE, member role", - "fic_service_id": "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "id": "07f97269-e616-4dff-a73f-ca80bc5682dc", - "name": "lab3-test-member-user-fic-gateway", - "qos_option_id": "e41f6a2f-e197-41c8-9f71-ef19cfd2a85a", - "status": "ACTIVE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - } -} -` - -var ficgw1 = fic_gateways.FICGateway{ - Description: "fic_gateway_inet_test, 10M-BE, member role", - FICServiceID: "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - ID: "07f97269-e616-4dff-a73f-ca80bc5682dc", - Name: "lab3-test-member-user-fic-gateway", - QoSOptionID: "e41f6a2f-e197-41c8-9f71-ef19cfd2a85a", - Status: "ACTIVE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", -} - -var ficgw2 = fic_gateways.FICGateway{ - Description: "", - FICServiceID: "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - ID: "4c842674-60e4-48eb-b5a3-b902f832d0af", - Name: "N000001996_V15000001", - QoSOptionID: "aa776ce4-08a8-4cc1-9a2c-bb95e547916b", - Status: "ACTIVE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", -} - -var ExpectedFICGatewaySlice = []fic_gateways.FICGateway{ficgw1, ficgw2} diff --git a/v3/ecl/network/v2/fic_gateways/testing/request_test.go b/v3/ecl/network/v2/fic_gateways/testing/request_test.go deleted file mode 100644 index 25b27f7..0000000 --- a/v3/ecl/network/v2/fic_gateways/testing/request_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package testing - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3/ecl/network/v2/fic_gateways" - "github.com/nttcom/eclcloud/v3/pagination" - - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListFICGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/fic_gateways", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - fic_gateways.List(client, fic_gateways.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := fic_gateways.ExtractFICGateways(page) - if err != nil { - t.Errorf("Failed to extract FIC Gateways: %v", err) - return false, nil - } - th.CheckDeepEquals(t, ExpectedFICGatewaySlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetFICGateway(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - id := "07f97269-e616-4dff-a73f-ca80bc5682dc" - th.Mux.HandleFunc(fmt.Sprintf("/v2.0/fic_gateways/%s", id), - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - n, err := fic_gateways.Get(fake.ServiceClient(), id).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &ficgw1, n) -} diff --git a/v3/ecl/network/v2/fic_gateways/urls.go b/v3/ecl/network/v2/fic_gateways/urls.go deleted file mode 100644 index dbf6a3b..0000000 --- a/v3/ecl/network/v2/fic_gateways/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package fic_gateways - -import "github.com/nttcom/eclcloud/v3" - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("fic_gateways", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("fic_gateways") -} diff --git a/v3/ecl/network/v2/gateway_interfaces/doc.go b/v3/ecl/network/v2/gateway_interfaces/doc.go deleted file mode 100644 index 2029b1c..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/doc.go +++ /dev/null @@ -1 +0,0 @@ -package gateway_interfaces diff --git a/v3/ecl/network/v2/gateway_interfaces/requests.go b/v3/ecl/network/v2/gateway_interfaces/requests.go deleted file mode 100644 index dce7a6b..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/requests.go +++ /dev/null @@ -1,162 +0,0 @@ -package gateway_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type ListOptsBuilder interface { - ToGatewayInterfaceListQuery() (string, error) -} - -type ListOpts struct { - AwsGwID string `q:"aws_gw_id"` - AzureGwID string `q:"azure_gw_id"` - Description string `q:"description"` - FICGatewayID string `q:"fic_gw_id"` - GcpGwID string `q:"gcp_gw_id"` - GwVipv4 string `q:"gw_vipv4"` - GwVipv6 string `q:"gw_vipv6"` - ID string `q:"id"` - InterdcGwID string `q:"interdc_gw_id"` - InternetGwID string `q:"internet_gw_id"` - Name string `q:"name"` - Netmask int `q:"netmask"` - NetworkID string `q:"network_id"` - PrimaryIpv4 string `q:"primary_ipv4"` - PrimaryIpv6 string `q:"primary_ipv6"` - SecondaryIpv4 string `q:"secondary_ipv4"` - SecondaryIpv6 string `q:"secondary_ipv6"` - ServiceType string `q:"service_type"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - VpnGwID string `q:"vpn_gw_id"` - VRID int `q:"vrid"` -} - -func (opts ListOpts) ToGatewayInterfaceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToGatewayInterfaceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return GatewayInterfacePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -func Get(c *eclcloud.ServiceClient, gatewayInterfaceID string) (r GetResult) { - _, r.Err = c.Get(getURL(c, gatewayInterfaceID), &r.Body, nil) - return -} - -type CreateOptsBuilder interface { - ToGatewayInterfaceCreateMap() (map[string]interface{}, error) -} - -type CreateOpts struct { - AwsGwID string `json:"aws_gw_id,omitempty"` - AzureGwID string `json:"azure_gw_id,omitempty"` - Description string `json:"description"` - FICGatewayID string `json:"fic_gw_id,omitempty"` - GcpGwID string `json:"gcp_gw_id,omitempty"` - GwVipv4 string `json:"gw_vipv4" required:"true"` - InterdcGwID string `json:"interdc_gw_id,omitempty"` - InternetGwID string `json:"internet_gw_id,omitempty"` - Name string `json:"name"` - Netmask int `json:"netmask" required:"true"` - NetworkID string `json:"network_id" required:"true"` - PrimaryIpv4 string `json:"primary_ipv4" required:"true"` - SecondaryIpv4 string `json:"secondary_ipv4" required:"true"` - ServiceType string `json:"service_type" required:"true"` - TenantID string `json:"tenant_id,omitempty"` - VpnGwID string `json:"vpn_gw_id,omitempty"` - VRID int `json:"vrid" required:"true"` -} - -func (opts CreateOpts) ToGatewayInterfaceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "gw_interface") -} - -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToGatewayInterfaceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -type UpdateOptsBuilder interface { - ToGatewayInterfaceUpdateMap() (map[string]interface{}, error) -} - -type UpdateOpts struct { - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` -} - -func (opts UpdateOpts) ToGatewayInterfaceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "gw_interface") -} - -func Update(c *eclcloud.ServiceClient, gatewayInterfaceID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToGatewayInterfaceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, gatewayInterfaceID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -func Delete(c *eclcloud.ServiceClient, gatewayInterfaceID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, gatewayInterfaceID), nil) - return -} - -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractGatewayInterfaces(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "gw_interface"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "gw_interface"} - } -} diff --git a/v3/ecl/network/v2/gateway_interfaces/results.go b/v3/ecl/network/v2/gateway_interfaces/results.go deleted file mode 100644 index 6b6ca65..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/results.go +++ /dev/null @@ -1,91 +0,0 @@ -package gateway_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*GatewayInterface, error) { - var s GatewayInterface - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "gw_interface") -} - -type CreateResult struct { - commonResult -} - -type GetResult struct { - commonResult -} - -type UpdateResult struct { - commonResult -} - -type DeleteResult struct { - eclcloud.ErrResult -} - -type GatewayInterface struct { - AwsGwID string `json:"aws_gw_id"` - AzureGwID string `json:"azure_gw_id"` - Description string `json:"description"` - FICGatewayID string `json:"fic_gw_id"` - GcpGwID string `json:"gcp_gw_id"` - GwVipv4 string `json:"gw_vipv4"` - GwVipv6 string `json:"gw_vipv6"` - ID string `json:"id"` - InterdcGwID string `json:"interdc_gw_id"` - InternetGwID string `json:"internet_gw_id"` - Name string `json:"name"` - Netmask int `json:"netmask"` - NetworkID string `json:"network_id"` - PrimaryIpv4 string `json:"primary_ipv4"` - PrimaryIpv6 string `json:"primary_ipv6"` - SecondaryIpv4 string `json:"secondary_ipv4"` - SecondaryIpv6 string `json:"secondary_ipv6"` - ServiceType string `json:"service_type"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` - VpnGwID string `json:"vpn_gw_id"` - VRID int `json:"vrid"` -} - -type GatewayInterfacePage struct { - pagination.LinkedPageBase -} - -func (r GatewayInterfacePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"gw_interfaces_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -func (r GatewayInterfacePage) IsEmpty() (bool, error) { - is, err := ExtractGatewayInterfaces(r) - return len(is) == 0, err -} - -func ExtractGatewayInterfaces(r pagination.Page) ([]GatewayInterface, error) { - var s []GatewayInterface - err := ExtractGatewayInterfacesInto(r, &s) - return s, err -} - -func ExtractGatewayInterfacesInto(r pagination.Page, v interface{}) error { - return r.(GatewayInterfacePage).Result.ExtractIntoSlicePtr(v, "gw_interfaces") -} diff --git a/v3/ecl/network/v2/gateway_interfaces/testing/docs.go b/v3/ecl/network/v2/gateway_interfaces/testing/docs.go deleted file mode 100644 index 37028c4..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/testing/docs.go +++ /dev/null @@ -1,2 +0,0 @@ -// gateway_interfaces unit tests -package testing diff --git a/v3/ecl/network/v2/gateway_interfaces/testing/fixtures.go b/v3/ecl/network/v2/gateway_interfaces/testing/fixtures.go deleted file mode 100644 index d4cc7f0..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/testing/fixtures.go +++ /dev/null @@ -1,202 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/gateway_interfaces" -) - -const ListResponse = ` -{ - "gw_interfaces": [ - { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "", - "fic_gw_id": null, - "gcp_gw_id": null, - "gw_vipv4": "100.127.254.49", - "gw_vipv6": null, - "id": "09771fbb-6496-4ae1-9b53-226b6edcc1be", - "interdc_gw_id": null, - "internet_gw_id": "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - "name": "5_Gateway", - "netmask": 29, - "network_id": "0200a550-82cf-4d6d-b564-a87eb63e2b75", - "primary_ipv4": "100.127.254.53", - "primary_ipv6": null, - "secondary_ipv4": "100.127.254.54", - "secondary_ipv6": null, - "service_type": "internet", - "status": "PENDING_CREATE", - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9", - "vpn_gw_id": null, - "vrid": 1 - }, - { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "lab3-test-user-fic-gateway-interface, role : member", - "fic_gw_id": "dd04adc4-459f-4fc4-83a5-47436c6aece5", - "gcp_gw_id": null, - "gw_vipv4": "100.127.254.1", - "gw_vipv6": null, - "id": "165ed64c-b9d4-46b1-afc1-cbbdc356ddcb", - "interdc_gw_id": null, - "internet_gw_id": null, - "name": "lab3-hara-cfg-20151204", - "netmask": 29, - "network_id": "cce5c9a1-1ec3-40b1-bfc7-634bb914646b", - "primary_ipv4": "100.127.254.3", - "primary_ipv6": null, - "secondary_ipv4": "100.127.254.4", - "secondary_ipv6": null, - "service_type": "fic", - "status": "ACTIVE", - "tenant_id": "fe1f6fb95b0e48ba8c59be2121a58adc", - "vpn_gw_id": null, - "vrid": 10 - } - ] -}` - -const GetResponse = ` -{ - "gw_interface": { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "", - "fic_gw_id": null, - "gcp_gw_id": null, - "gw_vipv4": "100.127.254.49", - "gw_vipv6": null, - "id": "09771fbb-6496-4ae1-9b53-226b6edcc1be", - "interdc_gw_id": null, - "internet_gw_id": "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - "name": "5_Gateway", - "netmask": 29, - "network_id": "0200a550-82cf-4d6d-b564-a87eb63e2b75", - "primary_ipv4": "100.127.254.53", - "primary_ipv6": null, - "secondary_ipv4": "100.127.254.54", - "secondary_ipv6": null, - "service_type": "internet", - "status": "PENDING_CREATE", - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9", - "vpn_gw_id": null, - "vrid": 1 - } -}` - -const CreateRequest = ` -{ - "gw_interface": { - "description": "", - "gw_vipv4": "100.127.254.49", - "internet_gw_id": "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - "name": "5_Gateway", - "netmask": 29, - "network_id": "0200a550-82cf-4d6d-b564-a87eb63e2b75", - "primary_ipv4": "100.127.254.53", - "secondary_ipv4": "100.127.254.54", - "service_type": "internet", - "vrid": 1 - } -} -` - -const CreateResponse = ` -{ - "gw_interface": { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "", - "fic_gw_id": null, - "gcp_gw_id": null, - "gw_vipv4": "100.127.254.49", - "gw_vipv6": null, - "id": "09771fbb-6496-4ae1-9b53-226b6edcc1be", - "interdc_gw_id": null, - "internet_gw_id": "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - "name": "5_Gateway", - "netmask": 29, - "network_id": "0200a550-82cf-4d6d-b564-a87eb63e2b75", - "primary_ipv4": "100.127.254.53", - "primary_ipv6": null, - "secondary_ipv4": "100.127.254.54", - "secondary_ipv6": null, - "service_type": "internet", - "status": "PENDING_CREATE", - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9", - "vpn_gw_id": null, - "vrid": 1 - } -}` - -const UpdateRequest = ` -{ - "gw_interface": { - "description": "Updated", - "name": "6_Gateway" - } -}` - -const UpdateResponse = ` -{ - "gw_interface": { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "Updated", - "fic_gw_id": null, - "gcp_gw_id": null, - "gw_vipv4": "100.127.254.49", - "gw_vipv6": null, - "id": "09771fbb-6496-4ae1-9b53-226b6edcc1be", - "interdc_gw_id": null, - "internet_gw_id": "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - "name": "6_Gateway", - "netmask": 29, - "network_id": "0200a550-82cf-4d6d-b564-a87eb63e2b75", - "primary_ipv4": "100.127.254.53", - "primary_ipv6": null, - "secondary_ipv4": "100.127.254.54", - "secondary_ipv6": null, - "service_type": "internet", - "status": "PENDING_UPDATE", - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9", - "vpn_gw_id": null, - "vrid": 1 - } -}` - -var GatewayInterface1 = gateway_interfaces.GatewayInterface{ - Description: "", - GwVipv4: "100.127.254.49", - ID: "09771fbb-6496-4ae1-9b53-226b6edcc1be", - InternetGwID: "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - Name: "5_Gateway", - Netmask: 29, - NetworkID: "0200a550-82cf-4d6d-b564-a87eb63e2b75", - PrimaryIpv4: "100.127.254.53", - SecondaryIpv4: "100.127.254.54", - ServiceType: "internet", - Status: "PENDING_CREATE", - TenantID: "19ab165c7a664abe9c217334cd0e9cc9", - VRID: 1, -} - -var GatewayInterface2 = gateway_interfaces.GatewayInterface{ - Description: "lab3-test-user-fic-gateway-interface, role : member", - FICGatewayID: "dd04adc4-459f-4fc4-83a5-47436c6aece5", - GwVipv4: "100.127.254.1", - ID: "165ed64c-b9d4-46b1-afc1-cbbdc356ddcb", - Name: "lab3-hara-cfg-20151204", - Netmask: 29, - NetworkID: "cce5c9a1-1ec3-40b1-bfc7-634bb914646b", - PrimaryIpv4: "100.127.254.3", - SecondaryIpv4: "100.127.254.4", - ServiceType: "fic", - Status: "ACTIVE", - TenantID: "fe1f6fb95b0e48ba8c59be2121a58adc", - VRID: 10, -} - -var ExpectedGatewayInterfaceSlice = []gateway_interfaces.GatewayInterface{GatewayInterface1, GatewayInterface2} diff --git a/v3/ecl/network/v2/gateway_interfaces/testing/request_test.go b/v3/ecl/network/v2/gateway_interfaces/testing/request_test.go deleted file mode 100644 index ab2f6f0..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/testing/request_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/gateway_interfaces" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListGatewayInterfaces(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/gw_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - tmp := gateway_interfaces.List(client, gateway_interfaces.ListOpts{}) - err := tmp.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := gateway_interfaces.ExtractGatewayInterfaces(page) - if err != nil { - t.Errorf("Failed to extract gateway interfaces: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedGatewayInterfaceSlice, actual) - - return true, nil - }) - - if err != nil { - fmt.Printf("%s", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetGatewayInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/gw_interfaces/09771fbb-6496-4ae1-9b53-226b6edcc1be", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - i, err := gateway_interfaces.Get(fake.ServiceClient(), "09771fbb-6496-4ae1-9b53-226b6edcc1be").Extract() - t.Logf("%s", err) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &GatewayInterface1, i) -} - -func TestCreateGatewayInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/gw_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - options := gateway_interfaces.CreateOpts{ - Description: "", - GwVipv4: "100.127.254.49", - InternetGwID: "e72ef35a-c96f-45f8-aeee-e7547c5b94b3", - Name: "5_Gateway", - Netmask: 29, - NetworkID: "0200a550-82cf-4d6d-b564-a87eb63e2b75", - PrimaryIpv4: "100.127.254.53", - SecondaryIpv4: "100.127.254.54", - ServiceType: "internet", - VRID: 1, - } - i, err := gateway_interfaces.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &GatewayInterface1, i) -} - -func TestUpdateGatewayInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/gw_interfaces/09771fbb-6496-4ae1-9b53-226b6edcc1be", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - description := "Updated" - name := "6_Gateway" - options := gateway_interfaces.UpdateOpts{ - Description: &description, - Name: &name, - } - i, err := gateway_interfaces.Update(fake.ServiceClient(), "09771fbb-6496-4ae1-9b53-226b6edcc1be", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Name, "6_Gateway") - th.AssertEquals(t, i.Description, "Updated") - th.AssertEquals(t, i.ID, "09771fbb-6496-4ae1-9b53-226b6edcc1be") -} - -func TestDeleteGatewayInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/gw_interfaces/09771fbb-6496-4ae1-9b53-226b6edcc1be", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := gateway_interfaces.Delete(fake.ServiceClient(), "09771fbb-6496-4ae1-9b53-226b6edcc1be") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/gateway_interfaces/urls.go b/v3/ecl/network/v2/gateway_interfaces/urls.go deleted file mode 100644 index c444099..0000000 --- a/v3/ecl/network/v2/gateway_interfaces/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package gateway_interfaces - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("gw_interfaces", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("gw_interfaces") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/internet_gateways/doc.go b/v3/ecl/network/v2/internet_gateways/doc.go deleted file mode 100644 index 9be4fab..0000000 --- a/v3/ecl/network/v2/internet_gateways/doc.go +++ /dev/null @@ -1 +0,0 @@ -package internet_gateways diff --git a/v3/ecl/network/v2/internet_gateways/requests.go b/v3/ecl/network/v2/internet_gateways/requests.go deleted file mode 100644 index dbf1997..0000000 --- a/v3/ecl/network/v2/internet_gateways/requests.go +++ /dev/null @@ -1,136 +0,0 @@ -package internet_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type ListOptsBuilder interface { - ToInternetGatewayListQuery() (string, error) -} - -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - InternetServiceID string `q:"internet_service_id"` - Name string `q:"name"` - QoSOptionID string `q:"qos_option_id"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` -} - -func (opts ListOpts) ToInternetGatewayListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToInternetGatewayListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return InternetGatewayPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -func Get(c *eclcloud.ServiceClient, internetGatewayID string) (r GetResult) { - _, r.Err = c.Get(getURL(c, internetGatewayID), &r.Body, nil) - return -} - -type CreateOptsBuilder interface { - ToInternetGatewayCreateMap() (map[string]interface{}, error) -} - -type CreateOpts struct { - Description string `json:"description,omitempty"` - InternetServiceID string `json:"internet_service_id" required:"true"` - Name string `json:"name,omitempty"` - QoSOptionID string `json:"qos_option_id" required:"true"` - TenantID string `json:"tenant_id,omitempty"` -} - -func (opts CreateOpts) ToInternetGatewayCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "internet_gateway") -} - -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToInternetGatewayCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -type UpdateOptsBuilder interface { - ToInternetGatewayUpdateMap() (map[string]interface{}, error) -} - -type UpdateOpts struct { - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` - QoSOptionID *string `json:"qos_option_id,omitempty"` -} - -func (opts UpdateOpts) ToInternetGatewayUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "internet_gateway") -} - -func Update(c *eclcloud.ServiceClient, internetGatewayID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToInternetGatewayUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, internetGatewayID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -func Delete(c *eclcloud.ServiceClient, internetGatewayID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, internetGatewayID), nil) - return -} - -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractInternetGateways(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "internet_gateway"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "internet_gateway"} - } -} diff --git a/v3/ecl/network/v2/internet_gateways/results.go b/v3/ecl/network/v2/internet_gateways/results.go deleted file mode 100644 index 01edec2..0000000 --- a/v3/ecl/network/v2/internet_gateways/results.go +++ /dev/null @@ -1,76 +0,0 @@ -package internet_gateways - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*InternetGateway, error) { - var s InternetGateway - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "internet_gateway") -} - -type CreateResult struct { - commonResult -} - -type GetResult struct { - commonResult -} - -type UpdateResult struct { - commonResult -} - -type DeleteResult struct { - eclcloud.ErrResult -} - -type InternetGateway struct { - ID string `json:"id"` - Description string `json:"description"` - InternetServiceID string `json:"internet_service_id"` - Name string `json:"name"` - QoSOptionID string `json:"qos_option_id"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` -} - -type InternetGatewayPage struct { - pagination.LinkedPageBase -} - -func (r InternetGatewayPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"internet_gateways_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -func (r InternetGatewayPage) IsEmpty() (bool, error) { - is, err := ExtractInternetGateways(r) - return len(is) == 0, err -} - -func ExtractInternetGateways(r pagination.Page) ([]InternetGateway, error) { - var s []InternetGateway - err := ExtractInternetGatewaysInto(r, &s) - return s, err -} - -func ExtractInternetGatewaysInto(r pagination.Page, v interface{}) error { - return r.(InternetGatewayPage).Result.ExtractIntoSlicePtr(v, "internet_gateways") -} diff --git a/v3/ecl/network/v2/internet_gateways/testing/doc.go b/v3/ecl/network/v2/internet_gateways/testing/doc.go deleted file mode 100644 index 79517b8..0000000 --- a/v3/ecl/network/v2/internet_gateways/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// internet_gateways unit tests -package testing diff --git a/v3/ecl/network/v2/internet_gateways/testing/fixtures.go b/v3/ecl/network/v2/internet_gateways/testing/fixtures.go deleted file mode 100644 index 16e1692..0000000 --- a/v3/ecl/network/v2/internet_gateways/testing/fixtures.go +++ /dev/null @@ -1,110 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/internet_gateways" -) - -const ListResponse = ` -{ - "internet_gateways": [ - { - "description": "test", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40", - "status": "PENDING_CREATE", - "tenant_id": "6c0bdafab1914ab2b2b6c415477defc7" - }, - { - "description": "", - "id": "05db9b0e-65ed-4478-a6b3-d3fc259c8d07", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "6_performance", - "qos_option_id": "be985a60-e918-4cca-98f1-8886333f6f5e", - "status": "ACTIVE", - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } - ] -}` - -const GetResponse = `{ - "internet_gateway": { - "description": "test", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40", - "status": "PENDING_CREATE", - "tenant_id": "6c0bdafab1914ab2b2b6c415477defc7" - } -}` - -const CreateRequest = ` -{ - "internet_gateway": { - "description": "test", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40", - "tenant_id": "6c0bdafab1914ab2b2b6c415477defc7" - } -} -` - -const CreateResponse = ` -{ - "internet_gateway": { - "description": "test", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40", - "status": "PENDING_CREATE", - "tenant_id": "6c0bdafab1914ab2b2b6c415477defc7" - } - }` - -const UpdateRequest = ` - { - "internet_gateway": { - "description": "test2", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40" - } -}` - -const UpdateResponse = ` -{ - "internet_gateway": { - "description": "test2", - "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22", - "internet_service_id": "5536154d-9a00-4b11-81fb-b185c9111d90", - "name": "Lab3-Internet-Service-Provider-01", - "qos_option_id": "e497bbc3-1127-4490-a51d-93582c40ab40", - "status": "PENDING_UPDATE", - "tenant_id": "6c0bdafab1914ab2b2b6c415477defc7" - } -}` - -var InternetGateway1 = internet_gateways.InternetGateway{ - Description: "test", - ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - InternetServiceID: "5536154d-9a00-4b11-81fb-b185c9111d90", - Name: "Lab3-Internet-Service-Provider-01", - QoSOptionID: "e497bbc3-1127-4490-a51d-93582c40ab40", - Status: "PENDING_CREATE", - TenantID: "6c0bdafab1914ab2b2b6c415477defc7", -} - -var InternetGateway2 = internet_gateways.InternetGateway{ - Description: "", - ID: "05db9b0e-65ed-4478-a6b3-d3fc259c8d07", - InternetServiceID: "5536154d-9a00-4b11-81fb-b185c9111d90", - Name: "6_performance", - QoSOptionID: "be985a60-e918-4cca-98f1-8886333f6f5e", - Status: "ACTIVE", - TenantID: "19ab165c7a664abe9c217334cd0e9cc9", -} - -var ExpectedInternetGatewaySlice = []internet_gateways.InternetGateway{InternetGateway1, InternetGateway2} diff --git a/v3/ecl/network/v2/internet_gateways/testing/request_test.go b/v3/ecl/network/v2/internet_gateways/testing/request_test.go deleted file mode 100644 index dbe0a50..0000000 --- a/v3/ecl/network/v2/internet_gateways/testing/request_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/internet_gateways" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_gateways", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - tmp := internet_gateways.List(client, internet_gateways.ListOpts{}) - err := tmp.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := internet_gateways.ExtractInternetGateways(page) - if err != nil { - t.Errorf("Failed to extract internet gateways: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedInternetGatewaySlice, actual) - - return true, nil - }) - - if err != nil { - fmt.Printf("%s", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_gateways/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, GetResponse) - }) - - i, err := internet_gateways.Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() - t.Logf("%s", err) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &InternetGateway1, i) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_gateways", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprint(w, CreateResponse) - }) - - options := internet_gateways.CreateOpts{ - Name: "Lab3-Internet-Service-Provider-01", - TenantID: "6c0bdafab1914ab2b2b6c415477defc7", - Description: "test", - InternetServiceID: "5536154d-9a00-4b11-81fb-b185c9111d90", - QoSOptionID: "e497bbc3-1127-4490-a51d-93582c40ab40", - } - i, err := internet_gateways.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Status, "PENDING_CREATE") - th.AssertDeepEquals(t, &InternetGateway1, i) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_gateways/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, UpdateResponse) - }) - - name := "Lab3-Internet-Service-Provider-01" - description := "test2" - qosOptionId := "e497bbc3-1127-4490-a51d-93582c40ab40" - options := internet_gateways.UpdateOpts{ - Name: &name, - Description: &description, - QoSOptionID: &qosOptionId, - } - i, err := internet_gateways.Update(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Name, "Lab3-Internet-Service-Provider-01") - th.AssertEquals(t, i.Description, "test2") - th.AssertEquals(t, i.QoSOptionID, "e497bbc3-1127-4490-a51d-93582c40ab40") - th.AssertEquals(t, i.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_gateways/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := internet_gateways.Delete(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/internet_gateways/urls.go b/v3/ecl/network/v2/internet_gateways/urls.go deleted file mode 100644 index 1da0d07..0000000 --- a/v3/ecl/network/v2/internet_gateways/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package internet_gateways - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("internet_gateways", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("internet_gateways") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/internet_services/doc.go b/v3/ecl/network/v2/internet_services/doc.go deleted file mode 100644 index 1d5dd38..0000000 --- a/v3/ecl/network/v2/internet_services/doc.go +++ /dev/null @@ -1 +0,0 @@ -package internet_services diff --git a/v3/ecl/network/v2/internet_services/requests.go b/v3/ecl/network/v2/internet_services/requests.go deleted file mode 100644 index 7aaa84c..0000000 --- a/v3/ecl/network/v2/internet_services/requests.go +++ /dev/null @@ -1,42 +0,0 @@ -package internet_services - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type ListOptsBuilder interface { - ToInternetServiceListQuery() (string, error) -} - -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - MinimalSubmaskLength int `q:"minimal_submask_length"` - Name string `q:"name"` - Zone string `q:"zone"` -} - -func (opts ListOpts) ToInternetServiceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToInternetServiceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return InternetServicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -func Get(c *eclcloud.ServiceClient, internetServiceID string) (r GetResult) { - _, r.Err = c.Get(getURL(c, internetServiceID), &r.Body, nil) - return -} diff --git a/v3/ecl/network/v2/internet_services/results.go b/v3/ecl/network/v2/internet_services/results.go deleted file mode 100644 index 681e475..0000000 --- a/v3/ecl/network/v2/internet_services/results.go +++ /dev/null @@ -1,62 +0,0 @@ -package internet_services - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*InternetService, error) { - var s InternetService - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "internet_service") -} - -type GetResult struct { - commonResult -} - -type InternetService struct { - Description string `json:"description"` - ID string `json:"id"` - MinimalSubmaskLength int `json:"minimal_submask_length"` - Name string `json:"name"` - Zone string `json:"zone"` -} - -type InternetServicePage struct { - pagination.LinkedPageBase -} - -func (r InternetServicePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"internet_services_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -func (r InternetServicePage) IsEmpty() (bool, error) { - is, err := ExtractInternetServices(r) - return len(is) == 0, err -} - -func ExtractInternetServices(r pagination.Page) ([]InternetService, error) { - var s []InternetService - err := ExtractInternetServicesInto(r, &s) - return s, err -} - -func ExtractInternetServicesInto(r pagination.Page, v interface{}) error { - return r.(InternetServicePage).Result.ExtractIntoSlicePtr(v, "internet_services") -} diff --git a/v3/ecl/network/v2/internet_services/testing/doc.go b/v3/ecl/network/v2/internet_services/testing/doc.go deleted file mode 100644 index 7603f83..0000000 --- a/v3/ecl/network/v2/internet_services/testing/doc.go +++ /dev/null @@ -1 +0,0 @@ -package testing diff --git a/v3/ecl/network/v2/internet_services/testing/fixtures.go b/v3/ecl/network/v2/internet_services/testing/fixtures.go deleted file mode 100644 index 000e788..0000000 --- a/v3/ecl/network/v2/internet_services/testing/fixtures.go +++ /dev/null @@ -1,53 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/internet_services" -) - -const ListResponse = ` -{ - "internet_services": [ - { - "description": "Example internet_service 1 description", - "id": "a7791c79-19b0-4eb6-9a8f-ea739b44e8d5", - "minimal_submask_length": 26, - "name": "Internet-Service-01", - "zone": "jp1-zone1" - }, - { - "description": "Example internet_service 2 description.", - "id": "5d6eaf32-8c42-4187-973b-dcee142dcb9d", - "minimal_submask_length": 26, - "name": "Internet-Service-01", - "zone": "jp2-zone1" - } - ] -}` - -const GetResponse = `{ - "internet_service": { - "description": "Example internet_service 1 description", - "id": "a7791c79-19b0-4eb6-9a8f-ea739b44e8d5", - "minimal_submask_length": 26, - "name": "Internet-Service-01", - "zone": "jp1-zone1" - } -}` - -var InternetService1 = internet_services.InternetService{ - Description: "Example internet_service 1 description", - ID: "a7791c79-19b0-4eb6-9a8f-ea739b44e8d5", - MinimalSubmaskLength: 26, - Name: "Internet-Service-01", - Zone: "jp1-zone1", -} - -var InternetService2 = internet_services.InternetService{ - Description: "Example internet_service 2 description.", - ID: "5d6eaf32-8c42-4187-973b-dcee142dcb9d", - MinimalSubmaskLength: 26, - Name: "Internet-Service-01", - Zone: "jp2-zone1", -} - -var ExpectedInternetServiceSlice = []internet_services.InternetService{InternetService1, InternetService2} diff --git a/v3/ecl/network/v2/internet_services/testing/request_test.go b/v3/ecl/network/v2/internet_services/testing/request_test.go deleted file mode 100644 index 65fa18e..0000000 --- a/v3/ecl/network/v2/internet_services/testing/request_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/internet_services" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_services", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - tmp := internet_services.List(client, internet_services.ListOpts{}) - err := tmp.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := internet_services.ExtractInternetServices(page) - if err != nil { - t.Errorf("Failed to extract internet services: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedInternetServiceSlice, actual) - - return true, nil - }) - - if err != nil { - fmt.Printf("%s", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/internet_services/a7791c79-19b0-4eb6-9a8f-ea739b44e8d5", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - i, err := internet_services.Get(fake.ServiceClient(), "a7791c79-19b0-4eb6-9a8f-ea739b44e8d5").Extract() - t.Logf("%s", err) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &InternetService1, i) -} diff --git a/v3/ecl/network/v2/internet_services/urls.go b/v3/ecl/network/v2/internet_services/urls.go deleted file mode 100644 index 6cddfaf..0000000 --- a/v3/ecl/network/v2/internet_services/urls.go +++ /dev/null @@ -1,19 +0,0 @@ -package internet_services - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("internet_services", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("internet_services") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} diff --git a/v3/ecl/network/v2/load_balancer_actions/doc.go b/v3/ecl/network/v2/load_balancer_actions/doc.go deleted file mode 100644 index 26b188d..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/doc.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Package load_balancer_actions contains functionality for working with -ECL Load Balancer/Actions resources. - -Example to reboot a Load Balancer - - loadBalancerID := "9ab7ab3c-38a6-417c-926b-93772c4eb2f9" - - rebootOpts := load_balancer_actions.RebootOpts{ - Type: "HARD", - } - - err := load_balancer_actions.Reboot(networkClient, loadBalancerID, rebootOpts).ExtractErr() - if err != nil { - panic(err) - } - -Example to reset password of Load Balancer - - loadBalancerID := "9ab7ab3c-38a6-417c-926b-93772c4eb2f9" - - resetPasswordOpts := load_balancer_actions.ResetPasswordOpts{ - Username: "user-read", - } - - resetPasswordResult, err := load_balancer_actions.ResetPassword(networkClient, loadBalancerID, resetPasswordOpts).ExtractResetPassword() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", resetPasswordResult) - -*/ -package load_balancer_actions diff --git a/v3/ecl/network/v2/load_balancer_actions/requests.go b/v3/ecl/network/v2/load_balancer_actions/requests.go deleted file mode 100644 index 7d95ee4..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/requests.go +++ /dev/null @@ -1,67 +0,0 @@ -package load_balancer_actions - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// RebootOpts represents the attributes used when rebooting a Load Balancer. -type RebootOpts struct { - - // should syslog record acl info - Type string `json:"type" required:"true"` -} - -// ToLoadBalancerActionRebootMap builds a request body from RebootOpts. -func (opts RebootOpts) ToLoadBalancerActionRebootMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - return b, nil -} - -// Reboot accepts a RebootOpts struct and reboots an existing Load Balancer using the -// values provided. -func Reboot(c *eclcloud.ServiceClient, id string, opts RebootOpts) (r RebootResult) { - b, err := opts.ToLoadBalancerActionRebootMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(rebootURL(c, id), b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// ResetPasswordOpts represents the attributes used when resetting password of load_balancer instance. -type ResetPasswordOpts struct { - - // should syslog record acl info - Username string `json:"username" required:"true"` -} - -// ToLoadBalancerActionResetPasswordMap builds a request body from ResetPasswordOpts. -func (opts ResetPasswordOpts) ToLoadBalancerActionResetPasswordMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - return b, nil -} - -// ResetPassword accepts a ResetPasswordOpts struct and resets an existing Load Balancer password using the -// values provided. -func ResetPassword(c *eclcloud.ServiceClient, id string, opts ResetPasswordOpts) (r ResetPasswordResult) { - b, err := opts.ToLoadBalancerActionResetPasswordMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(resetPasswordURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/network/v2/load_balancer_actions/results.go b/v3/ecl/network/v2/load_balancer_actions/results.go deleted file mode 100644 index 025a972..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/results.go +++ /dev/null @@ -1,38 +0,0 @@ -package load_balancer_actions - -import ( - "github.com/nttcom/eclcloud/v3" -) - -type commonResult struct { - eclcloud.Result -} - -// ExtractResetPassword is a function that accepts a result and extracts a result of reset_password. -func (r commonResult) ExtractResetPassword() (*Password, error) { - var s Password - err := r.ExtractInto(&s) - return &s, err -} - -// RebootResult represents the result of a reboot operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type RebootResult struct { - eclcloud.ErrResult -} - -// ResetPasswordResult represents the result of a Reset Password operation. Call its ExtractResetPassword -// method to interpret it as an action's result. -type ResetPasswordResult struct { - commonResult -} - -// Password represents a detail of a Reset Password operation. -type Password struct { - - // new password - NewPassword string `json:"new_password"` - - // username - Username string `json:"username"` -} diff --git a/v3/ecl/network/v2/load_balancer_actions/testing/doc.go b/v3/ecl/network/v2/load_balancer_actions/testing/doc.go deleted file mode 100644 index b0c1fa6..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Load Balancer/Actions unit tests -package testing diff --git a/v3/ecl/network/v2/load_balancer_actions/testing/fixtures.go b/v3/ecl/network/v2/load_balancer_actions/testing/fixtures.go deleted file mode 100644 index 909f092..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/testing/fixtures.go +++ /dev/null @@ -1,27 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_actions" -) - -const RebootRequest = ` -{ - "type": "HARD" -} -` -const ResetPasswordResponse = ` -{ - "new_password": "ABCDabcd4321", - "username": "user-read" -} -` -const ResetPasswordRequest = ` -{ - "username": "user-read" -} -` - -var ResetPasswordDetail = load_balancer_actions.Password{ - NewPassword: "ABCDabcd4321", - Username: "user-read", -} diff --git a/v3/ecl/network/v2/load_balancer_actions/testing/request_test.go b/v3/ecl/network/v2/load_balancer_actions/testing/request_test.go deleted file mode 100644 index 483765b..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/testing/request_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_actions" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestRebootLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers/6e9c7745-61f2-491f-9689-add8c5fc4b9a/reboot", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, RebootRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - }) - - options := load_balancer_actions.RebootOpts{ - Type: "HARD", - } - res := load_balancer_actions.Reboot(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a", options) - th.AssertNoErr(t, res.Err) -} - -func TestRequiredRebootOptsLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := load_balancer_actions.Reboot(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a", load_balancer_actions.RebootOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestResetPasswordLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers/6e9c7745-61f2-491f-9689-add8c5fc4b9a/reset_password", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, ResetPasswordRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ResetPasswordResponse) - }) - - options := load_balancer_actions.ResetPasswordOpts{ - Username: "user-read", - } - s, err := load_balancer_actions.ResetPassword(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a", options).ExtractResetPassword() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &ResetPasswordDetail, s) -} - -func TestRequiredResetPasswordOptsLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := load_balancer_actions.ResetPassword(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a", load_balancer_actions.ResetPasswordOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/load_balancer_actions/urls.go b/v3/ecl/network/v2/load_balancer_actions/urls.go deleted file mode 100644 index 9542c29..0000000 --- a/v3/ecl/network/v2/load_balancer_actions/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package load_balancer_actions - -import "github.com/nttcom/eclcloud/v3" - -func rebootURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancers", id, "reboot") -} - -func resetPasswordURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancers", id, "reset_password") -} diff --git a/v3/ecl/network/v2/load_balancer_interfaces/doc.go b/v3/ecl/network/v2/load_balancer_interfaces/doc.go deleted file mode 100644 index 973f0d8..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/doc.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Package load_balancer_interfaces contains functionality for working with -ECL Load Balancer Interface resources. - -Example to List Load Balancer Interfaces - - listOpts := load_balancer_interfaces.ListOpts{ - Status: "ACTIVE", - } - - allPages, err := load_balancer_interfaces.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allLoadBalancerInterfaces, err := load_balancer_interfaces.ExtractLoadBalancerInterfaces(allPages) - if err != nil { - panic(err) - } - - for _, loadBalancerInterface := range allLoadBalancerInterfaces { - fmt.Printf("%+v\n", loadBalancerInterface) - } - - -Example to Show Load Balancer Interface - - loadBalancerInterfaceID := "f44e063c-5fea-45b8-9124-956995eafe2a" - - loadBalancerInterface, err := load_balancer_interfaces.Get(networkClient, loadBalancerInterfaceID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", loadBalancerInterface) - - -Example to Update Load Balancer Interface - - loadBalancerInterfaceID := "f44e063c-5fea-45b8-9124-956995eafe2a" - - updateOpts := load_balancer_interfaces.UpdateOpts{ - Name: "new_name", - } - - loadBalancerInterface, err := load_balancer_interfaces.Update(networkClient, loadBalancerInterfaceID, updateOpts).Extract() - if err != nil { - panic(err) - } -*/ -package load_balancer_interfaces diff --git a/v3/ecl/network/v2/load_balancer_interfaces/requests.go b/v3/ecl/network/v2/load_balancer_interfaces/requests.go deleted file mode 100644 index e3a3e20..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/requests.go +++ /dev/null @@ -1,138 +0,0 @@ -package load_balancer_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Load Balancer Interface attributes you want to see returned. SortKey allows you to sort -// by a particular Load Balancer Interface attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - IPAddress string `q:"ip_address"` - LoadBalancerID string `q:"load_balancer_id"` - Name string `q:"name"` - NetworkID string `q:"network_id"` - SlotNumber int `q:"slot_number"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - VirtualIPAddress string `q:"virtual_ip_address"` -} - -// ToLoadBalancerInterfacesListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToLoadBalancerInterfacesListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Load Balancer Interfaces. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those Load Balancer Interfaces that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOpts) pagination.Pager { - url := listURL(c) - query, err := opts.ToLoadBalancerInterfacesListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return LoadBalancerInterfacePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific Load Balancer Interface based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// UpdateOpts represents the attributes used when updating an existing Load Balancer Interface. -type UpdateOpts struct { - - // Description is description - Description *string `json:"description,omitempty"` - - // IP Address - IPAddress string `json:"ip_address,omitempty"` - - // Name of the Load Balancer Interface - Name *string `json:"name,omitempty"` - - // UUID of the parent network. - NetworkID *interface{} `json:"network_id,omitempty"` - - // Virtual IP Address - VirtualIPAddress *interface{} `json:"virtual_ip_address,omitempty"` - - // Properties used for virtual IP address - VirtualIPProperties *VirtualIPProperties `json:"virtual_ip_properties,omitempty"` -} - -// ToLoadBalancerUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToLoadBalancerInterfaceUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "load_balancer_interface") - if err != nil { - return nil, err - } - - return b, nil -} - -// Update accepts a UpdateOpts struct and updates an existing Load Balancer Interface using the -// values provided. -func Update(c *eclcloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { - b, err := opts.ToLoadBalancerInterfaceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// IDFromName is a convenience function that returns a Load Balancer Interface's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractLoadBalancerInterfaces(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "load_balancer_interface"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "load_balancer_interface"} - } -} diff --git a/v3/ecl/network/v2/load_balancer_interfaces/results.go b/v3/ecl/network/v2/load_balancer_interfaces/results.go deleted file mode 100644 index c9f3421..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/results.go +++ /dev/null @@ -1,101 +0,0 @@ -package load_balancer_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Load Balancer Interface. -type UpdateResult struct { - commonResult -} - -// Extract is a function that accepts a result and extracts a Load Balancer Interface resource. -func (r commonResult) Extract() (*LoadBalancerInterface, error) { - var s struct { - LoadBalancerInterface *LoadBalancerInterface `json:"load_balancer_interface"` - } - err := r.ExtractInto(&s) - return s.LoadBalancerInterface, err -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Load Balancer Interface. -type GetResult struct { - commonResult -} - -// Properties used for virtual IP address -type VirtualIPProperties struct { - Protocol string `json:"protocol"` - Vrid int `json:"vrid"` -} - -// LoadBalancerInterface represents a Load Balancer Interface. See package documentation for a top-level -// description of what this is. -type LoadBalancerInterface struct { - - // Description is description - Description string `json:"description"` - - // UUID representing the Load Balancer Interface. - ID string `json:"id"` - - // IP Address - IPAddress *string `json:"ip_address"` - - // The ID of load_balancer this load_balancer_interface belongs to. - LoadBalancerID string `json:"load_balancer_id"` - - // Name of the Load Balancer Interface - Name string `json:"name"` - - // UUID of the parent network. - NetworkID *string `json:"network_id"` - - // Slot Number - SlotNumber int `json:"slot_number"` - - // Load Balancer Interface status - Status string `json:"status"` - - // Tenant ID of the owner (UUID) - TenantID string `json:"tenant_id"` - - // Load Balancer Interface type - Type string `json:"type"` - - // Virtual IP Address - VirtualIPAddress *string `json:"virtual_ip_address"` - - // Properties used for virtual IP address - VirtualIPProperties *VirtualIPProperties `json:"virtual_ip_properties"` -} - -// LoadBalancerPage is the page returned by a pager when traversing over a collection -// of load balancers. -type LoadBalancerInterfacePage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a LoadBalancerInterfacePage struct is empty. -func (r LoadBalancerInterfacePage) IsEmpty() (bool, error) { - is, err := ExtractLoadBalancerInterfaces(r) - return len(is) == 0, err -} - -// ExtractLoadBalancerInterfaces accepts a Page struct, specifically a LoadBalancerPage struct, -// and extracts the elements into a slice of Load Balancer Interface structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractLoadBalancerInterfaces(r pagination.Page) ([]LoadBalancerInterface, error) { - var s struct { - LoadBalancerInterfaces []LoadBalancerInterface `json:"load_balancer_interfaces"` - } - err := (r.(LoadBalancerInterfacePage)).ExtractInto(&s) - return s.LoadBalancerInterfaces, err -} diff --git a/v3/ecl/network/v2/load_balancer_interfaces/testing/doc.go b/v3/ecl/network/v2/load_balancer_interfaces/testing/doc.go deleted file mode 100644 index d644bd6..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Load Balancer Interfaces unit tests -package testing diff --git a/v3/ecl/network/v2/load_balancer_interfaces/testing/fixtures.go b/v3/ecl/network/v2/load_balancer_interfaces/testing/fixtures.go deleted file mode 100644 index c8dadcb..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/testing/fixtures.go +++ /dev/null @@ -1,183 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_interfaces" -) - -const ListResponse = ` -{ - "load_balancer_interfaces": [ - { - "description": "test1", - "id": "b409f68e-9307-4649-9073-bb3cb776bda5", - "ip_address": "100.64.64.34", - "load_balancer_id": "5a109f4a-ebd8-4998-8410-98629e2bd5cd", - "name": "Interface 1/2", - "network_id": "30b665e3-db2b-473b-a09a-8940148b6491", - "slot_number": 2, - "status": "ACTIVE", - "tenant_id": "8fe1cc29-ff7d4773bced6cb02fc8002f", - "virtual_ip_address": "100.64.64.101", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - }, - { - "description": "test2", - "id": "0aaef2e9-b4a0-4c31-bd98-496e0a8fed4f", - "ip_address": null, - "load_balancer_id": "12efe0b1-02b6-4e97-ad93-9dc1f7b5c0fc", - "name": "Interface 1/1", - "network_id": null, - "slot_number": 1, - "status": "DOWN", - "tenant_id": "44777b33f0ee474ab1466ebee9fa369f", - "virtual_ip_address": null, - "virtual_ip_properties": null - } - ] -} -` -const GetResponse = ` -{ - "load_balancer_interface": { - "description": "test3", - "id": "da3f99e8-a949-40e7-a0e4-4609b705a7c7", - "ip_address": "100.64.64.34", - "load_balancer_id": "79378a5d-bc2f-4a74-ab4b-ceae8693dca5", - "name": "Interface 1/2", - "network_id": "30b665e3-db2b-473b-a09a-8940148b6491", - "slot_number": 2, - "status": "ACTIVE", - "tenant_id": "401c9473a52b4ee486d17ea76f466f66", - "virtual_ip_address": "100.64.64.101", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - } -} - ` - -const UpdateRequest = ` -{ - "load_balancer_interface": { - "description": "test", - "ip_address": "100.64.64.34", - "name": "Interface 1/2", - "network_id": "e6106a35-d79b-44a3-bda0-6009b2f8775a", - "virtual_ip_address": "100.64.64.101", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - } -} -` -const UpdateResponse = ` -{ - "load_balancer_interface": { - "description": "test", - "id": "2897f333-3554-4099-a638-64d7022bf9ae", - "ip_address": "100.64.64.34", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "name": "Interface 1/2", - "network_id": "e6106a35-d79b-44a3-bda0-6009b2f8775a", - "slot_number": 2, - "status": "PENDING_UPDATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "virtual_ip_address": "100.64.64.101", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - } -} -` - -var LoadBalancerInterface1 = load_balancer_interfaces.LoadBalancerInterface{ - Description: "test1", - ID: "b409f68e-9307-4649-9073-bb3cb776bda5", - IPAddress: &DetailIPAddress, - LoadBalancerID: "5a109f4a-ebd8-4998-8410-98629e2bd5cd", - Name: "Interface 1/2", - NetworkID: &DetailNetworkID, - SlotNumber: 2, - Status: "ACTIVE", - TenantID: "8fe1cc29-ff7d4773bced6cb02fc8002f", - VirtualIPAddress: &DetailVirtualIPAddress, - VirtualIPProperties: &load_balancer_interfaces.VirtualIPProperties{ - Protocol: "vrrp", - Vrid: 10, - }, -} - -var DetailIPAddress = "100.64.64.34" -var DetailNetworkID = "30b665e3-db2b-473b-a09a-8940148b6491" -var DetailVirtualIPAddress = "100.64.64.101" - -var LoadBalancerInterface2 = load_balancer_interfaces.LoadBalancerInterface{ - Description: "test2", - ID: "0aaef2e9-b4a0-4c31-bd98-496e0a8fed4f", - LoadBalancerID: "12efe0b1-02b6-4e97-ad93-9dc1f7b5c0fc", - Name: "Interface 1/1", - SlotNumber: 1, - Status: "DOWN", - TenantID: "44777b33f0ee474ab1466ebee9fa369f", -} - -var LoadBalancerInterfaceDetail = load_balancer_interfaces.LoadBalancerInterface{ - Description: "test3", - ID: "da3f99e8-a949-40e7-a0e4-4609b705a7c7", - IPAddress: &DetailIPAddress, - LoadBalancerID: "79378a5d-bc2f-4a74-ab4b-ceae8693dca5", - Name: "Interface 1/2", - NetworkID: &DetailNetworkID, - SlotNumber: 2, - Status: "ACTIVE", - TenantID: "401c9473a52b4ee486d17ea76f466f66", - VirtualIPAddress: &DetailVirtualIPAddress, - VirtualIPProperties: &load_balancer_interfaces.VirtualIPProperties{ - Protocol: "vrrp", - Vrid: 10, - }, -} - -var ExpectedLoadBalancerInterfaceSlice = []load_balancer_interfaces.LoadBalancerInterface{LoadBalancerInterface1, LoadBalancerInterface2} - -const ListResponseDuplicatedNames = ` -{ - "load_balancer_interfaces": [ - { - "description": "test1", - "id": "b409f68e-9307-4649-9073-bb3cb776bda5", - "ip_address": "100.64.64.34", - "load_balancer_id": "5a109f4a-ebd8-4998-8410-98629e2bd5cd", - "name": "Interface 1/2", - "network_id": "30b665e3-db2b-473b-a09a-8940148b6491", - "slot_number": 2, - "status": "ACTIVE", - "tenant_id": "8fe1cc29-ff7d4773bced6cb02fc8002f", - "virtual_ip_address": "100.64.64.101", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - }, - { - "description": "test2", - "id": "0aaef2e9-b4a0-4c31-bd98-496e0a8fed4f", - "ip_address": null, - "load_balancer_id": "12efe0b1-02b6-4e97-ad93-9dc1f7b5c0fc", - "name": "Interface 1/2", - "network_id": null, - "slot_number": 1, - "status": "DOWN", - "tenant_id": "44777b33f0ee474ab1466ebee9fa369f", - "virtual_ip_address": null, - "virtual_ip_properties": null - } - ] -} -` diff --git a/v3/ecl/network/v2/load_balancer_interfaces/testing/request_test.go b/v3/ecl/network/v2/load_balancer_interfaces/testing/request_test.go deleted file mode 100644 index 8048ebd..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/testing/request_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_interfaces" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListLoadBalancerInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - load_balancer_interfaces.List(client, load_balancer_interfaces.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := load_balancer_interfaces.ExtractLoadBalancerInterfaces(page) - if err != nil { - t.Errorf("Failed to extract Load Balancer Interfaces: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedLoadBalancerInterfaceSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetLoadBalancerInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces/5f3cae7c-58a5-4124-b622-9ca3cfbf2525", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := load_balancer_interfaces.Get(fake.ServiceClient(), "5f3cae7c-58a5-4124-b622-9ca3cfbf2525").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &LoadBalancerInterfaceDetail, s) -} - -func TestUpdateLoadBalancerInterface(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - description := "test" - ipAddress := "100.64.64.34" - name := "Interface 1/2" - networkID := interface{}("e6106a35-d79b-44a3-bda0-6009b2f8775a") - virtualIPAddress := interface{}("100.64.64.101") - virtualIPProperties := load_balancer_interfaces.VirtualIPProperties{ - Protocol: "vrrp", - Vrid: 10, - } - - id := "2897f333-3554-4099-a638-64d7022bf9ae" - slotNumber := 2 - - status := "PENDING_UPDATE" - - tenantID := "6a156ddf2ecd497ca786ff2da6df5aa8" - - loadBalancerID := "9f872504-36ab-46af-83ce-a4991c669edd" - - options := load_balancer_interfaces.UpdateOpts{ - Description: &description, - IPAddress: ipAddress, - Name: &name, - NetworkID: &networkID, - VirtualIPAddress: &virtualIPAddress, - VirtualIPProperties: &virtualIPProperties, - } - - s, err := load_balancer_interfaces.Update(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416", options).Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, description, s.Description) - th.CheckEquals(t, id, s.ID) - th.CheckEquals(t, ipAddress, *s.IPAddress) - th.CheckEquals(t, loadBalancerID, s.LoadBalancerID) - th.CheckEquals(t, name, s.Name) - th.CheckEquals(t, networkID, *s.NetworkID) - th.CheckEquals(t, slotNumber, s.SlotNumber) - th.CheckEquals(t, status, s.Status) - th.CheckEquals(t, tenantID, s.TenantID) - th.CheckEquals(t, virtualIPAddress, *s.VirtualIPAddress) - th.CheckDeepEquals(t, virtualIPProperties, *s.VirtualIPProperties) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - expectedID := "b409f68e-9307-4649-9073-bb3cb776bda5" - actualID, err := load_balancer_interfaces.IDFromName(client, "Interface 1/2") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_interfaces.IDFromName(client, "Interface X") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_interfaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_interfaces.IDFromName(client, "Interface 1/2") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/load_balancer_interfaces/urls.go b/v3/ecl/network/v2/load_balancer_interfaces/urls.go deleted file mode 100644 index e9ff953..0000000 --- a/v3/ecl/network/v2/load_balancer_interfaces/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package load_balancer_interfaces - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancer_interfaces", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("load_balancer_interfaces") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/load_balancer_plans/doc.go b/v3/ecl/network/v2/load_balancer_plans/doc.go deleted file mode 100644 index f5f38bc..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/doc.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Package load_balancer_plans contains functionality for working with -ECL Load Balancer Plan resources. - -Example to List Load Balancer Plans - - listOpts := load_balancer_plans.ListOpts{ - Description: "general", - } - - allPages, err := load_balancer_plans.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allLoadBalancerPlans, err := load_balancer_plans.ExtractLoadBalancerPlans(allPages) - if err != nil { - panic(err) - } - - for _, loadBalancerPlan := range allLoadBalancerPlans { - fmt.Printf("%+v\n", loadBalancerPlan) - } - -Example to Show Load Balancer Plan - - loadBalancerPlanID := "a46eeb5a-bc0a-40fa-b455-e5dc13b1220a" - - loadBalancerPlan, err := load_balancer_plans.Get(networkClient, loadBalancerPlanID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", loadBalancerPlan) - -*/ -package load_balancer_plans diff --git a/v3/ecl/network/v2/load_balancer_plans/requests.go b/v3/ecl/network/v2/load_balancer_plans/requests.go deleted file mode 100644 index a8436ae..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/requests.go +++ /dev/null @@ -1,88 +0,0 @@ -package load_balancer_plans - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Load Balancer Plan attributes you want to see returned. SortKey allows you to sort -// by a particular Load Balancer Plan attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - MaximumSyslogServers int `q:"maximum_syslog_servers"` - Name string `q:"name"` - Vendor string `q:"vendor"` - Version string `q:"version"` -} - -// ToLoadBalancerPlansListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToLoadBalancerPlansListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Load Balancer Plans. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those Load Balancer Plans that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOpts) pagination.Pager { - url := listURL(c) - query, err := opts.ToLoadBalancerPlansListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return LoadBalancerPlanPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific Load Balancer Plan based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// IDFromName is a convenience function that returns a Load Balancer Plan's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractLoadBalancerPlans(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "load_balancer_plan"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "load_balancer_plan"} - } -} diff --git a/v3/ecl/network/v2/load_balancer_plans/results.go b/v3/ecl/network/v2/load_balancer_plans/results.go deleted file mode 100644 index 836741f..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/results.go +++ /dev/null @@ -1,83 +0,0 @@ -package load_balancer_plans - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a Load Balancer Plan resource. -func (r commonResult) Extract() (*LoadBalancerPlan, error) { - var s struct { - LoadBalancerPlan *LoadBalancerPlan `json:"load_balancer_plan"` - } - err := r.ExtractInto(&s) - return s.LoadBalancerPlan, err -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Load Balancer Plan. -type GetResult struct { - commonResult -} - -// Model of Load Balancer. -type Model struct { - Edition string `json:"edition"` - Size string `json:"size"` -} - -// LoadBalancerPlan represents a Load Balancer Plan. See package documentation for a top-level -// description of what this is. -type LoadBalancerPlan struct { - - // Description is description - Description string `json:"description"` - - // Is user allowed to create new load balancers with this plan. - Enabled bool `json:"enabled"` - - // UUID representing the Load Balancer Plan. - ID string `json:"id"` - - // Maximum number of syslog servers - MaximumSyslogServers int `json:"maximum_syslog_servers"` - - // Model of load balancer - Model Model `json:"model"` - - // Name of the Load Balancer Plan - Name string `json:"name"` - - // Load Balancer Type - Vendor string `json:"vendor"` - - // Version name - Version string `json:"version"` -} - -// LoadBalancerPlanPage is the page returned by a pager when traversing over a collection -// of load balancer plans. -type LoadBalancerPlanPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a LoadBalancerPlanPage struct is empty. -func (r LoadBalancerPlanPage) IsEmpty() (bool, error) { - is, err := ExtractLoadBalancerPlans(r) - return len(is) == 0, err -} - -// ExtractLoadBalancerPlans accepts a Page struct, specifically a LoadBalancerPage struct, -// and extracts the elements into a slice of Load Balancer Plan structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractLoadBalancerPlans(r pagination.Page) ([]LoadBalancerPlan, error) { - var s struct { - LoadBalancerPlans []LoadBalancerPlan `json:"load_balancer_plans"` - } - err := (r.(LoadBalancerPlanPage)).ExtractInto(&s) - return s.LoadBalancerPlans, err -} diff --git a/v3/ecl/network/v2/load_balancer_plans/testing/doc.go b/v3/ecl/network/v2/load_balancer_plans/testing/doc.go deleted file mode 100644 index 6a790dc..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Load Balancer Plans unit tests -package testing diff --git a/v3/ecl/network/v2/load_balancer_plans/testing/fixtures.go b/v3/ecl/network/v2/load_balancer_plans/testing/fixtures.go deleted file mode 100644 index 9ffca0a..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/testing/fixtures.go +++ /dev/null @@ -1,132 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_plans" -) - -const ListResponse = ` -{ - "load_balancer_plans": [ - { - "description": "Load Balancer Description 1", - "enabled": true, - "id": "58ab4df4-10f2-4fa0-b374-74b06dd648ee", - "maximum_syslog_servers": 10, - "model": { - "edition": "Standard", - "size": "50" - }, - "name": "LB_Plan1", - "vendor": "citrix", - "version": "10.5-57.7" - }, - { - "description": "Load Balancer Description 2", - "enabled": false, - "id": "8b0cc5cc-b612-4810-ae45-7d6c5e806b3a", - "maximum_syslog_servers": 10, - "model": { - "edition": "Standard", - "size": "1000" - }, - "name": "LB_Plan2", - "vendor": "citrix", - "version": "10.5-57.7" - } - ] -} -` -const GetResponse = ` -{ - "load_balancer_plan": { - "description": "Load Balance Plan Description", - "enabled": true, - "id": "6e5faf0c-9361-4b98-bfc4-670497c9bde3", - "maximum_syslog_servers": 10, - "model": { - "edition": "Standard", - "size": "50" - }, - "name": "LB_Plan1", - "vendor": "citrix", - "version": "10.5-57.7" - } -} - ` - -var LoadBalancerPlan1 = load_balancer_plans.LoadBalancerPlan{ - Description: "Load Balancer Description 1", - Enabled: true, - ID: "58ab4df4-10f2-4fa0-b374-74b06dd648ee", - MaximumSyslogServers: 10, - Model: load_balancer_plans.Model{ - Edition: "Standard", - Size: "50", - }, - Name: "LB_Plan1", - Vendor: "citrix", - Version: "10.5-57.7", -} - -var LoadBalancerPlan2 = load_balancer_plans.LoadBalancerPlan{ - Description: "Load Balancer Description 2", - Enabled: false, - ID: "8b0cc5cc-b612-4810-ae45-7d6c5e806b3a", - MaximumSyslogServers: 10, - Model: load_balancer_plans.Model{ - Edition: "Standard", - Size: "1000", - }, - Name: "LB_Plan2", - Vendor: "citrix", - Version: "10.5-57.7", -} - -var LoadBalancerDetail = load_balancer_plans.LoadBalancerPlan{ - Description: "Load Balance Plan Description", - Enabled: true, - ID: "6e5faf0c-9361-4b98-bfc4-670497c9bde3", - MaximumSyslogServers: 10, - Model: load_balancer_plans.Model{ - Edition: "Standard", - Size: "50", - }, - Name: "LB_Plan1", - Vendor: "citrix", - Version: "10.5-57.7", -} - -var ExpectedLoadBalancerPlanSlice = []load_balancer_plans.LoadBalancerPlan{LoadBalancerPlan1, LoadBalancerPlan2} - -const ListResponseDuplicatedNames = ` -{ - "load_balancer_plans": [ - { - "description": "Load Balancer Description 1", - "enabled": true, - "id": "58ab4df4-10f2-4fa0-b374-74b06dd648ee", - "maximum_syslog_servers": 10, - "model": { - "edition": "Standard", - "size": "50" - }, - "name": "LB_Plan1", - "vendor": "citrix", - "version": "10.5-57.7" - }, - { - "description": "Load Balancer Description 2", - "enabled": false, - "id": "8b0cc5cc-b612-4810-ae45-7d6c5e806b3a", - "maximum_syslog_servers": 10, - "model": { - "edition": "Standard", - "size": "1000" - }, - "name": "LB_Plan1", - "vendor": "citrix", - "version": "10.5-57.7" - } - ] -} -` diff --git a/v3/ecl/network/v2/load_balancer_plans/testing/request_test.go b/v3/ecl/network/v2/load_balancer_plans/testing/request_test.go deleted file mode 100644 index 2c3f544..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/testing/request_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_plans" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListLoadBalancerPlan(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - load_balancer_plans.List(client, load_balancer_plans.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := load_balancer_plans.ExtractLoadBalancerPlans(page) - if err != nil { - t.Errorf("Failed to extract Load Balancer Plans: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedLoadBalancerPlanSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetLoadBalancerPlan(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_plans/5f3cae7c-58a5-4124-b622-9ca3cfbf2525", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := load_balancer_plans.Get(fake.ServiceClient(), "5f3cae7c-58a5-4124-b622-9ca3cfbf2525").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &LoadBalancerDetail, s) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - expectedID := "58ab4df4-10f2-4fa0-b374-74b06dd648ee" - actualID, err := load_balancer_plans.IDFromName(client, "LB_Plan1") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_plans.IDFromName(client, "LB_PlanX") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_plans.IDFromName(client, "LB_Plan1") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/load_balancer_plans/urls.go b/v3/ecl/network/v2/load_balancer_plans/urls.go deleted file mode 100644 index 3046da8..0000000 --- a/v3/ecl/network/v2/load_balancer_plans/urls.go +++ /dev/null @@ -1,19 +0,0 @@ -package load_balancer_plans - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancer_plans", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("load_balancer_plans") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/doc.go b/v3/ecl/network/v2/load_balancer_syslog_servers/doc.go deleted file mode 100644 index 623ddd3..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/doc.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Package load_balancer_syslog_servers contains functionality for working with -ECL Load Balancer Syslog Server resources. - -Example to List Load Balancer Syslog Servers - - listOpts := load_balancer_syslog_servers.ListOpts{ - Status: "ACTIVE", - } - - allPages, err := load_balancer_syslog_servers.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allLoadBalancerSyslogServers, err := load_balancer_syslog_servers.ExtractLoadBalancerSyslogServers(allPages) - if err != nil { - panic(err) - } - - for _, loadBalancerSyslogServer := range allLoadBalancerSyslogServers { - fmt.Printf("%+v\n", loadBalancerSyslogServer) - } - - -Example to Show Load Balancer Syslog Server - - loadBalancerSyslogServerID := "9ab7ab3c-38a6-417c-926b-93772c4eb2f9" - - loadBalancerSyslogServer, err := load_balancer_syslog_servers.Get(networkClient, loadBalancerSyslogServerID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", loadBalancerSyslogServer) - - -Example to Create a Load Balancer Syslog Server - - priority := 20 - - createOpts := load_balancer_syslog_servers.CreateOpts{ - AclLogging: "DISABLED", - AppflowLogging: "DISABLED", - DateFormat: "MMDDYYYY", - Description: "test", - IPAddress: "120.120.120.30", - LoadBalancerID: "4f6ebc24-f768-485b-99ef-f308063d0209", - LogFacility: "LOCAL3", - LogLevel: "DEBUG", - Name: "first_syslog_server", - PortNumber: 514, - Priority: &priority, - TcpLogging: "ALL", - TenantID: "b58531f716614e82a9bf001571c8bb15", - TimeZone: "LOCAL_TIME", - TransportType: "UDP", - UserConfigurableLogMessages: "NO", - } - - loadBalancerSyslogServer, err := load_balancer_syslog_servers.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Load Balancer Syslog Server - - loadBalancerSyslogServerID := "9ab7ab3c-38a6-417c-926b-93772c4eb2f9" - description := "new_description" - - updateOpts := load_balancer_syslog_servers.UpdateOpts{ - Description: &description, - } - - loadBalancerSyslogServer, err := load_balancer_syslog_servers.Update(networkClient, loadBalancerSyslogServerID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Load Balancer Syslog Server - - loadBalancerSyslogServerID := "13762eaf-9564-4c94-a106-98ece9fa189e" - err := load_balancer_syslog_servers.Delete(networkClient, loadBalancerSyslogServerID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package load_balancer_syslog_servers diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/requests.go b/v3/ecl/network/v2/load_balancer_syslog_servers/requests.go deleted file mode 100644 index bf456d6..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/requests.go +++ /dev/null @@ -1,233 +0,0 @@ -package load_balancer_syslog_servers - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Load Balancer Syslog Server attributes you want to see returned. SortKey allows you to sort -// by a particular Load Balancer Syslog Server attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - IPAddress string `q:"ip_address"` - LoadBalancerID string `q:"load_balancer_id"` - LogFacility string `q:"log_facility"` - LogLevel string `q:"log_level"` - Name string `q:"name"` - PortNumber int `q:"port_number"` - Status string `q:"status"` - TransportType string `q:"transport_type"` -} - -// ToLoadBalancerSyslogServersListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToLoadBalancerSyslogServersListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Load Balancer Syslog Servers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those Load Balancer Syslog Servers that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOpts) pagination.Pager { - url := listURL(c) - query, err := opts.ToLoadBalancerSyslogServersListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return LoadBalancerSyslogServerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific Load Balancer Syslog Server based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOpts represents the attributes used when creating a new Load Balancer Syslog Server. -type CreateOpts struct { - - // should syslog record acl info - AclLogging string `json:"acl_logging,omitempty"` - - // should syslog record appflow info - AppflowLogging string `json:"appflow_logging,omitempty"` - - // date format utilized by syslog - DateFormat string `json:"date_format,omitempty"` - - // Description is description - Description string `json:"description,omitempty"` - - // Ip address of syslog server - IPAddress string `json:"ip_address" required:"true"` - - // The ID of load_balancer this load_balancer_syslog_server belongs to. - LoadBalancerID string `json:"load_balancer_id" required:"true"` - - // Log facility for syslog - LogFacility string `json:"log_facility,omitempty"` - - // Log level for syslog - LogLevel string `json:"log_level,omitempty"` - - // Name is a human-readable name of the Load Balancer Syslog Server. - Name string `json:"name" required:"true"` - - // Port number of syslog server - PortNumber int `json:"port_number,omitempty"` - - // priority (0-255) - Priority *int `json:"priority,omitempty"` - - // should syslog record tcp protocol info - TcpLogging string `json:"tcp_logging,omitempty"` - - // The UUID of the project who owns the Load Balancer Syslog Server. Only administrative users - // can specify a project UUID other than their own. - TenantID string `json:"tenant_id,omitempty"` - - // time zone utilized by syslog - TimeZone string `json:"time_zone,omitempty"` - - // protocol for syslog transport - TransportType string `json:"transport_type,omitempty"` - - // can user configure log messages - UserConfigurableLogMessages string `json:"user_configurable_log_messages,omitempty"` -} - -// ToLoadBalancerSyslogServerCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToLoadBalancerSyslogServerCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "load_balancer_syslog_server") - if err != nil { - return nil, err - } - - return b, nil -} - -// Create accepts a CreateOpts struct and creates a new Load Balancer Syslog Server using the values -// provided. You must remember to provide a valid LoadBalancerPlanID. -func Create(c *eclcloud.ServiceClient, opts CreateOpts) (r CreateResult) { - b, err := opts.ToLoadBalancerSyslogServerCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// UpdateOpts represents the attributes used when updating an existing Load Balancer Syslog Server. -type UpdateOpts struct { - - // should syslog record acl info - AclLogging string `json:"acl_logging,omitempty"` - - // should syslog record appflow info - AppflowLogging string `json:"appflow_logging,omitempty"` - - // date format utilized by syslog - DateFormat string `json:"date_format,omitempty"` - - // Description is description - Description *string `json:"description,omitempty"` - - // Log facility for syslog - LogFacility string `json:"log_facility,omitempty"` - - // Log level for syslog - LogLevel string `json:"log_level,omitempty"` - - // priority (0-255) - Priority *int `json:"priority,omitempty"` - - // should syslog record tcp protocol info - TcpLogging string `json:"tcp_logging,omitempty"` - - // time zone utilized by syslog - TimeZone string `json:"time_zone,omitempty"` - - // can user configure log messages - UserConfigurableLogMessages string `json:"user_configurable_log_messages,omitempty"` -} - -// ToLoadBalancerSyslogServerUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToLoadBalancerSyslogServerUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "load_balancer_syslog_server") - if err != nil { - return nil, err - } - - return b, nil -} - -// Update accepts a UpdateOpts struct and updates an existing Load Balancer Syslog Server using the -// values provided. -func Update(c *eclcloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { - b, err := opts.ToLoadBalancerSyslogServerUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete accepts a unique ID and deletes the Load Balancer Syslog Server associated with it. -func Delete(c *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, id), nil) - return -} - -// IDFromName is a convenience function that returns a Load Balancer Syslog Server's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractLoadBalancerSyslogServers(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "load_balancer_syslog_server"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "load_balancer_syslog_server"} - } -} diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/results.go b/v3/ecl/network/v2/load_balancer_syslog_servers/results.go deleted file mode 100644 index 262c3e1..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/results.go +++ /dev/null @@ -1,125 +0,0 @@ -package load_balancer_syslog_servers - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a Load Balancer Syslog Server resource. -func (r commonResult) Extract() (*LoadBalancerSyslogServer, error) { - var s struct { - LoadBalancerSyslogServer *LoadBalancerSyslogServer `json:"load_balancer_syslog_server"` - } - err := r.ExtractInto(&s) - return s.LoadBalancerSyslogServer, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Load Balancer Syslog Server. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Load Balancer Syslog Server. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Load Balancer Syslog Server. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// LoadBalancerSyslogServer represents a Load Balancer Syslog Server. See package documentation for a top-level -// description of what this is. -type LoadBalancerSyslogServer struct { - - // should syslog record acl info - AclLogging string `json:"acl_logging"` - - // should syslog record appflow info - AppflowLogging string `json:"appflow_logging"` - - // date format utilized by syslog - DateFormat string `json:"date_format"` - - // Description is description - Description string `json:"description"` - - // UUID representing the Load Balancer Syslog Server. - ID string `json:"id"` - - // Ip address of syslog server - IPAddress string `json:"ip_address"` - - // The ID of load_balancer this load_balancer_syslog_server belongs to. - LoadBalancerID string `json:"load_balancer_id"` - - // Log facility for syslog - LogFacility string `json:"log_facility"` - - // Log level for syslog - LogLevel string `json:"log_level"` - - // Name of the syslog resource - Name string `json:"name"` - - // Port number of syslog server - PortNumber int `json:"port_number"` - - // priority (0-255) - Priority int `json:"priority"` - - // Load balancer syslog server status - Status string `json:"status"` - - // should syslog record tcp protocol info - TcpLogging string `json:"tcp_logging"` - - // TenantID is the project owner of the Load Balancer Syslog Server. - TenantID string `json:"tenant_id"` - - // time zone utilized by syslog - TimeZone string `json:"time_zone"` - - // protocol for syslog transport - TransportType string `json:"transport_type"` - - // can user configure log messages - UserConfigurableLogMessages string `json:"user_configurable_log_messages"` -} - -// LoadBalancerSyslogServerPage is the page returned by a pager when traversing over a collection -// of load balancer Syslog Servers. -type LoadBalancerSyslogServerPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a LoadBalancerSyslogServerPage struct is empty. -func (r LoadBalancerSyslogServerPage) IsEmpty() (bool, error) { - is, err := ExtractLoadBalancerSyslogServers(r) - return len(is) == 0, err -} - -// ExtractLoadBalancerSyslogServers accepts a Page struct, specifically a LoadBalancerSyslogServerPage struct, -// and extracts the elements into a slice of Load Balancer Syslog Server structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractLoadBalancerSyslogServers(r pagination.Page) ([]LoadBalancerSyslogServer, error) { - var s struct { - LoadBalancerSyslogServers []LoadBalancerSyslogServer `json:"load_balancer_syslog_servers"` - } - err := (r.(LoadBalancerSyslogServerPage)).ExtractInto(&s) - return s.LoadBalancerSyslogServers, err -} diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/doc.go b/v3/ecl/network/v2/load_balancer_syslog_servers/testing/doc.go deleted file mode 100644 index 1593aa9..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Load Balancer Syslog Servers unit tests -package testing diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/fixtures.go b/v3/ecl/network/v2/load_balancer_syslog_servers/testing/fixtures.go deleted file mode 100644 index 3da58ff..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/fixtures.go +++ /dev/null @@ -1,226 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_syslog_servers" -) - -const ListResponse = ` -{ - "load_balancer_syslog_servers": [ - { - "description": "test", - "id": "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "status": "ACTIVE", - "transport_type": "UDP" - }, - { - "description": "My second backup server", - "id": "c7de2dee-73a0-4a9b-acdf-8a348c242a30", - "ip_address": "120.120.122.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL2", - "log_level": "ERROR", - "name": "second_syslog_server", - "port_number": 514, - "status": "ACTIVE", - "transport_type": "UDP" - } - ] -} -` -const GetResponse = ` -{ - "load_balancer_syslog_server": { - "acl_logging": "DISABLED", - "appflow_logging": "DISABLED", - "date_format": "MMDDYYYY", - "description": "test", - "id": "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "priority": 20, - "status": "ACTIVE", - "tcp_logging": "ALL", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "time_zone": "LOCAL_TIME", - "transport_type": "UDP", - "user_configurable_log_messages": "NO" - } -} -` -const CreateResponse = ` -{ - "load_balancer_syslog_server": { - "acl_logging": "DISABLED", - "appflow_logging": "DISABLED", - "date_format": "MMDDYYYY", - "description": "test", - "id": "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "priority": 20, - "status": "ACTIVE", - "tcp_logging": "ALL", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "time_zone": "LOCAL_TIME", - "transport_type": "UDP", - "user_configurable_log_messages": "NO" - } -} -` -const CreateRequest = ` -{ - "load_balancer_syslog_server": { - "acl_logging": "DISABLED", - "appflow_logging": "DISABLED", - "date_format": "MMDDYYYY", - "description": "test", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "priority": 20, - "tcp_logging": "ALL", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "time_zone": "LOCAL_TIME", - "transport_type": "UDP", - "user_configurable_log_messages": "NO" - } -} -` -const UpdateResponse = ` -{ - "load_balancer_syslog_server": { - "acl_logging": "DISABLED", - "appflow_logging": "DISABLED", - "date_format": "MMDDYYYY", - "description": "test2", - "id": "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "priority": 20, - "status": "PENDING_UPDATE", - "tcp_logging": "ALL", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "time_zone": "LOCAL_TIME", - "transport_type": "UDP", - "user_configurable_log_messages": "NO" - } -} -` -const UpdateRequest = ` -{ - "load_balancer_syslog_server": { - "acl_logging": "DISABLED", - "appflow_logging": "DISABLED", - "date_format": "MMDDYYYY", - "description": "test2", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "priority": 20, - "tcp_logging": "ALL", - "time_zone": "LOCAL_TIME", - "user_configurable_log_messages": "NO" - } -} -` - -var LoadBalancerSyslogServer1 = load_balancer_syslog_servers.LoadBalancerSyslogServer{ - Description: "test", - ID: "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - IPAddress: "120.120.120.30", - LoadBalancerID: "9f872504-36ab-46af-83ce-a4991c669edd", - LogFacility: "LOCAL3", - LogLevel: "DEBUG", - Name: "first_syslog_server", - PortNumber: 514, - Status: "ACTIVE", - TransportType: "UDP", -} - -var LoadBalancerSyslogServer2 = load_balancer_syslog_servers.LoadBalancerSyslogServer{ - Description: "My second backup server", - ID: "c7de2dee-73a0-4a9b-acdf-8a348c242a30", - IPAddress: "120.120.122.30", - LoadBalancerID: "9f872504-36ab-46af-83ce-a4991c669edd", - LogFacility: "LOCAL2", - LogLevel: "ERROR", - Name: "second_syslog_server", - PortNumber: 514, - Status: "ACTIVE", - TransportType: "UDP", -} - -var LoadBalancerSyslogServerDetail = load_balancer_syslog_servers.LoadBalancerSyslogServer{ - AclLogging: "DISABLED", - AppflowLogging: "DISABLED", - DateFormat: "MMDDYYYY", - Description: "test", - ID: "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - IPAddress: "120.120.120.30", - LoadBalancerID: "9f872504-36ab-46af-83ce-a4991c669edd", - LogFacility: "LOCAL3", - LogLevel: "DEBUG", - Name: "first_syslog_server", - PortNumber: 514, - Priority: 20, - Status: "ACTIVE", - TcpLogging: "ALL", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - TimeZone: "LOCAL_TIME", - TransportType: "UDP", - UserConfigurableLogMessages: "NO", -} - -var ExpectedLoadBalancerSlice = []load_balancer_syslog_servers.LoadBalancerSyslogServer{LoadBalancerSyslogServer1, LoadBalancerSyslogServer2} - -const ListResponseDuplicatedNames = ` -{ - "load_balancer_syslog_servers": [ - { - "description": "test", - "id": "6e9c7745-61f2-491f-9689-add8c5fc4b9a", - "ip_address": "120.120.120.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL3", - "log_level": "DEBUG", - "name": "first_syslog_server", - "port_number": 514, - "status": "ACTIVE", - "transport_type": "UDP" - }, - { - "description": "My second backup server", - "id": "c7de2dee-73a0-4a9b-acdf-8a348c242a30", - "ip_address": "120.120.122.30", - "load_balancer_id": "9f872504-36ab-46af-83ce-a4991c669edd", - "log_facility": "LOCAL2", - "log_level": "ERROR", - "name": "first_syslog_server", - "port_number": 514, - "status": "ACTIVE", - "transport_type": "UDP" - } - ] -} -` diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/request_test.go b/v3/ecl/network/v2/load_balancer_syslog_servers/testing/request_test.go deleted file mode 100644 index 8117e0a..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/testing/request_test.go +++ /dev/null @@ -1,276 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_syslog_servers" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - load_balancer_syslog_servers.List(client, load_balancer_syslog_servers.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := load_balancer_syslog_servers.ExtractLoadBalancerSyslogServers(page) - if err != nil { - t.Errorf("Failed to extract Load Balancer Syslog Servers: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedLoadBalancerSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers/6e9c7745-61f2-491f-9689-add8c5fc4b9a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := load_balancer_syslog_servers.Get(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &LoadBalancerSyslogServerDetail, s) -} - -func TestCreateLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - priority := 20 - - options := load_balancer_syslog_servers.CreateOpts{ - AclLogging: "DISABLED", - AppflowLogging: "DISABLED", - DateFormat: "MMDDYYYY", - Description: "test", - IPAddress: "120.120.120.30", - LoadBalancerID: "9f872504-36ab-46af-83ce-a4991c669edd", - LogFacility: "LOCAL3", - LogLevel: "DEBUG", - Name: "first_syslog_server", - PortNumber: 514, - Priority: &priority, - TcpLogging: "ALL", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - TimeZone: "LOCAL_TIME", - TransportType: "UDP", - UserConfigurableLogMessages: "NO", - } - s, err := load_balancer_syslog_servers.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &LoadBalancerSyslogServerDetail, s) -} - -func TestRequiredCreateOptsLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := load_balancer_syslog_servers.Create(fake.ServiceClient(), load_balancer_syslog_servers.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdateLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers/6e9c7745-61f2-491f-9689-add8c5fc4b9a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - aclLogging := "DISABLED" - appflowLogging := "DISABLED" - dateFormat := "MMDDYYYY" - description := "test2" - logFacility := "LOCAL3" - logLevel := "DEBUG" - priority := 20 - tcpLogging := "ALL" - timeZone := "LOCAL_TIME" - userConfigurableLogMessages := "NO" - - id := "6e9c7745-61f2-491f-9689-add8c5fc4b9a" - - ipAddress := "120.120.120.30" - loadBalancerID := "9f872504-36ab-46af-83ce-a4991c669edd" - name := "first_syslog_server" - portNumber := 514 - status := "PENDING_UPDATE" - tenantID := "6a156ddf2ecd497ca786ff2da6df5aa8" - transportType := "UDP" - - options := load_balancer_syslog_servers.UpdateOpts{ - AclLogging: aclLogging, - AppflowLogging: appflowLogging, - DateFormat: dateFormat, - Description: &description, - LogFacility: logFacility, - LogLevel: logLevel, - Priority: &priority, - TcpLogging: tcpLogging, - TimeZone: timeZone, - UserConfigurableLogMessages: userConfigurableLogMessages, - } - - s, err := load_balancer_syslog_servers.Update(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a", options).Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, aclLogging, s.AclLogging) - th.CheckEquals(t, appflowLogging, s.AppflowLogging) - th.CheckEquals(t, dateFormat, s.DateFormat) - th.CheckEquals(t, description, s.Description) - th.CheckEquals(t, id, s.ID) - th.CheckEquals(t, logFacility, s.LogFacility) - th.CheckEquals(t, logLevel, s.LogLevel) - th.CheckEquals(t, priority, s.Priority) - th.CheckEquals(t, tcpLogging, s.TcpLogging) - th.CheckEquals(t, timeZone, s.TimeZone) - th.CheckEquals(t, userConfigurableLogMessages, s.UserConfigurableLogMessages) - th.CheckEquals(t, ipAddress, s.IPAddress) - th.CheckEquals(t, loadBalancerID, s.LoadBalancerID) - th.CheckEquals(t, name, s.Name) - th.CheckEquals(t, portNumber, s.PortNumber) - th.CheckEquals(t, status, s.Status) - th.CheckEquals(t, tenantID, s.TenantID) - th.CheckEquals(t, transportType, s.TransportType) - -} - -func TestDeleteLoadBalancerSyslogServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers/6e9c7745-61f2-491f-9689-add8c5fc4b9a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := load_balancer_syslog_servers.Delete(fake.ServiceClient(), "6e9c7745-61f2-491f-9689-add8c5fc4b9a") - th.AssertNoErr(t, res.Err) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - expectedID := "6e9c7745-61f2-491f-9689-add8c5fc4b9a" - actualID, err := load_balancer_syslog_servers.IDFromName(client, "first_syslog_server") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_syslog_servers.IDFromName(client, "syslog_server X") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancer_syslog_servers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := fake.ServiceClient() - - _, err := load_balancer_syslog_servers.IDFromName(client, "first_syslog_server") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/load_balancer_syslog_servers/urls.go b/v3/ecl/network/v2/load_balancer_syslog_servers/urls.go deleted file mode 100644 index 4fd634f..0000000 --- a/v3/ecl/network/v2/load_balancer_syslog_servers/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package load_balancer_syslog_servers - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancer_syslog_servers", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("load_balancer_syslog_servers") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/load_balancers/doc.go b/v3/ecl/network/v2/load_balancers/doc.go deleted file mode 100644 index e4b5a81..0000000 --- a/v3/ecl/network/v2/load_balancers/doc.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Package load_balancers contains functionality for working with -ECL Load Balancer resources. - -Example to List Load Balancers - - listOpts := load_balancers.ListOpts{ - Status: "ACTIVE", - } - - allPages, err := load_balancers.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allLoadBalancers, err := load_balancers.ExtractLoadBalancers(allPages) - if err != nil { - panic(err) - } - - for _, loadBalancer := range allLoadBalancers { - fmt.Printf("%+v\n", loadBalancer) - } - - -Example to Show Load Balancer - - loadBalancerID := "f44e063c-5fea-45b8-9124-956995eafe2a" - - loadBalancer, err := load_balancers.Get(networkClient, loadBalancerID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", loadBalancer) - - -Example to Create a Load Balancer - - createOpts := load_balancers.CreateOpts{ - AvailabilityZone: "zone1-groupa", - Description: "Load Balancer 1", - LoadBalancerPlanID: "69bf1e91-73f6-41d5-84c4-91de21a9af05", - Name: "abcdefghijklmnopqrstuvwxyz", - TenantID: "5cc454d62d8c4a0595134b2632bf2263", - } - - loadBalancer, err := load_balancers.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Load Balancer - - loadBalancerID := "f44e063c-5fea-45b8-9124-956995eafe2a" - name := "new_name" - - updateOpts := load_balancers.UpdateOpts{ - Name: &name, - } - - loadBalancer, err := load_balancers.Update(networkClient, loadBalancerID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Load Balancer - - loadBalancerID := "165fb257-2365-4c05-b368-a7bed21bb927" - err := load_balancers.Delete(networkClient, loadBalancerID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package load_balancers diff --git a/v3/ecl/network/v2/load_balancers/requests.go b/v3/ecl/network/v2/load_balancers/requests.go deleted file mode 100644 index 06dab83..0000000 --- a/v3/ecl/network/v2/load_balancers/requests.go +++ /dev/null @@ -1,182 +0,0 @@ -package load_balancers - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Load Balancer attributes you want to see returned. SortKey allows you to sort -// by a particular Load Balancer attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - AdminUsername string `q:"admin_username"` - AvailabilityZone string `q:"availability_zone"` - DefaultGateway string `q:"default_gateway"` - Description string `q:"description"` - ID string `q:"id"` - LoadBalancerPlanID string `q:"load_balancer_plan_id"` - Name string `q:"name"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - UserUsername string `q:"user_username"` -} - -// ToLoadBalancersListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToLoadBalancersListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Load Balancers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those Load Balancers that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOpts) pagination.Pager { - url := listURL(c) - query, err := opts.ToLoadBalancersListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return LoadBalancerPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific Load Balancer based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOpts represents the attributes used when creating a new Load Balancer. -type CreateOpts struct { - - // AvailabilityZone is one of the Virtual Server (Nova)’s availability zone. - AvailabilityZone string `json:"availability_zone,omitempty"` - - // Description is description - Description string `json:"description,omitempty"` - - // LoadBalancerPlanID is the UUID of Load Balancer Plan. - LoadBalancerPlanID string `json:"load_balancer_plan_id" required:"true"` - - // Name is a human-readable name of the Load Balancer. - Name string `json:"name,omitempty"` - - // The UUID of the project who owns the Load Balancer. Only administrative users - // can specify a project UUID other than their own. - TenantID string `json:"tenant_id,omitempty"` -} - -// ToLoadBalancerCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToLoadBalancerCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "load_balancer") - if err != nil { - return nil, err - } - - return b, nil -} - -// Create accepts a CreateOpts struct and creates a new Load Balancer using the values -// provided. You must remember to provide a valid LoadBalancerPlanID. -func Create(c *eclcloud.ServiceClient, opts CreateOpts) (r CreateResult) { - b, err := opts.ToLoadBalancerCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{201}, - }) - return -} - -// UpdateOpts represents the attributes used when updating an existing Load Balancer. -type UpdateOpts struct { - - // Description is description - DefaultGateway *interface{} `json:"default_gateway,omitempty"` - - // Description is description - Description *string `json:"description,omitempty"` - - // LoadBalancerPlanID is the UUID of Load Balancer Plan. - LoadBalancerPlanID string `json:"load_balancer_plan_id,omitempty"` - - // Name is a human-readable name of the Load Balancer. - Name *string `json:"name,omitempty"` -} - -// ToLoadBalancerUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToLoadBalancerUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "load_balancer") - if err != nil { - return nil, err - } - - return b, nil -} - -// Update accepts a UpdateOpts struct and updates an existing Load Balancer using the -// values provided. -func Update(c *eclcloud.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { - b, err := opts.ToLoadBalancerUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete accepts a unique ID and deletes the Load Balancer associated with it. -func Delete(c *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, id), nil) - return -} - -// IDFromName is a convenience function that returns a Load Balancer's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractLoadBalancers(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "load_balancer"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "load_balancer"} - } -} diff --git a/v3/ecl/network/v2/load_balancers/results.go b/v3/ecl/network/v2/load_balancers/results.go deleted file mode 100644 index 3f884af..0000000 --- a/v3/ecl/network/v2/load_balancers/results.go +++ /dev/null @@ -1,115 +0,0 @@ -package load_balancers - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_interfaces" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_syslog_servers" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a Load Balancer resource. -func (r commonResult) Extract() (*LoadBalancer, error) { - var s struct { - LoadBalancer *LoadBalancer `json:"load_balancer"` - } - err := r.ExtractInto(&s) - return s.LoadBalancer, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Load Balancer. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Load Balancer. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Load Balancer. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// LoadBalancer represents a Load Balancer. See package documentation for a top-level -// description of what this is. -type LoadBalancer struct { - - // AdminPassword is admin's password - AdminPassword string `json:"admin_password"` - - // AdminUsername is admin's username - AdminUsername string `json:"admin_username"` - - // AvailabilityZone is one of the Virtual Server (Nova)’s availability zone. - AvailabilityZone string `json:"availability_zone"` - - // Description is description - DefaultGateway *string `json:"default_gateway"` - - // Description is description - Description string `json:"description"` - - // UUID representing the Load Balancer. - ID string `json:"id"` - - // Attached interfaces by Load Balancer. - Interfaces []load_balancer_interfaces.LoadBalancerInterface `json:"interfaces"` - - // LoadBalancerPlanID is the UUID of Load Balancer Plan. - LoadBalancerPlanID string `json:"load_balancer_plan_id"` - - // Name of the Load Balancer. - Name string `json:"name"` - - // The Load Balancer status. - Status string `json:"status"` - - // Connected syslog servers. - SyslogServers []load_balancer_syslog_servers.LoadBalancerSyslogServer `json:"syslog_servers"` - - // TenantID is the project owner of the Load Balancer. - TenantID string `json:"tenant_id"` - - // User's password placeholder. - UserPassword string `json:"user_password"` - - // User's username placeholder. - UserUsername string `json:"user_username"` -} - -// LoadBalancerPage is the page returned by a pager when traversing over a collection -// of load balancers. -type LoadBalancerPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a LoadBalancerPage struct is empty. -func (r LoadBalancerPage) IsEmpty() (bool, error) { - is, err := ExtractLoadBalancers(r) - return len(is) == 0, err -} - -// ExtractLoadBalancers accepts a Page struct, specifically a LoadBalancerPage struct, -// and extracts the elements into a slice of Load Balancer structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractLoadBalancers(r pagination.Page) ([]LoadBalancer, error) { - var s struct { - LoadBalancers []LoadBalancer `json:"load_balancers"` - } - err := (r.(LoadBalancerPage)).ExtractInto(&s) - return s.LoadBalancers, err -} diff --git a/v3/ecl/network/v2/load_balancers/testing/doc.go b/v3/ecl/network/v2/load_balancers/testing/doc.go deleted file mode 100644 index 22e7d91..0000000 --- a/v3/ecl/network/v2/load_balancers/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Load Balancers unit tests -package testing diff --git a/v3/ecl/network/v2/load_balancers/testing/fixtures.go b/v3/ecl/network/v2/load_balancers/testing/fixtures.go deleted file mode 100644 index 9b9a9a8..0000000 --- a/v3/ecl/network/v2/load_balancers/testing/fixtures.go +++ /dev/null @@ -1,370 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_interfaces" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_syslog_servers" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancers" -) - -const ListResponse = ` -{ - "load_balancers": [ - { - "admin_username": "user-admin", - "availability_zone": "zone1-groupa", - "default_gateway": "100.127.253.1", - "description": "Load Balancer 1 Description", - "id": "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 1", - "status": "ACTIVE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - }, - { - "admin_username": "user-admin", - "availability_zone": "zone1_groupa", - "default_gateway": null, - "description": "abcdefghijklmnopqrstuvwxyz", - "id": "601665cf-c161-4e80-87f0-a3c0925d07a0", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 2", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - } - ] -} -` -const GetResponse = ` -{ - "load_balancer": { - "admin_username": "user-admin", - "availability_zone": "zone1-groupa", - "default_gateway": "100.127.253.1", - "description": "Load Balancer 1 Description", - "id": "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - "interfaces": [ - { - "id": "ee335c69-b50f-4a32-9d0f-f44cef84a456", - "ip_address": "100.127.253.173", - "name": "Interface 1/1", - "network_id": "c7f88fab-573e-47aa-b0b4-257db28dae23", - "slot_number": 1, - "status": "ACTIVE", - "type": "user", - "virtual_ip_address": "100.127.253.174", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - }, - { - "id": "b39b61e4-00b1-4698-aed0-1928beb90abe", - "ip_address": "192.168.110.1", - "name": "Interface 1/2", - "network_id": "1839d290-721c-49ba-99f1-3d7aa37811b0", - "slot_number": 2, - "status": "ACTIVE", - "type": "user", - "virtual_ip_address": null, - "virtual_ip_properties": null - } - ], - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 1", - "status": "ACTIVE", - "syslog_servers": [ - { - "id": "11001101-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.215", - "log_facility": "LOCAL0", - "log_level": "ALERT|INFO|ERROR", - "name": "syslog_server_main", - "port_number": 514, - "status": "ACTIVE" - }, - { - "id": "22002202-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.211", - "log_facility": "LOCAL1", - "log_level": "ERROR", - "name": "syslog_server_backup_fst", - "port_number": 514, - "status": "ACTIVE" - } - ], - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - } -} - ` -const CreateResponse = ` -{ - "load_balancer": { - "admin_username": "user-admin", - "availability_zone": "zone1-groupa", - "default_gateway": "100.127.253.1", - "description": "Load Balancer 1 Description", - "id": "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - "interfaces": [ - { - "id": "ee335c69-b50f-4a32-9d0f-f44cef84a456", - "ip_address": "100.127.253.173", - "name": "Interface 1/1", - "network_id": "c7f88fab-573e-47aa-b0b4-257db28dae23", - "slot_number": 1, - "status": "ACTIVE", - "type": "user", - "virtual_ip_address": "100.127.253.174", - "virtual_ip_properties": { - "protocol": "vrrp", - "vrid": 10 - } - }, - { - "id": "b39b61e4-00b1-4698-aed0-1928beb90abe", - "ip_address": "192.168.110.1", - "name": "Interface 1/2", - "network_id": "1839d290-721c-49ba-99f1-3d7aa37811b0", - "slot_number": 2, - "status": "ACTIVE", - "type": "user", - "virtual_ip_address": null, - "virtual_ip_properties": null - } - ], - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 1", - "status": "ACTIVE", - "syslog_servers": [ - { - "id": "11001101-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.215", - "log_facility": "LOCAL0", - "log_level": "ALERT|INFO|ERROR", - "name": "syslog_server_main", - "port_number": 514, - "status": "ACTIVE" - }, - { - "id": "22002202-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.211", - "log_facility": "LOCAL1", - "log_level": "ERROR", - "name": "syslog_server_backup_fst", - "port_number": 514, - "status": "ACTIVE" - } - ], - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - } -} - ` -const CreateRequest = ` -{ - "load_balancer": { - "availability_zone": "zone1-groupa", - "description": "abcdefghijklmnopqrstuvwxyz", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "abcdefghijklmnopqrstuvwxyz", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - } -} -` -const UpdateResponse = ` -{ - "load_balancer": { - "admin_username": "user-admin", - "availability_zone": "zone1-groupa", - "default_gateway": "100.127.253.1", - "description": "UPDATED", - "id": "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - "interfaces": [ - { - "id": "ee335c69-b50f-4a32-9d0f-f44cef84a456", - "ip_address": "100.127.253.173", - "name": "Interface 1/1", - "network_id": "c7f88fab-573e-47aa-b0b4-257db28dae23", - "slot_number": 1, - "status": "ACTIVE", - "virtual_ip_address": null, - "virtual_ip_properties": null - }, - { - "id": "b39b61e4-00b1-4698-aed0-1928beb90abe", - "ip_address": "192.168.110.1", - "name": "Interface 1/2", - "network_id": "1839d290-721c-49ba-99f1-3d7aa37811b0", - "slot_number": 2, - "status": "ACTIVE", - "virtual_ip_address": null, - "virtual_ip_properties": null - } - ], - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "abcdefghijklmnopqrstuvwxyz", - "status": "PENDING_UPDATE", - "syslog_servers": [ - { - "id": "11001101-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.215", - "log_facility": "LOCAL0", - "log_level": "ALERT|INFO|ERROR", - "name": "syslog_server_main", - "port_number": 514, - "status": "ACTIVE" - }, - { - "id": "22002202-2edf-1844-1ff7-12ba5b7e566a", - "ip_address": "177.77.07.211", - "log_facility": "LOCAL1", - "log_level": "ERROR", - "name": "syslog_server_backup_fst", - "port_number": 514, - "status": "ACTIVE" - } - ], - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - } -} -` -const UpdateRequest = ` -{ - "load_balancer": { - "default_gateway": "100.127.253.1", - "description": "UPDATED", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "abcdefghijklmnopqrstuvwxyz" - } -} -` - -var LoadBalancer1 = load_balancers.LoadBalancer{ - ID: "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - AdminUsername: "user-admin", - AvailabilityZone: "zone1-groupa", - DefaultGateway: &DetailDefaultGateway, - Description: "Load Balancer 1 Description", - LoadBalancerPlanID: "bd12784a-c66e-4f13-9f72-5143d64762b6", - Name: "Load Balancer 1", - Status: "ACTIVE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - UserUsername: "user-read", -} - -var LoadBalancer2 = load_balancers.LoadBalancer{ - ID: "601665cf-c161-4e80-87f0-a3c0925d07a0", - AdminUsername: "user-admin", - AvailabilityZone: "zone1_groupa", - Description: "abcdefghijklmnopqrstuvwxyz", - LoadBalancerPlanID: "bd12784a-c66e-4f13-9f72-5143d64762b6", - Name: "Load Balancer 2", - Status: "PENDING_CREATE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - UserUsername: "user-read", -} - -var DetailDefaultGateway = "100.127.253.1" -var DetailIPAddress1 = "100.127.253.173" -var DetailNetworkID1 = "c7f88fab-573e-47aa-b0b4-257db28dae23" -var DetailVirtualIPAddress1 = "100.127.253.174" - -var DetailIPAddress2 = "192.168.110.1" -var DetailNetworkID2 = "1839d290-721c-49ba-99f1-3d7aa37811b0" - -var VirtualIPPropertiesProtocol = "vrrp" -var VirtualIPPropertiesVrid = 10 - -var LoadBalancerDetail = load_balancers.LoadBalancer{ - ID: "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - AdminUsername: "user-admin", - AvailabilityZone: "zone1-groupa", - DefaultGateway: &DetailDefaultGateway, - Description: "Load Balancer 1 Description", - Interfaces: []load_balancer_interfaces.LoadBalancerInterface{ - { - ID: "ee335c69-b50f-4a32-9d0f-f44cef84a456", - IPAddress: &DetailIPAddress1, - Name: "Interface 1/1", - NetworkID: &DetailNetworkID1, - SlotNumber: 1, - Status: "ACTIVE", - Type: "user", - VirtualIPAddress: &DetailVirtualIPAddress1, - VirtualIPProperties: &load_balancer_interfaces.VirtualIPProperties{ - Protocol: VirtualIPPropertiesProtocol, - Vrid: VirtualIPPropertiesVrid, - }, - }, - { - ID: "b39b61e4-00b1-4698-aed0-1928beb90abe", - IPAddress: &DetailIPAddress2, - Name: "Interface 1/2", - NetworkID: &DetailNetworkID2, - SlotNumber: 2, - Status: "ACTIVE", - Type: "user", - }, - }, - LoadBalancerPlanID: "bd12784a-c66e-4f13-9f72-5143d64762b6", - Name: "Load Balancer 1", - Status: "ACTIVE", - SyslogServers: []load_balancer_syslog_servers.LoadBalancerSyslogServer{ - { - ID: "11001101-2edf-1844-1ff7-12ba5b7e566a", - IPAddress: "177.77.07.215", - LogFacility: "LOCAL0", - LogLevel: "ALERT|INFO|ERROR", - Name: "syslog_server_main", - PortNumber: 514, - Status: "ACTIVE", - }, - { - ID: "22002202-2edf-1844-1ff7-12ba5b7e566a", - IPAddress: "177.77.07.211", - LogFacility: "LOCAL1", - LogLevel: "ERROR", - Name: "syslog_server_backup_fst", - PortNumber: 514, - Status: "ACTIVE", - }, - }, - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - UserUsername: "user-read", -} - -var ExpectedLoadBalancerSlice = []load_balancers.LoadBalancer{LoadBalancer1, LoadBalancer2} - -const ListResponseDuplicatedNames = ` -{ - "load_balancers": [ - { - "admin_username": "user-admin", - "availability_zone": "zone1-groupa", - "default_gateway": "100.127.253.1", - "description": "Load Balancer 1 Description", - "id": "5f3cae7c-58a5-4124-b622-9ca3cfbf2525", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 1", - "status": "ACTIVE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - }, - { - "admin_username": "user-admin", - "availability_zone": "zone1_groupa", - "default_gateway": null, - "description": "abcdefghijklmnopqrstuvwxyz", - "id": "601665cf-c161-4e80-87f0-a3c0925d07a0", - "load_balancer_plan_id": "bd12784a-c66e-4f13-9f72-5143d64762b6", - "name": "Load Balancer 1", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "user_username": "user-read" - } - ] -} -` diff --git a/v3/ecl/network/v2/load_balancers/testing/request_test.go b/v3/ecl/network/v2/load_balancers/testing/request_test.go deleted file mode 100644 index 29663ab..0000000 --- a/v3/ecl/network/v2/load_balancers/testing/request_test.go +++ /dev/null @@ -1,289 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_interfaces" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancer_syslog_servers" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/load_balancers" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - load_balancers.List(client, load_balancers.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := load_balancers.ExtractLoadBalancers(page) - if err != nil { - t.Errorf("Failed to extract Load Balancers: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedLoadBalancerSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers/5f3cae7c-58a5-4124-b622-9ca3cfbf2525", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := load_balancers.Get(fake.ServiceClient(), "5f3cae7c-58a5-4124-b622-9ca3cfbf2525").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &LoadBalancerDetail, s) -} - -func TestCreateLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - options := load_balancers.CreateOpts{ - AvailabilityZone: "zone1-groupa", - Description: "abcdefghijklmnopqrstuvwxyz", - LoadBalancerPlanID: "bd12784a-c66e-4f13-9f72-5143d64762b6", - Name: "abcdefghijklmnopqrstuvwxyz", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - } - s, err := load_balancers.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &LoadBalancerDetail, s) -} - -func TestRequiredCreateOptsLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := load_balancers.Create(fake.ServiceClient(), load_balancers.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdateLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - adminUsername := "user-admin" - availabilityZone := "zone1-groupa" - defaultGateway := interface{}("100.127.253.1") - description := "UPDATED" - id := "5f3cae7c-58a5-4124-b622-9ca3cfbf2525" - - ipAddress1 := "100.127.253.173" - networkID1 := "c7f88fab-573e-47aa-b0b4-257db28dae23" - ipAddress2 := "192.168.110.1" - networkID2 := "1839d290-721c-49ba-99f1-3d7aa37811b0" - - interfaces := []load_balancer_interfaces.LoadBalancerInterface{ - { - ID: "ee335c69-b50f-4a32-9d0f-f44cef84a456", - IPAddress: &ipAddress1, - Name: "Interface 1/1", - NetworkID: &networkID1, - SlotNumber: 1, - Status: "ACTIVE", - }, - { - ID: "b39b61e4-00b1-4698-aed0-1928beb90abe", - IPAddress: &ipAddress2, - Name: "Interface 1/2", - NetworkID: &networkID2, - SlotNumber: 2, - Status: "ACTIVE", - }, - } - - loadBalancerPlanID := "bd12784a-c66e-4f13-9f72-5143d64762b6" - name := "abcdefghijklmnopqrstuvwxyz" - status := "PENDING_UPDATE" - - syslogServers := []load_balancer_syslog_servers.LoadBalancerSyslogServer{ - { - ID: "11001101-2edf-1844-1ff7-12ba5b7e566a", - IPAddress: "177.77.07.215", - LogFacility: "LOCAL0", - LogLevel: "ALERT|INFO|ERROR", - Name: "syslog_server_main", - PortNumber: 514, - Status: "ACTIVE", - }, - { - ID: "22002202-2edf-1844-1ff7-12ba5b7e566a", - IPAddress: "177.77.07.211", - LogFacility: "LOCAL1", - LogLevel: "ERROR", - Name: "syslog_server_backup_fst", - PortNumber: 514, - Status: "ACTIVE", - }, - } - - tenantID := "6a156ddf2ecd497ca786ff2da6df5aa8" - userUsername := "user-read" - - options := load_balancers.UpdateOpts{ - DefaultGateway: &defaultGateway, - Description: &description, - LoadBalancerPlanID: loadBalancerPlanID, - Name: &name, - } - - s, err := load_balancers.Update(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416", options).Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, adminUsername, s.AdminUsername) - th.CheckEquals(t, availabilityZone, s.AvailabilityZone) - th.CheckEquals(t, defaultGateway, *s.DefaultGateway) - th.CheckEquals(t, description, s.Description) - th.CheckEquals(t, id, s.ID) - th.CheckDeepEquals(t, interfaces, s.Interfaces) - th.CheckEquals(t, loadBalancerPlanID, s.LoadBalancerPlanID) - th.CheckEquals(t, name, s.Name) - th.CheckEquals(t, status, s.Status) - th.CheckDeepEquals(t, syslogServers, s.SyslogServers) - th.CheckEquals(t, tenantID, s.TenantID) - th.CheckEquals(t, userUsername, s.UserUsername) -} - -func TestDeleteLoadBalancer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := load_balancers.Delete(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416") - th.AssertNoErr(t, res.Err) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - expectedID := "5f3cae7c-58a5-4124-b622-9ca3cfbf2525" - actualID, err := load_balancers.IDFromName(client, "Load Balancer 1") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - - _, err := load_balancers.IDFromName(client, "Load Balancer X") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/load_balancers", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := fake.ServiceClient() - - _, err := load_balancers.IDFromName(client, "Load Balancer 1") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/network/v2/load_balancers/urls.go b/v3/ecl/network/v2/load_balancers/urls.go deleted file mode 100644 index e39bbd4..0000000 --- a/v3/ecl/network/v2/load_balancers/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package load_balancers - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("load_balancers", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("load_balancers") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/networks/doc.go b/v3/ecl/network/v2/networks/doc.go deleted file mode 100644 index e768b71..0000000 --- a/v3/ecl/network/v2/networks/doc.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Package networks contains functionality for working with Neutron network -resources. A network is an isolated virtual layer-2 broadcast domain that is -typically reserved for the tenant who created it (unless you configure the -network to be shared). Tenants can create multiple networks until the -thresholds per-tenant quota is reached. - -In the v2.0 Networking API, the network is the main entity. Ports and subnets -are always associated with a network. - -Example to List Networks - - listOpts := networks.ListOpts{ - TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", - } - - allPages, err := networks.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allNetworks, err := networks.ExtractNetworks(allPages) - if err != nil { - panic(err) - } - - for _, network := range allNetworks { - fmt.Printf("%+v", network) - } - -Example to Create a Network - - iTrue := true - createOpts := networks.CreateOpts{ - Name: "network_1", - AdminStateUp: &iTrue, - } - - network, err := networks.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Network - - networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - - updateOpts := networks.UpdateOpts{ - Name: "new_name", - } - - network, err := networks.Update(networkClient, networkID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Network - - networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - err := networks.Delete(networkClient, networkID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package networks diff --git a/v3/ecl/network/v2/networks/requests.go b/v3/ecl/network/v2/networks/requests.go deleted file mode 100644 index cb0f079..0000000 --- a/v3/ecl/network/v2/networks/requests.go +++ /dev/null @@ -1,170 +0,0 @@ -package networks - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToNetworkListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the network attributes you want to see returned. SortKey allows you to sort -// by a particular network attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - ID string `q:"id"` - Name string `q:"name"` - Plane string `q:"plane"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` -} - -// ToNetworkListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToNetworkListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToNetworkListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return NetworkPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific network based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToNetworkCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents options used to create a network. -type CreateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - Plane string `json:"plane,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - TenantID string `json:"tenant_id,omitempty"` -} - -// ToNetworkCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "network") -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// network. An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToNetworkCreateMap() - if err != nil { - r.Err = err - return - } - - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToNetworkUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents options used to update a network. -type UpdateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` -} - -// ToNetworkUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "network") -} - -// Update accepts a UpdateOpts struct and updates an existing network using the -// values provided. For more information, see the Create function. -func Update(c *eclcloud.ServiceClient, networkID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToNetworkUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, networkID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -// Delete accepts a unique ID and deletes the network associated with it. -func Delete(c *eclcloud.ServiceClient, networkID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, networkID), nil) - return -} - -// IDFromName is a convenience function that returns a network's ID, given -// its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractNetworks(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "network"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "network"} - } -} diff --git a/v3/ecl/network/v2/networks/results.go b/v3/ecl/network/v2/networks/results.go deleted file mode 100644 index 335ceb3..0000000 --- a/v3/ecl/network/v2/networks/results.go +++ /dev/null @@ -1,120 +0,0 @@ -package networks - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a network resource. -func (r commonResult) Extract() (*Network, error) { - var s Network - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "network") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Network. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Network. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Network. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// Network represents, well, a network. -type Network struct { - // The administrative state of network. If false (down), the network does not - // forward packets. - AdminStateUp bool `json:"admin_state_up"` - - // Description is the description of the network. - Description string `json:"description"` - - // UUID for the network - ID string `json:"id"` - - // Human-readable name for the network. Might not be unique. - Name string `json:"name"` - - // Plane it the ype of the traffic for which network will be used. - Plane string `json:"plane"` - - // Specifies whether the network resource can be accessed by any tenant. - Shared bool `json:"shared"` - - // Indicates whether network is currently operational. Possible values include - // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional - // values. - Status string `json:"status"` - - // Subnets associated with this network. - Subnets []string `json:"subnets"` - - // Tags optionally set via extensions/attributestags - Tags map[string]string `json:"tags"` - - // TenantID is the project owner of the network. - TenantID string `json:"tenant_id"` -} - -// NetworkPage is the page returned by a pager when traversing over a -// collection of networks. -type NetworkPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of networks has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r NetworkPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"networks_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a NetworkPage struct is empty. -func (r NetworkPage) IsEmpty() (bool, error) { - is, err := ExtractNetworks(r) - return len(is) == 0, err -} - -// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct, -// and extracts the elements into a slice of Network structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractNetworks(r pagination.Page) ([]Network, error) { - var s []Network - err := ExtractNetworksInto(r, &s) - return s, err -} - -func ExtractNetworksInto(r pagination.Page, v interface{}) error { - return r.(NetworkPage).Result.ExtractIntoSlicePtr(v, "networks") -} diff --git a/v3/ecl/network/v2/networks/testing/doc.go b/v3/ecl/network/v2/networks/testing/doc.go deleted file mode 100644 index bf82f4e..0000000 --- a/v3/ecl/network/v2/networks/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// ports unit tests -package testing diff --git a/v3/ecl/network/v2/networks/testing/fixtures.go b/v3/ecl/network/v2/networks/testing/fixtures.go deleted file mode 100644 index 887c421..0000000 --- a/v3/ecl/network/v2/networks/testing/fixtures.go +++ /dev/null @@ -1,155 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/networks" -) - -const ListResponse = ` -{ - "networks": [ - { - "admin_state_up": true, - "description": "", - "id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "name": "", - "plane": "data", - "shared": false, - "status": "ACTIVE", - "subnets": [ - "ab49eb24-667f-4a4e-9421-b4d915bff416", - "f6aa2d33-f3ae-4c4e-82f7-0d4ab4c67678" - ], - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - }, - { - "admin_state_up": true, - "description": "Example Network 2", - "id": "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", - "name": "Example Network 2", - "plane": "data", - "shared": false, - "status": "ACTIVE", - "subnets": [], - "tags": { - "keyword1": "value1", - "keyword2": "value2" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - ] - }` -const GetResponse = `{ - "network": { - "admin_state_up": true, - "description": "Example Network 2", - "id": "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", - "name": "Example Network 2", - "plane": "data", - "shared": false, - "status": "ACTIVE", - "subnets": [], - "tags": { - "keyword1": "value1", - "keyword2": "value2" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - }` -const CreateResponse = ` -{ - "network": { - "admin_state_up": true, - "description": "Example Network 2", - "id": "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", - "name": "Example Network 2", - "plane": "data", - "shared": false, - "status": "ACTIVE", - "subnets": [], - "tags": { - "keyword1": "value1", - "keyword2": "value2" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - }` -const CreateRequest = ` -{ - "network": { - "admin_state_up": true, - "description": "Example Network 2", - "name": "Example Network 2", - "plane": "data", - "tags": { - "keyword1": "value1", - "keyword2": "value2" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } -` -const UpdateResponse = ` -{ - "network": { - "admin_state_up": false, - "description": "UPDATED", - "id": "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", - "name": "UPDATED", - "plane": "data", - "shared": false, - "status": "PENDING_UPDATE", - "subnets": [], - "tags": { - "keyword1": "UPDATED", - "keyword3": "CREATED" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - }` -const UpdateRequest = ` -{ - "network": { - "admin_state_up": false, - "description": "UPDATED", - "name": "UPDATED", - "tags": { - "keyword1": "UPDATED", - "keyword3": "CREATED" - } - } - }` - -var Network1 = networks.Network{ - AdminStateUp: true, - Description: "", - ID: "8f36b88a-443f-4d97-9751-34d34af9e782", - Name: "", - Plane: "data", - Shared: false, - Status: "ACTIVE", - Subnets: []string{ - "ab49eb24-667f-4a4e-9421-b4d915bff416", - "f6aa2d33-f3ae-4c4e-82f7-0d4ab4c67678", - }, - Tags: map[string]string{}, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var Network2 = networks.Network{ - AdminStateUp: true, - Description: "Example Network 2", - ID: "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", - Name: "Example Network 2", - Plane: "data", - Shared: false, - Status: "ACTIVE", - Subnets: []string{}, - Tags: map[string]string{ - "keyword1": "value1", - "keyword2": "value2", - }, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var ExpectedNetworkSlice = []networks.Network{Network1, Network2} diff --git a/v3/ecl/network/v2/networks/testing/request_test.go b/v3/ecl/network/v2/networks/testing/request_test.go deleted file mode 100644 index 76fa0a0..0000000 --- a/v3/ecl/network/v2/networks/testing/request_test.go +++ /dev/null @@ -1,164 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/networks" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - networks.List(client, networks.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := networks.ExtractNetworks(page) - if err != nil { - t.Errorf("Failed to extrace ports: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedNetworkSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - n, err := networks.Get(fake.ServiceClient(), "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &Network2, n) -} - -func TestCreateNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - asu := true - - options := &networks.CreateOpts{ - AdminStateUp: &asu, - Description: "Example Network 2", - Name: "Example Network 2", - Plane: "data", - Tags: map[string]string{ - "keyword1": "value1", - "keyword2": "value2", - }, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", - } - n, err := networks.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &Network2, n) -} - -func TestRequiredCreateOptsNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := networks.Create(fake.ServiceClient(), networks.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdateNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - asu := false - description := "UPDATED" - name := "UPDATED" - tags := map[string]string{ - "keyword1": "UPDATED", - "keyword3": "CREATED", - } - - options := &networks.UpdateOpts{ - AdminStateUp: &asu, - Description: &description, - Name: &name, - Tags: &tags, - } - n, err := networks.Update(fake.ServiceClient(), "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", options).Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, asu, n.AdminStateUp) - th.CheckEquals(t, description, n.Description) - th.CheckEquals(t, name, n.Name) - th.CheckDeepEquals(t, tags, n.Tags) -} - -func TestDeleteNetwork(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/networks/a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := networks.Delete(fake.ServiceClient(), "a033d04b-b1fe-4ff4-a7c7-5f4b6da981d2") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/networks/urls.go b/v3/ecl/network/v2/networks/urls.go deleted file mode 100644 index 4dbf8e0..0000000 --- a/v3/ecl/network/v2/networks/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package networks - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("networks", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("networks") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/ports/doc.go b/v3/ecl/network/v2/ports/doc.go deleted file mode 100644 index cfb1774..0000000 --- a/v3/ecl/network/v2/ports/doc.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Package ports contains functionality for working with Neutron port resources. - -A port represents a virtual switch port on a logical network switch. Virtual -instances attach their interfaces into ports. The logical port also defines -the MAC address and the IP address(es) to be assigned to the interfaces -plugged into them. When IP addresses are associated to a port, this also -implies the port is associated with a subnet, as the IP address was taken -from the allocation pool for a specific subnet. - -Example to List Ports - - listOpts := ports.ListOpts{ - DeviceID: "b0b89efe-82f8-461d-958b-adbf80f50c7d", - } - - allPages, err := ports.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allPorts, err := ports.ExtractPorts(allPages) - if err != nil { - panic(err) - } - - for _, port := range allPorts { - fmt.Printf("%+v\n", port) - } - -Example to Create a Port - - createOtps := ports.CreateOpts{ - Name: "private-port", - AdminStateUp: &asu, - NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7", - FixedIPs: []ports.IP{ - {SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"}, - }, - SecurityGroups: &[]string{"foo"}, - AllowedAddressPairs: []ports.AddressPair{ - {IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"}, - }, - } - - port, err := ports.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Port - - portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8" - - updateOpts := ports.UpdateOpts{ - Name: "new_name", - SecurityGroups: &[]string{}, - } - - port, err := ports.Update(networkClient, portID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Port - - portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8" - err := ports.Delete(networkClient, portID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package ports diff --git a/v3/ecl/network/v2/ports/requests.go b/v3/ecl/network/v2/ports/requests.go deleted file mode 100644 index 1cfcce2..0000000 --- a/v3/ecl/network/v2/ports/requests.go +++ /dev/null @@ -1,186 +0,0 @@ -package ports - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToPortListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the port attributes you want to see returned. SortKey allows you to sort -// by a particular port attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Description string `q:"description"` - DeviceID string `q:"device_id"` - DeviceOwner string `q:"device_owner"` - ID string `q:"id"` - MACAddress string `q:"mac_address"` - Name string `q:"name"` - NetworkID string `q:"network_id"` - SegmentationID int `q:"segmentation_id"` - SegmentationType string `q:"segmentation_type"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` -} - -// ToPortListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToPortListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// ports. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those ports that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToPortListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return PortPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific port based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToPortCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents the attributes used when creating a new port. -type CreateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"` - Description string `json:"description,omitempty"` - DeviceID string `json:"device_id,omitempty"` - DeviceOwner string `json:"device_owner,omitempty"` - FixedIPs interface{} `json:"fixed_ips,omitempty"` - MACAddress string `json:"mac_address,omitempty"` - Name string `json:"name,omitempty"` - NetworkID string `json:"network_id"` - SegmentationID int `json:"segmentation_id,omitempty"` - SegmentationType string `json:"segmentation_type,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - TenantID string `json:"tenant_id,omitempty"` -} - -// ToPortCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "port") -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. You must remember to provide a NetworkID value. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToPortCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToPortUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the attributes used when updating an existing port. -type UpdateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"` - Description *string `json:"description,omitempty"` - DeviceID *string `json:"device_id,omitempty"` - DeviceOwner *string `json:"device_owner,omitempty"` - FixedIPs interface{} `json:"fixed_ips,omitempty"` - Name *string `json:"name,omitempty"` - SegmentationID *int `json:"segmentation_id,omitempty"` - SegmentationType *string `json:"segmentation_type,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` -} - -// ToPortUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "port") -} - -// Update accepts a UpdateOpts struct and updates an existing port using the -// values provided. -func Update(c *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToPortUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -// Delete accepts a unique ID and deletes the port associated with it. -func Delete(c *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, id), nil) - return -} - -// IDFromName is a convenience function that returns a port's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractPorts(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "port"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "port"} - } -} diff --git a/v3/ecl/network/v2/ports/results.go b/v3/ecl/network/v2/ports/results.go deleted file mode 100644 index c2f50c8..0000000 --- a/v3/ecl/network/v2/ports/results.go +++ /dev/null @@ -1,152 +0,0 @@ -package ports - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a port resource. -func (r commonResult) Extract() (*Port, error) { - var s Port - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "port") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Port. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Port. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Port. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// IP is a sub-struct that represents an individual IP. -type IP struct { - SubnetID string `json:"subnet_id"` - IPAddress string `json:"ip_address,omitempty"` -} - -// AddressPair contains the IP Address and the MAC address. -type AddressPair struct { - IPAddress string `json:"ip_address,omitempty"` - MACAddress string `json:"mac_address,omitempty"` -} - -// Port represents a Neutron port. See package documentation for a top-level -// description of what this is. -type Port struct { - // Administrative state of port. If false (down), port does not forward - // packets. - AdminStateUp bool `json:"admin_state_up"` - - // Identifies the list of IP addresses the port will recognize/accept - AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"` - - // Description is description - Description string `json:"description"` - - // Identifies the device (e.g., virtual server) using this port. - DeviceID string `json:"device_id"` - - // Identifies the entity (e.g.: dhcp agent) using this port. - DeviceOwner string `json:"device_owner"` - - // Specifies IP addresses for the port thus associating the port itself with - // the subnets where the IP addresses are picked from - FixedIPs []IP `json:"fixed_ips"` - - // UUID for the port. - ID string `json:"id"` - - // Mac address to use on this port. - MACAddress string `json:"mac_address"` - - // ManagedByService is set to true if only admin can modify it. Normal user has only read access. - ManagedByService bool `json:"managed_by_service"` - - // Human-readable name for the port. Might not be unique. - Name string `json:"name"` - - // Network that this port is associated with. - NetworkID string `json:"network_id"` - - // SegmentationID is the segmenation ID used for this port (i.e. for vlan type it is vlan tag) - SegmentationID int `json:"segmentation_id"` - - // SegmenationType is the segmentation type used for this port (i.e. vlan) - SegmentationType string `json:"segmentation_type"` - - // Indicates whether network is currently operational. Possible values include - // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional - // values. - Status string `json:"status"` - - // Tags optionally set via extensions/attributestags - Tags map[string]string `json:"tags"` - - // TenantID is the project owner of the port. - TenantID string `json:"tenant_id"` -} - -// PortPage is the page returned by a pager when traversing over a collection -// of network ports. -type PortPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of ports has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r PortPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"ports_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a PortPage struct is empty. -func (r PortPage) IsEmpty() (bool, error) { - is, err := ExtractPorts(r) - return len(is) == 0, err -} - -// ExtractPorts accepts a Page struct, specifically a PortPage struct, -// and extracts the elements into a slice of Port structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractPorts(r pagination.Page) ([]Port, error) { - var s []Port - err := ExtractPortsInto(r, &s) - return s, err -} - -func ExtractPortsInto(r pagination.Page, v interface{}) error { - return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports") -} diff --git a/v3/ecl/network/v2/ports/testing/doc.go b/v3/ecl/network/v2/ports/testing/doc.go deleted file mode 100644 index bf82f4e..0000000 --- a/v3/ecl/network/v2/ports/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// ports unit tests -package testing diff --git a/v3/ecl/network/v2/ports/testing/fixtures.go b/v3/ecl/network/v2/ports/testing/fixtures.go deleted file mode 100644 index c622b71..0000000 --- a/v3/ecl/network/v2/ports/testing/fixtures.go +++ /dev/null @@ -1,290 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/ports" -) - -const ListResponse = ` -{ - "ports": [ - { - "admin_state_up": true, - "allowed_address_pairs": [], - "description": "DHCP Server Port", - "device_id": "ab49eb24-667f-4a4e-9421-b4d915bff416", - "device_owner": "network:dhcp", - "fixed_ips": [ - { - "ip_address": "192.168.2.2", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "id": "8db1ba30-be40-4943-a7be-ed5b98f053b3", - "mac_address": "00:00:5e:00:01:00", - "managed_by_service": false, - "name": "dhcp-server-port", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": null, - "segmentation_type": null, - "status": "ACTIVE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - }, - { - "admin_state_up": true, - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - }], - "description": "", - "device_id": "", - "device_owner": "", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "id": "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - "mac_address": "fa:16:3e:b0:ca:f1", - "managed_by_service": false, - "name": "port_12", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": 0, - "segmentation_type": "flat", - "status": "PENDING_CREATE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - ] - }` -const GetResponse = ` -{ - "port": { - "admin_state_up": true, - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - }], - "description": "", - "device_id": "", - "device_owner": "", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "id": "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - "mac_address": "fa:16:3e:b0:ca:f1", - "managed_by_service": false, - "name": "port_12", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": 0, - "segmentation_type": "flat", - "status": "PENDING_CREATE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } -` - -const CreateResponse = ` -{ - "port": { - "admin_state_up": true, - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - }], - "description": "", - "device_id": "", - "device_owner": "", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "id": "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - "mac_address": "fa:16:3e:b0:ca:f1", - "name": "port_12", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": 0, - "segmentation_type": "flat", - "status": "PENDING_CREATE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - }` -const CreateRequest = ` -{ - "port": - { - "admin_state_up": true, - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - }], - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "name": "port_12", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1", - "segmentation_type": "flat" - } -}` -const UpdateResponse = ` -{ - "port": { - "admin_state_up": true, - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - },{ - "ip_address": "192.168.2.255", - "mac_address": "26:8d:42:f6:c2:c4" - }], - "description": "UPDATED", - "device_id": "b269b8c0-1a42-4464-9314-4396e51e5107", - "device_owner": "UPDATED", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - }, { - "ip_address": "192.168.2.31", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff417" - } - ], - "id": "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - "mac_address": "fa:16:3e:b0:ca:f1", - "name": "UPDATED", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": 2, - "segmentation_type": "vlan", - "status": "PENDING_CREATE", - "tags": { - "some-key":"UPDATED" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - }` - -const UpdateRequest = ` -{ - "port": { - "allowed_address_pairs": [{ - "ip_address": "192.168.2.100", - "mac_address": "00:00:5e:00:01:01" - },{ - "ip_address": "192.168.2.255", - "mac_address": "26:8d:42:f6:c2:c4" - }], - "description": "UPDATED", - "device_id": "b269b8c0-1a42-4464-9314-4396e51e5107", - "device_owner": "UPDATED", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - }, { - "ip_address": "192.168.2.31", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff417" - } - ], - "name": "UPDATED", - "segmentation_id": 2, - "segmentation_type": "vlan", - "tags": { - "some-key":"UPDATED" - } - } - }` - -const RemoveAllowedAddressPairsRequest = ` -{ - "port": { - "allowed_address_pairs": [], - "name": "new_port_name" - } - } -` - -const RemoveAllowedAddressPairsResponse = ` -{ - "port": { - "admin_state_up": true, - "allowed_address_pairs": [], - "description": "", - "device_id": "", - "device_owner": "", - "fixed_ips": [ - { - "ip_address": "192.168.2.30", - "subnet_id": "ab49eb24-667f-4a4e-9421-b4d915bff416" - } - ], - "id": "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - "mac_address": "fa:16:3e:b0:ca:f1", - "name": "new_port_name", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "segmentation_id": 0, - "segmentation_type": "flat", - "status": "PENDING_CREATE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } -` - -var Port1 = ports.Port{ - AdminStateUp: true, - AllowedAddressPairs: []ports.AddressPair{}, - Description: "DHCP Server Port", - DeviceID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - DeviceOwner: "network:dhcp", - FixedIPs: []ports.IP{{ - IPAddress: "192.168.2.2", - SubnetID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - }}, - ID: "8db1ba30-be40-4943-a7be-ed5b98f053b3", - MACAddress: "00:00:5e:00:01:00", - ManagedByService: false, - Name: "dhcp-server-port", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - Status: "ACTIVE", - Tags: map[string]string{}, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var Port2 = ports.Port{ - AdminStateUp: true, - AllowedAddressPairs: []ports.AddressPair{{ - IPAddress: "192.168.2.100", - MACAddress: "00:00:5e:00:01:01", - }}, - Description: "", - DeviceID: "", - DeviceOwner: "", - FixedIPs: []ports.IP{{ - IPAddress: "192.168.2.30", - SubnetID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - }}, - ID: "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", - MACAddress: "fa:16:3e:b0:ca:f1", - ManagedByService: false, - Name: "port_12", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - SegmentationID: 0, - SegmentationType: "flat", - Status: "PENDING_CREATE", - Tags: map[string]string{}, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var ExpectedPortSlice = []ports.Port{Port1, Port2} diff --git a/v3/ecl/network/v2/ports/testing/request_test.go b/v3/ecl/network/v2/ports/testing/request_test.go deleted file mode 100644 index 0fb45d8..0000000 --- a/v3/ecl/network/v2/ports/testing/request_test.go +++ /dev/null @@ -1,221 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/ports" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - ports.List(client, ports.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ports.ExtractPorts(page) - if err != nil { - t.Errorf("Failed to extrace ports: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedPortSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - p, err := ports.Get(fake.ServiceClient(), "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &Port2, p) -} - -func TestCreatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - asu := true - - options := &ports.CreateOpts{ - AdminStateUp: &asu, - AllowedAddressPairs: []ports.AddressPair{{ - IPAddress: "192.168.2.100", - MACAddress: "00:00:5e:00:01:01", - }}, - FixedIPs: []ports.IP{{ - IPAddress: "192.168.2.30", - SubnetID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - }}, - Name: "port_12", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", - SegmentationType: "flat", - } - p, err := ports.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &Port2, p) -} - -func TestRequiredCreateOptsPort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := ports.Create(fake.ServiceClient(), ports.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} -func TestUpdatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - aap := []ports.AddressPair{{ - IPAddress: "192.168.2.100", - MACAddress: "00:00:5e:00:01:01", - }, { - IPAddress: "192.168.2.255", - MACAddress: "26:8d:42:f6:c2:c4", - }} - description := "UPDATED" - deviceID := "b269b8c0-1a42-4464-9314-4396e51e5107" - deviceOwner := "UPDATED" - fip := []ports.IP{{ - IPAddress: "192.168.2.30", - SubnetID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - }, { - IPAddress: "192.168.2.31", - SubnetID: "ab49eb24-667f-4a4e-9421-b4d915bff417", - }} - name := "UPDATED" - segmentationID := 2 - segmentationType := "vlan" - tags := map[string]string{"some-key": "UPDATED"} - - options := ports.UpdateOpts{ - AllowedAddressPairs: &aap, - Description: &description, - DeviceID: &deviceID, - DeviceOwner: &deviceOwner, - FixedIPs: fip, - Name: &name, - SegmentationID: &segmentationID, - SegmentationType: &segmentationType, - Tags: &tags, - } - p, err := ports.Update(fake.ServiceClient(), "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", options).Extract() - th.AssertNoErr(t, err) - - th.CheckDeepEquals(t, aap, p.AllowedAddressPairs) - th.CheckEquals(t, description, p.Description) - th.CheckEquals(t, deviceID, p.DeviceID) - th.CheckEquals(t, deviceOwner, p.DeviceOwner) - th.CheckDeepEquals(t, fip, p.FixedIPs) - th.CheckEquals(t, name, p.Name) - th.CheckEquals(t, segmentationID, p.SegmentationID) - th.CheckEquals(t, segmentationType, p.SegmentationType) - th.CheckDeepEquals(t, tags, p.Tags) -} - -func TestRemoveAllowedAddressPairs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, RemoveAllowedAddressPairsRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, RemoveAllowedAddressPairsResponse) - }) - - name := "new_port_name" - options := ports.UpdateOpts{ - Name: &name, - AllowedAddressPairs: &[]ports.AddressPair{}, - } - - s, err := ports.Update(fake.ServiceClient(), "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, s.Name, "new_port_name") - th.AssertDeepEquals(t, s.AllowedAddressPairs, []ports.AddressPair{}) -} - -func TestDeletePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/ports/ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := ports.Delete(fake.ServiceClient(), "ac57c5c9-aaf4-4ffc-b8b8-f1ef84656730") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/ports/urls.go b/v3/ecl/network/v2/ports/urls.go deleted file mode 100644 index 958f39a..0000000 --- a/v3/ecl/network/v2/ports/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package ports - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("ports", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("ports") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/public_ips/doc.go b/v3/ecl/network/v2/public_ips/doc.go deleted file mode 100644 index eff1dea..0000000 --- a/v3/ecl/network/v2/public_ips/doc.go +++ /dev/null @@ -1 +0,0 @@ -package public_ips diff --git a/v3/ecl/network/v2/public_ips/requests.go b/v3/ecl/network/v2/public_ips/requests.go deleted file mode 100644 index a991f79..0000000 --- a/v3/ecl/network/v2/public_ips/requests.go +++ /dev/null @@ -1,136 +0,0 @@ -package public_ips - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type ListOptsBuilder interface { - ToPublicIPListQuery() (string, error) -} - -type ListOpts struct { - Cidr string `q:"cidr"` - Description string `q:"description"` - ID string `q:"id"` - InternetGwID string `q:"internet_gw_id"` - Name string `q:"name"` - Status string `q:"status"` - SubmaskLength int `q:"submask_length"` - TenantID string `q:"tenant_id"` -} - -func (opts ListOpts) ToPublicIPListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToPublicIPListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return PublicIPPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -func Get(c *eclcloud.ServiceClient, publicIPID string) (r GetResult) { - _, r.Err = c.Get(getURL(c, publicIPID), &r.Body, nil) - return -} - -type CreateOptsBuilder interface { - ToPublicIPCreateMap() (map[string]interface{}, error) -} - -type CreateOpts struct { - Description string `json:"description,omitempty"` - InternetGwID string `json:"internet_gw_id" required:"true"` - Name string `json:"name,omitempty"` - SubmaskLength int `json:"submask_length" required:"true"` - TenantID string `json:"tenant_id,omitempty"` -} - -func (opts CreateOpts) ToPublicIPCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "public_ip") -} - -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToPublicIPCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -type UpdateOptsBuilder interface { - ToPublicIPUpdateMap() (map[string]interface{}, error) -} - -type UpdateOpts struct { - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` -} - -func (opts UpdateOpts) ToPublicIPUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "public_ip") -} - -func Update(c *eclcloud.ServiceClient, publicIPID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToPublicIPUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, publicIPID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -func Delete(c *eclcloud.ServiceClient, publicIPID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, publicIPID), nil) - return -} - -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractPublicIPs(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "public_ip"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "public_ip"} - } -} diff --git a/v3/ecl/network/v2/public_ips/results.go b/v3/ecl/network/v2/public_ips/results.go deleted file mode 100644 index 9861312..0000000 --- a/v3/ecl/network/v2/public_ips/results.go +++ /dev/null @@ -1,77 +0,0 @@ -package public_ips - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*PublicIP, error) { - var s PublicIP - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "public_ip") -} - -type CreateResult struct { - commonResult -} - -type GetResult struct { - commonResult -} - -type UpdateResult struct { - commonResult -} - -type DeleteResult struct { - eclcloud.ErrResult -} - -type PublicIP struct { - Cidr string `json:"cidr"` - Description string `json:"description"` - ID string `json:"id"` - InternetGwID string `json:"internet_gw_id"` - Name string `json:"name"` - Status string `json:"status"` - SubmaskLength int `json:"submask_length"` - TenantID string `json:"tenant_id"` -} - -type PublicIPPage struct { - pagination.LinkedPageBase -} - -func (r PublicIPPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"public_ips_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -func (r PublicIPPage) IsEmpty() (bool, error) { - is, err := ExtractPublicIPs(r) - return len(is) == 0, err -} - -func ExtractPublicIPs(r pagination.Page) ([]PublicIP, error) { - var s []PublicIP - err := ExtractPublicIPsInto(r, &s) - return s, err -} - -func ExtractPublicIPsInto(r pagination.Page, v interface{}) error { - return r.(PublicIPPage).Result.ExtractIntoSlicePtr(v, "public_ips") -} diff --git a/v3/ecl/network/v2/public_ips/testing/doc.go b/v3/ecl/network/v2/public_ips/testing/doc.go deleted file mode 100644 index ab98250..0000000 --- a/v3/ecl/network/v2/public_ips/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// public_ips unit tests -package testing diff --git a/v3/ecl/network/v2/public_ips/testing/fixtures.go b/v3/ecl/network/v2/public_ips/testing/fixtures.go deleted file mode 100644 index ac5a8b7..0000000 --- a/v3/ecl/network/v2/public_ips/testing/fixtures.go +++ /dev/null @@ -1,121 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/public_ips" -) - -const ListResponse = ` -{ - "public_ips": [ - { - "cidr": "100.127.255.80", - "description": "", - "id": "0718a31b-67be-4349-946b-61a0fc38e4cd", - "internet_gw_id": "2a75cfa6-89af-425b-bce5-2a85197ef04f", - "name": "seinou-test-public", - "status": "PENDING_CREATE", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - }, - { - "cidr": "100.127.254.56", - "description": "", - "id": "110846c3-3a20-42ff-ad3d-25ba7b0272bb", - "internet_gw_id": "05db9b0e-65ed-4478-a6b3-d3fc259c8d07", - "name": "6_Public", - "status": "ACTIVE", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } - ] -} -` - -const GetResponse = ` -{ - "public_ip": { - "cidr": "100.127.255.80", - "description": "", - "id": "0718a31b-67be-4349-946b-61a0fc38e4cd", - "internet_gw_id": "2a75cfa6-89af-425b-bce5-2a85197ef04f", - "name": "seinou-test-public", - "status": "PENDING_CREATE", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } -} -` - -const CreateRequest = ` -{ - "public_ip": { - "internet_gw_id": "2a75cfa6-89af-425b-bce5-2a85197ef04f", - "name": "seinou-test-public", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } -} -` - -const CreateResponse = ` -{ - "public_ip": { - "cidr": "100.127.255.80", - "description": "", - "id": "0718a31b-67be-4349-946b-61a0fc38e4cd", - "internet_gw_id": "2a75cfa6-89af-425b-bce5-2a85197ef04f", - "name": "seinou-test-public", - "status": "PENDING_CREATE", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } -} -` - -const UpdateRequest = ` -{ - "public_ip": { - "name": "seinou-test-public", - "description": "" - } -} - ` - -const UpdateResponse = ` -{ - "public_ip": { - "cidr": "100.127.255.80", - "description": "", - "id": "0718a31b-67be-4349-946b-61a0fc38e4cd", - "internet_gw_id": "2a75cfa6-89af-425b-bce5-2a85197ef04f", - "name": "seinou-test-public", - "status": "PENDING_UPDATE", - "submask_length": 29, - "tenant_id": "19ab165c7a664abe9c217334cd0e9cc9" - } -} -` - -var PublicIP1 = public_ips.PublicIP{ - Cidr: "100.127.255.80", - Description: "", - ID: "0718a31b-67be-4349-946b-61a0fc38e4cd", - InternetGwID: "2a75cfa6-89af-425b-bce5-2a85197ef04f", - Name: "seinou-test-public", - Status: "PENDING_CREATE", - SubmaskLength: 29, - TenantID: "19ab165c7a664abe9c217334cd0e9cc9", -} - -var PublicIP2 = public_ips.PublicIP{ - Cidr: "100.127.254.56", - Description: "", - ID: "110846c3-3a20-42ff-ad3d-25ba7b0272bb", - InternetGwID: "05db9b0e-65ed-4478-a6b3-d3fc259c8d07", - Name: "6_Public", - Status: "ACTIVE", - SubmaskLength: 29, - TenantID: "19ab165c7a664abe9c217334cd0e9cc9", -} - -var ExpectedPublicIPSlice = []public_ips.PublicIP{PublicIP1, PublicIP2} diff --git a/v3/ecl/network/v2/public_ips/testing/request_test.go b/v3/ecl/network/v2/public_ips/testing/request_test.go deleted file mode 100644 index 40efed5..0000000 --- a/v3/ecl/network/v2/public_ips/testing/request_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/public_ips" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestList(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/public_ips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - tmp := public_ips.List(client, public_ips.ListOpts{}) - err := tmp.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := public_ips.ExtractPublicIPs(page) - if err != nil { - t.Errorf("Failed to extract public ips: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedPublicIPSlice, actual) - - return true, nil - }) - - if err != nil { - fmt.Printf("%s", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/public_ips/0718a31b-67be-4349-946b-61a0fc38e4cd", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - i, err := public_ips.Get(fake.ServiceClient(), "0718a31b-67be-4349-946b-61a0fc38e4cd").Extract() - t.Logf("%s", err) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &PublicIP1, i) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/public_ips", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - options := public_ips.CreateOpts{ - Name: "seinou-test-public", - Description: "", - InternetGwID: "2a75cfa6-89af-425b-bce5-2a85197ef04f", - SubmaskLength: 29, - TenantID: "19ab165c7a664abe9c217334cd0e9cc9", - } - i, err := public_ips.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Status, "PENDING_CREATE") - th.AssertDeepEquals(t, &PublicIP1, i) -} - -func TestUpdate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/public_ips/0718a31b-67be-4349-946b-61a0fc38e4cd", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - name := "seinou-test-public" - description := "" - options := public_ips.UpdateOpts{Name: &name, Description: &description} - i, err := public_ips.Update(fake.ServiceClient(), "0718a31b-67be-4349-946b-61a0fc38e4cd", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Name, "seinou-test-public") - th.AssertEquals(t, i.Description, "") - th.AssertEquals(t, i.ID, "0718a31b-67be-4349-946b-61a0fc38e4cd") -} - -func TestDelete(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/public_ips/0718a31b-67be-4349-946b-61a0fc38e4cd", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := public_ips.Delete(fake.ServiceClient(), "0718a31b-67be-4349-946b-61a0fc38e4cd") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/public_ips/urls.go b/v3/ecl/network/v2/public_ips/urls.go deleted file mode 100644 index 7aca340..0000000 --- a/v3/ecl/network/v2/public_ips/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package public_ips - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("public_ips", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("public_ips") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/qos_options/doc.go b/v3/ecl/network/v2/qos_options/doc.go deleted file mode 100644 index cd8de8c..0000000 --- a/v3/ecl/network/v2/qos_options/doc.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Package qos_options provides information of several service -in the Enterprise Cloud Compute service - -Example to List QoS Options - - listOpts := qos_options.ListOpts{ - QoSType: "guarantee", - } - - allPages, err := qos_options.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allQoSOptions, err := qos_options.ExtractQoSOptions(allPages) - if err != nil { - panic(err) - } - - for _, qosOption := range allQoSOptions { - fmt.Printf("%+v", qosOption) - } - -Example to Show QoS Option - - id := "02dc9a22-129c-4b12-9936-4080f6a7ae44" - qosOption, err := qos_options.Get(client, id).Extract() - if err != nil { - panic(err) - } - fmt.Print(qosOption) - -*/ -package qos_options diff --git a/v3/ecl/network/v2/qos_options/requests.go b/v3/ecl/network/v2/qos_options/requests.go deleted file mode 100644 index fef4f7d..0000000 --- a/v3/ecl/network/v2/qos_options/requests.go +++ /dev/null @@ -1,87 +0,0 @@ -package qos_options - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToQosOptionsListQuery() (string, error) -} - -// ListOpts allows the filtering of paginated collections through the API. -// Filtering is achieved by passing in struct field values that map to -// the QoS option attributes you want to see returned. Marker and Limit are used -// for pagination. -type ListOpts struct { - // Unique ID for the AWSService. - AWSServiceID string `q:"aws_service_id"` - - // Unique ID for the AzureService. - AzureServiceID string `q:"azure_service_id"` - - // Bandwidth assigned with this QoS Option - Bandwidth string `q:"bandwidth"` - - // Description is the description of the QoS Policy. - Description string `q:"description"` - - // Unique ID for the FICService. - FICServiceID string `q:"fic_service_id"` - - // Unique ID for the GCPService. - GCPServiceID string `q:"gcp_service_id"` - - // Unique ID for the QoS option. - ID string `q:"id"` - - // Unique ID for the InterDCService. - InterDCServiceID string `q:"interdc_service_id"` - - // Unique ID for the InternetService. - InternetServiceID string `q:"internet_service_id"` - - // Name is the name of the QoS option. - Name string `q:"name"` - - // Type of the QoS option.(guarantee or besteffort) - QoSType string `q:"qos_type"` - - // Service type of the QoS option.(aws, azure, fic, gcp, vpn, internet, interdc) - ServiceType string `q:"service_type"` - - // Indicates whether QoS option is currently operational. - Status string `q:"status"` - - // Unique ID for the VPNService. - VPNServiceID string `q:"vpn_service_id"` -} - -// ToQosOptionsListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToQosOptionsListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List makes a request against the API to list QoS options accessible to you. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToQosOptionsListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return QosOptionPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific QoS option based on its unique ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} diff --git a/v3/ecl/network/v2/qos_options/results.go b/v3/ecl/network/v2/qos_options/results.go deleted file mode 100644 index 4fe3c61..0000000 --- a/v3/ecl/network/v2/qos_options/results.go +++ /dev/null @@ -1,60 +0,0 @@ -package qos_options - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type QosOptionPage struct { - pagination.LinkedPageBase -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the result of Get operations. Call its Extract method to -// interpret it as a QoSOption. -type GetResult struct { - commonResult -} - -// QoSOption represents a QoS option. -type QoSOption struct { - AWSServiceID string `json:"aws_service_id"` - AzureServiceID string `json:"azure_service_id"` - Bandwidth string `json:"bandwidth"` - Description string `json:"description"` - FICServiceID string `json:"fic_service_id"` - GCPServiceID string `json:"gcp_service_id"` - ID string `json:"id"` - InterDCServiceID string `json:"interdc_service_id"` - InternetServiceID string `json:"internet_service_id"` - Name string `json:"name"` - QoSType string `json:"qos_type"` - ServiceType string `json:"service_type"` - Status string `json:"status"` - VPNServiceID string `json:"vpn_service_id"` -} - -// IsEmpty checks whether a QosOptionPage struct is empty. -func (r QosOptionPage) IsEmpty() (bool, error) { - is, err := ExtractQoSOptions(r) - return len(is) == 0, err -} - -// ExtractQoSOptions accepts a Page struct, specifically a QoSOptionPage struct, -// and extracts the elements into a slice of ListOpts structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractQoSOptions(r pagination.Page) ([]QoSOption, error) { - var s []QoSOption - err := r.(QosOptionPage).Result.ExtractIntoSlicePtr(&s, "qos_options") - return s, err -} - -// Extract is a function that accepts a result and extracts a QoSOption. -func (r GetResult) Extract() (*QoSOption, error) { - var l QoSOption - err := r.Result.ExtractIntoStructPtr(&l, "qos_option") - return &l, err -} diff --git a/v3/ecl/network/v2/qos_options/testing/doc.go b/v3/ecl/network/v2/qos_options/testing/doc.go deleted file mode 100644 index bf82f4e..0000000 --- a/v3/ecl/network/v2/qos_options/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// ports unit tests -package testing diff --git a/v3/ecl/network/v2/qos_options/testing/fixtures.go b/v3/ecl/network/v2/qos_options/testing/fixtures.go deleted file mode 100644 index fc9df64..0000000 --- a/v3/ecl/network/v2/qos_options/testing/fixtures.go +++ /dev/null @@ -1,99 +0,0 @@ -package testing - -import "github.com/nttcom/eclcloud/v3/ecl/network/v2/qos_options" - -const ListResponse = ` -{ - "qos_options": [ - { - "aws_service_id" : null, - "azure_service_id" : "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "bandwidth" : "20", - "description" : "20M-guarantee-menu-for-azure", - "fic_service_id" : null, - "gcp_service_id" : null, - "id" : "a6b91294-8870-4f2c-b9e9-a899acada723", - "interdc_service_id" : null, - "internet_service_id" : null, - "name" : "20M-GA-AZURE", - "qos_type" : "guarantee", - "service_type" : "azure", - "status" : "ACTIVE", - "vpn_service_id" : null - }, - { - "aws_service_id" : null, - "azure_service_id" : "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "bandwidth" : "500", - "description" : "500M-guarantee-menu-for-azure", - "fic_service_id" : null, - "gcp_service_id" : null, - "id" : "aa776ce4-08a8-4cc1-9a2c-bb95e547916b", - "interdc_service_id" : null, - "internet_service_id" : null, - "name" : "500M-GA-AZURE", - "qos_type" : "guarantee", - "service_type" : "azure", - "status" : "ACTIVE", - "vpn_service_id" : null - } - ] -} -` - -const GetResponse = ` -{ - "qos_option": { - "aws_service_id" : null, - "azure_service_id" : "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - "bandwidth" : "20", - "description" : "20M-guarantee-menu-for-azure", - "fic_service_id" : null, - "gcp_service_id" : null, - "id" : "a6b91294-8870-4f2c-b9e9-a899acada723", - "interdc_service_id" : null, - "internet_service_id" : null, - "name" : "20M-GA-AZURE", - "qos_type" : "guarantee", - "service_type" : "azure", - "status" : "ACTIVE", - "vpn_service_id" : null - } -} -` - -var Qos1 = qos_options.QoSOption{ - AWSServiceID: "", - AzureServiceID: "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - Bandwidth: "20", - Description: "20M-guarantee-menu-for-azure", - FICServiceID: "", - GCPServiceID: "", - ID: "a6b91294-8870-4f2c-b9e9-a899acada723", - InterDCServiceID: "", - InternetServiceID: "", - Name: "20M-GA-AZURE", - QoSType: "guarantee", - ServiceType: "azure", - Status: "ACTIVE", - VPNServiceID: "", -} - -var Qos2 = qos_options.QoSOption{ - AWSServiceID: "", - AzureServiceID: "d4006e79-9f60-4b72-9f86-5f6ef8b4e9e9", - Bandwidth: "500", - Description: "500M-guarantee-menu-for-azure", - FICServiceID: "", - GCPServiceID: "", - ID: "aa776ce4-08a8-4cc1-9a2c-bb95e547916b", - InterDCServiceID: "", - InternetServiceID: "", - Name: "500M-GA-AZURE", - QoSType: "guarantee", - ServiceType: "azure", - Status: "ACTIVE", - VPNServiceID: "", -} - -var ExpectedQosSlice = []qos_options.QoSOption{Qos1, Qos2} diff --git a/v3/ecl/network/v2/qos_options/testing/request_test.go b/v3/ecl/network/v2/qos_options/testing/request_test.go deleted file mode 100644 index 8f3589a..0000000 --- a/v3/ecl/network/v2/qos_options/testing/request_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package testing - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/qos_options" - "github.com/nttcom/eclcloud/v3/pagination" - - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListQoS(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/qos_options", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - qos_options.List(client, qos_options.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := qos_options.ExtractQoSOptions(page) - if err != nil { - t.Errorf("Failed to extract QoS options: %v", err) - return false, nil - } - th.CheckDeepEquals(t, ExpectedQosSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetQoS(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - id := "2c649b8e-f007-4d90-b208-9b8710937a94" - th.Mux.HandleFunc(fmt.Sprintf("/v2.0/qos_options/%s", id), - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - n, err := qos_options.Get(fake.ServiceClient(), id).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &Qos1, n) -} diff --git a/v3/ecl/network/v2/qos_options/urls.go b/v3/ecl/network/v2/qos_options/urls.go deleted file mode 100644 index b651e3e..0000000 --- a/v3/ecl/network/v2/qos_options/urls.go +++ /dev/null @@ -1,11 +0,0 @@ -package qos_options - -import "github.com/nttcom/eclcloud/v3" - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("qos_options", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("qos_options") -} diff --git a/v3/ecl/network/v2/static_routes/doc.go b/v3/ecl/network/v2/static_routes/doc.go deleted file mode 100644 index 00ca023..0000000 --- a/v3/ecl/network/v2/static_routes/doc.go +++ /dev/null @@ -1 +0,0 @@ -package static_routes diff --git a/v3/ecl/network/v2/static_routes/requests.go b/v3/ecl/network/v2/static_routes/requests.go deleted file mode 100644 index aa425ee..0000000 --- a/v3/ecl/network/v2/static_routes/requests.go +++ /dev/null @@ -1,151 +0,0 @@ -package static_routes - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type ListOptsBuilder interface { - ToStaticRouteListQuery() (string, error) -} - -type ListOpts struct { - AwsGwID string `q:"aws_gw_id"` - AzureGwID string `q:"azure_gw_id"` - Description string `q:"description"` - Destination string `q:"destination"` - FICGatewayID string `q:"fic_gw_id"` - GcpGwID string `q:"gcp_gw_id"` - ID string `q:"id"` - InterdcGwID string `q:"inter_dc_id"` - InternetGwID string `q:"internet_gw_id"` - Name string `q:"name"` - Nexthop string `q:"nexthop"` - ServiceType string `q:"service_type"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - VpnGwID string `q:"vpn_gw_id"` -} - -func (opts ListOpts) ToStaticRouteListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToStaticRouteListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return StaticRoutePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -func Get(c *eclcloud.ServiceClient, publicIPID string) (r GetResult) { - _, r.Err = c.Get(getURL(c, publicIPID), &r.Body, nil) - return -} - -type CreateOptsBuilder interface { - ToStaticRouteCreateMap() (map[string]interface{}, error) -} - -type CreateOpts struct { - AwsGwID string `json:"aws_gw_id,omitempty"` - AzureGwID string `json:"azure_gw_id,omitempty"` - Description string `json:"description"` - Destination string `json:"destination" required:"true"` - FICGatewayID string `json:"fic_gw_id,omitempty"` - GcpGwID string `json:"gcp_gw_id,omitempty"` - InterdcGwID string `json:"inter_dc_id,omitempty"` - InternetGwID string `json:"internet_gw_id,omitempty"` - Name string `json:"name"` - Nexthop string `json:"nexthop" required:"true"` - ServiceType string `json:"service_type" required:"true"` - TenantID string `json:"tenant_id,omitempty"` - VpnGwID string `json:"vpn_gw_id,omitempty"` -} - -func (opts CreateOpts) ToStaticRouteCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "static_route") -} - -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToStaticRouteCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -type UpdateOptsBuilder interface { - ToStaticRouteUpdateMap() (map[string]interface{}, error) -} - -type UpdateOpts struct { - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` -} - -func (opts UpdateOpts) ToStaticRouteUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "static_route") -} - -func Update(c *eclcloud.ServiceClient, publicIPID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToStaticRouteUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, publicIPID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -func Delete(c *eclcloud.ServiceClient, publicIPID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, publicIPID), nil) - return -} - -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractStaticRoutes(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "static_route"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "static_route"} - } -} diff --git a/v3/ecl/network/v2/static_routes/results.go b/v3/ecl/network/v2/static_routes/results.go deleted file mode 100644 index b64afda..0000000 --- a/v3/ecl/network/v2/static_routes/results.go +++ /dev/null @@ -1,84 +0,0 @@ -package static_routes - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*StaticRoute, error) { - var s StaticRoute - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "static_route") -} - -type CreateResult struct { - commonResult -} - -type GetResult struct { - commonResult -} - -type UpdateResult struct { - commonResult -} - -type DeleteResult struct { - eclcloud.ErrResult -} - -type StaticRoute struct { - AwsGwID string `json:"aws_gw_id"` - AzureGwID string `json:"azure_gw_id"` - Description string `json:"description"` - Destination string `json:"destination"` - FICGatewayID string `json:"fic_gw_id"` - GcpGwID string `json:"gcp_gw_id"` - ID string `json:"id"` - InterdcGwID string `json:"interdc_gw_id"` - InternetGwID string `json:"internet_gw_id"` - Name string `json:"name"` - Nexthop string `json:"nexthop"` - ServiceType string `json:"service_type"` - Status string `json:"status"` - TenantID string `json:"tenant_id"` - VpnGwID string `json:"vpn_gw_id"` -} - -type StaticRoutePage struct { - pagination.LinkedPageBase -} - -func (r StaticRoutePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"static_routes_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -func (r StaticRoutePage) IsEmpty() (bool, error) { - is, err := ExtractStaticRoutes(r) - return len(is) == 0, err -} - -func ExtractStaticRoutes(r pagination.Page) ([]StaticRoute, error) { - var s []StaticRoute - err := ExtractStaticRoutesInto(r, &s) - return s, err -} - -func ExtractStaticRoutesInto(r pagination.Page, v interface{}) error { - return r.(StaticRoutePage).Result.ExtractIntoSlicePtr(v, "static_routes") -} diff --git a/v3/ecl/network/v2/static_routes/testing/doc.go b/v3/ecl/network/v2/static_routes/testing/doc.go deleted file mode 100644 index ab98250..0000000 --- a/v3/ecl/network/v2/static_routes/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// public_ips unit tests -package testing diff --git a/v3/ecl/network/v2/static_routes/testing/fixtures.go b/v3/ecl/network/v2/static_routes/testing/fixtures.go deleted file mode 100644 index 8bf3357..0000000 --- a/v3/ecl/network/v2/static_routes/testing/fixtures.go +++ /dev/null @@ -1,155 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/static_routes" -) - -const ListResponse = ` -{ - "static_routes": [ - { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "SRT2", - "destination": "100.127.254.116/30", - "fic_gw_id": "5af4f343-91a7-4956-aabb-9ac678d215e5", - "gcp_gw_id": null, - "id": "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", - "interdc_gw_id": null, - "internet_gw_id": null, - "name": "SRT2", - "nexthop": "100.127.254.117", - "service_type": "fic", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "vpn_gw_id": null - }, - { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "StaticRoute for Scenario-test.", - "destination": "100.127.255.184/29", - "fic_gw_id": "1331e6a7-2876-4d34-b12f-5aac9517b034", - "gcp_gw_id": null, - "id": "e58162ca-9fef-4f27-898f-af0d495b780c", - "interdc_gw_id": null, - "internet_gw_id": null, - "name": "StaticRoute_INGW_02_01", - "nexthop": "100.127.255.189", - "service_type": "fic", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "vpn_gw_id": null - } - ] -} -` - -const GetResponse = ` -{ - "static_route": { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "SRT2", - "destination": "100.127.254.116/30", - "fic_gw_id": "5af4f343-91a7-4956-aabb-9ac678d215e5", - "gcp_gw_id": null, - "id": "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", - "interdc_gw_id": null, - "internet_gw_id": null, - "name": "SRT2", - "nexthop": "100.127.254.117", - "service_type": "fic", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "vpn_gw_id": null - } -} -` - -const CreateRequest = ` -{ - "static_route": { - "description": "SRT2", - "destination": "100.127.254.116/30", - "fic_gw_id": "5af4f343-91a7-4956-aabb-9ac678d215e5", - "name": "SRT2", - "nexthop": "100.127.254.117", - "service_type": "fic", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - } -} -` - -const CreateResponse = ` -{ - "static_route": { - "description": "SRT2", - "destination": "100.127.254.116/30", - "fic_gw_id": "5af4f343-91a7-4956-aabb-9ac678d215e5", - "id": "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", - "name": "SRT2", - "nexthop": "100.127.254.117", - "service_type": "fic", - "status": "PENDING_CREATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8" - } -} -` - -const UpdateRequest = ` -{ - "static_route": { - "description": "SRT2", - "name": "SRT2" - } -} - ` - -const UpdateResponse = ` -{ - "static_route": { - "aws_gw_id": null, - "azure_gw_id": null, - "description": "SRT2", - "destination": "100.127.254.116/30", - "fic_gw_id": "5af4f343-91a7-4956-aabb-9ac678d215e5", - "gcp_gw_id": null, - "id": "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", - "interdc_gw_id": null, - "internet_gw_id": null, - "name": "SRT2", - "nexthop": "100.127.254.117", - "service_type": "fic", - "status": "PENDING_UPDATE", - "tenant_id": "6a156ddf2ecd497ca786ff2da6df5aa8", - "vpn_gw_id": null - } -} -` - -var StaticRoute1 = static_routes.StaticRoute{ - Description: "SRT2", - Destination: "100.127.254.116/30", - FICGatewayID: "5af4f343-91a7-4956-aabb-9ac678d215e5", - ID: "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", - Name: "SRT2", - Nexthop: "100.127.254.117", - ServiceType: "fic", - Status: "PENDING_CREATE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", -} - -var StaticRoute2 = static_routes.StaticRoute{ - Description: "StaticRoute for Scenario-test.", - Destination: "100.127.255.184/29", - FICGatewayID: "1331e6a7-2876-4d34-b12f-5aac9517b034", - ID: "e58162ca-9fef-4f27-898f-af0d495b780c", - Name: "StaticRoute_INGW_02_01", - Nexthop: "100.127.255.189", - ServiceType: "fic", - Status: "PENDING_CREATE", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", -} - -var ExpectedStaticRouteSlice = []static_routes.StaticRoute{StaticRoute1, StaticRoute2} diff --git a/v3/ecl/network/v2/static_routes/testing/request_test.go b/v3/ecl/network/v2/static_routes/testing/request_test.go deleted file mode 100644 index cbcddda..0000000 --- a/v3/ecl/network/v2/static_routes/testing/request_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/static_routes" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListStaticRoutes(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/static_routes", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - tmp := static_routes.List(client, static_routes.ListOpts{}) - err := tmp.EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := static_routes.ExtractStaticRoutes(page) - if err != nil { - t.Errorf("Failed to extract public ips: %v", err) - return false, err - } - - th.CheckDeepEquals(t, ExpectedStaticRouteSlice, actual) - - return true, nil - }) - - if err != nil { - fmt.Printf("%s", err) - } - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetStaticRoute(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/static_routes/cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - i, err := static_routes.Get(fake.ServiceClient(), "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a").Extract() - t.Logf("%s", err) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &StaticRoute1, i) -} - -func TestCreateStaticRoute(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/static_routes", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - options := static_routes.CreateOpts{ - Name: "SRT2", - Description: "SRT2", - Destination: "100.127.254.116/30", - FICGatewayID: "5af4f343-91a7-4956-aabb-9ac678d215e5", - Nexthop: "100.127.254.117", - ServiceType: "fic", - TenantID: "6a156ddf2ecd497ca786ff2da6df5aa8", - } - i, err := static_routes.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Status, "PENDING_CREATE") - th.AssertDeepEquals(t, &StaticRoute1, i) -} - -func TestUpdateStaticRoute(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/static_routes/cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - name := "SRT2" - description := "SRT2" - options := static_routes.UpdateOpts{Name: &name, Description: &description} - i, err := static_routes.Update(fake.ServiceClient(), "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", options).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, i.Name, "SRT2") - th.AssertEquals(t, i.Description, "SRT2") - th.AssertEquals(t, i.ID, "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a") -} - -func TestDeleteStaticRoute(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/static_routes/cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := static_routes.Delete(fake.ServiceClient(), "cd1dacf1-0838-4ffc-bbb8-54d3152b9a5a") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/static_routes/urls.go b/v3/ecl/network/v2/static_routes/urls.go deleted file mode 100644 index da27d18..0000000 --- a/v3/ecl/network/v2/static_routes/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package static_routes - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("static_routes", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("static_routes") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/network/v2/subnets/doc.go b/v3/ecl/network/v2/subnets/doc.go deleted file mode 100644 index d0ed8df..0000000 --- a/v3/ecl/network/v2/subnets/doc.go +++ /dev/null @@ -1,133 +0,0 @@ -/* -Package subnets contains functionality for working with Neutron subnet -resources. A subnet represents an IP address block that can be used to -assign IP addresses to virtual instances. Each subnet must have a CIDR and -must be associated with a network. IPs can either be selected from the whole -subnet CIDR or from allocation pools specified by the user. - -A subnet can also have a gateway, a list of DNS name servers, and host routes. -This information is pushed to instances whose interfaces are associated with -the subnet. - -Example to List Subnets - - listOpts := subnets.ListOpts{ - IPVersion: 4, - } - - allPages, err := subnets.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allSubnets, err := subnets.ExtractSubnets(allPages) - if err != nil { - panic(err) - } - - for _, subnet := range allSubnets { - fmt.Printf("%+v\n", subnet) - } - -Example to Create a Subnet With Specified Gateway - - var gatewayIP = "192.168.199.1" - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - IPVersion: 4, - CIDR: "192.168.199.0/24", - GatewayIP: &gatewayIP, - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }, - DNSNameservers: []string{"foo"}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Create a Subnet With No Gateway - - var noGateway = "" - - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - IPVersion: 4, - CIDR: "192.168.1.0/24", - GatewayIP: &noGateway, - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.1.2", - End: "192.168.1.254", - }, - }, - DNSNameservers: []string{}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Create a Subnet With a Default Gateway - - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - IPVersion: 4, - CIDR: "192.168.1.0/24", - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.1.2", - End: "192.168.1.254", - }, - }, - DNSNameservers: []string{}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Subnet - - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - - updateOpts := subnets.UpdateOpts{ - Name: "new_name", - DNSNameservers: []string{"8.8.8.8}, - } - - subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Remove a Gateway From a Subnet - - var noGateway = "" - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - - updateOpts := subnets.UpdateOpts{ - GatewayIP: &noGateway, - } - - subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Subnet - - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - err := subnets.Delete(networkClient, subnetID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package subnets diff --git a/v3/ecl/network/v2/subnets/requests.go b/v3/ecl/network/v2/subnets/requests.go deleted file mode 100644 index 4fc6067..0000000 --- a/v3/ecl/network/v2/subnets/requests.go +++ /dev/null @@ -1,238 +0,0 @@ -package subnets - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToSubnetListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the subnet attributes you want to see returned. SortKey allows you to sort -// by a particular subnet attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - CIDR string `q:"cidr"` - Description string `q:"description"` - GatewayIP string `q:"gateway_ip"` - ID string `q:"id"` - IPVersion int `q:"ip_version"` - IPv6AddressMode string `q:"ipv6_address_mode"` - IPv6RAMode string `q:"ipv6_ra_mode"` - Name string `q:"name"` - NetworkID string `q:"network_id"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` -} - -// ToSubnetListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToSubnetListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// subnets. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those subnets that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToSubnetListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return SubnetPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific subnet based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// List request. -type CreateOptsBuilder interface { - ToSubnetCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents the attributes used when creating a new subnet. -type CreateOpts struct { - // AllocationPools are IP Address pools that will be available for DHCP. - AllocationPools []AllocationPool `json:"allocation_pools,omitempty"` - // CIDR is the address CIDR of the subnet. - CIDR string `json:"cidr" required:"true"` - // Description is description - Description string `json:"description,omitempty"` - // DNSNameservers are the nameservers to be set via DHCP. - DNSNameservers []string `json:"dns_nameservers,omitempty"` - // EnableDHCP will either enable to disable the DHCP service. - EnableDHCP *bool `json:"enable_dhcp,omitempty"` - // GatewayIP sets gateway information for the subnet. Setting to nil will - // cause a default gateway to automatically be created. Setting to an empty - // string will cause the subnet to be created with no gateway. Setting to - // an explicit address will set that address as the gateway. - GatewayIP *string `json:"gateway_ip,omitempty"` - // HostRoutes are any static host routes to be set via DHCP. - HostRoutes []HostRoute `json:"host_routes,omitempty"` - // IPVersion is the IP version for the subnet. - IPVersion eclcloud.IPVersion `json:"ip_version,omitempty"` - // Name is a human-readable name of the subnet. - Name string `json:"name,omitempty"` - // NetworkID is the UUID of the network the subnet will be associated with. - NetworkID string `json:"network_id" required:"true"` - // NTPServers are List of ntp servers. - NTPServers []string `json:"ntp_servers,omitempty"` - // Tags are tags - Tags map[string]string `json:"tags,omitempty"` - // The UUID of the project who owns the Subnet. Only administrative users - // can specify a project UUID other than their own. - TenantID string `json:"tenant_id,omitempty"` -} - -// ToSubnetCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "subnet") - if err != nil { - return nil, err - } - - if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" { - m["gateway_ip"] = nil - } - - return b, nil -} - -// Create accepts a CreateOpts struct and creates a new subnet using the values -// provided. You must remember to provide a valid NetworkID, CIDR and IP -// version. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToSubnetCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToSubnetUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the attributes used when updating an existing subnet. -type UpdateOpts struct { - // Name is a human-readable name of the subnet. - Name *string `json:"name,omitempty"` - - // GatewayIP sets gateway information for the subnet. Setting to nil will - // cause a default gateway to automatically be created. Setting to an empty - // string will cause the subnet to be created with no gateway. Setting to - // an explicit address will set that address as the gateway. - GatewayIP *string `json:"gateway_ip,omitempty"` - - // DNSNameservers are the nameservers to be set via DHCP. - DNSNameservers []string `json:"dns_nameservers,omitempty"` - - // HostRoutes are any static host routes to be set via DHCP. - HostRoutes *[]HostRoute `json:"host_routes,omitempty"` - - // EnableDHCP will either enable to disable the DHCP service. - EnableDHCP *bool `json:"enable_dhcp,omitempty"` - - // Description is description - Description *string `json:"description,omitempty"` - - // NTPServers are List of ntp servers. - NTPServers *[]string `json:"ntp_servers,omitempty"` - - // Tags are tags - Tags *map[string]string `json:"tags,omitempty"` -} - -// ToSubnetUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { - b, err := eclcloud.BuildRequestBody(opts, "subnet") - if err != nil { - return nil, err - } - - if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" { - m["gateway_ip"] = nil - } - - return b, nil -} - -// Update accepts a UpdateOpts struct and updates an existing subnet using the -// values provided. -func Update(c *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToSubnetUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200, 201}, - }) - return -} - -// Delete accepts a unique ID and deletes the subnet associated with it. -func Delete(c *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, id), nil) - return -} - -// IDFromName is a convenience function that returns a subnet's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractSubnets(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"} - } -} diff --git a/v3/ecl/network/v2/subnets/results.go b/v3/ecl/network/v2/subnets/results.go deleted file mode 100644 index 0bf3654..0000000 --- a/v3/ecl/network/v2/subnets/results.go +++ /dev/null @@ -1,152 +0,0 @@ -package subnets - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a subnet resource. -func (r commonResult) Extract() (*Subnet, error) { - var s struct { - Subnet *Subnet `json:"subnet"` - } - err := r.ExtractInto(&s) - return s.Subnet, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Subnet. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Subnet. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Subnet. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// AllocationPool represents a sub-range of cidr available for dynamic -// allocation to ports, e.g. {Start: "10.0.0.2", End: "10.0.0.254"} -type AllocationPool struct { - Start string `json:"start"` - End string `json:"end"` -} - -// HostRoute represents a route that should be used by devices with IPs from -// a subnet (not including local subnet route). -type HostRoute struct { - DestinationCIDR string `json:"destination"` - NextHop string `json:"nexthop"` -} - -// Subnet represents a subnet. See package documentation for a top-level -// description of what this is. -type Subnet struct { - // UUID representing the subnet. - ID string `json:"id"` - - // UUID of the parent network. - NetworkID string `json:"network_id"` - - // Human-readable name for the subnet. Might not be unique. - Name string `json:"name"` - - // IP version, either `4' or `6'. - IPVersion int `json:"ip_version"` - - // CIDR representing IP range for this subnet, based on IP version. - CIDR string `json:"cidr"` - - // Default gateway used by devices in this subnet. - GatewayIP string `json:"gateway_ip"` - - // DNS name servers used by hosts in this subnet. - DNSNameservers []string `json:"dns_nameservers"` - - // Sub-ranges of CIDR available for dynamic allocation to ports. - // See AllocationPool. - AllocationPools []AllocationPool `json:"allocation_pools"` - - // Routes that should be used by devices with IPs from this subnet - // (not including local subnet route). - HostRoutes []HostRoute `json:"host_routes"` - - // Specifies whether DHCP is enabled for this subnet or not. - EnableDHCP bool `json:"enable_dhcp"` - - // TenantID is the project owner of the subnet. - TenantID string `json:"tenant_id"` - - // The IPv6 address modes specifies mechanisms for assigning IPv6 IP addresses. - IPv6AddressMode string `json:"ipv6_address_mode"` - - // The IPv6 router advertisement specifies whether the networking service - // should transmit ICMPv6 packets. - IPv6RAMode string `json:"ipv6_ra_mode"` - - // Description is description - Description string `json:"description"` - - // NTPServers are List of ntp servers. - NTPServers []string `json:"ntp_servers"` - - // Status is Status - Status string `json:"status"` - - // Tags optionally set via extensions/attributestags - Tags map[string]string `json:"tags"` -} - -// SubnetPage is the page returned by a pager when traversing over a collection -// of subnets. -type SubnetPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of subnets has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r SubnetPage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"subnets_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a SubnetPage struct is empty. -func (r SubnetPage) IsEmpty() (bool, error) { - is, err := ExtractSubnets(r) - return len(is) == 0, err -} - -// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct, -// and extracts the elements into a slice of Subnet structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractSubnets(r pagination.Page) ([]Subnet, error) { - var s struct { - Subnets []Subnet `json:"subnets"` - } - err := (r.(SubnetPage)).ExtractInto(&s) - return s.Subnets, err -} diff --git a/v3/ecl/network/v2/subnets/testing/doc.go b/v3/ecl/network/v2/subnets/testing/doc.go deleted file mode 100644 index bf82f4e..0000000 --- a/v3/ecl/network/v2/subnets/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// ports unit tests -package testing diff --git a/v3/ecl/network/v2/subnets/testing/fixtures.go b/v3/ecl/network/v2/subnets/testing/fixtures.go deleted file mode 100644 index f1cecd3..0000000 --- a/v3/ecl/network/v2/subnets/testing/fixtures.go +++ /dev/null @@ -1,246 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/network/v2/subnets" -) - -const ListResponse = ` -{ - "subnets": [ - { - "allocation_pools": [ - { - "end": "192.168.2.254", - "start": "192.168.2.2" - } - ], - "cidr": "192.168.2.0/24", - "description": "", - "dns_nameservers": [ - "0.0.0.0" - ], - "enable_dhcp": true, - "gateway_ip": "192.168.2.1", - "host_routes": [], - "id": "ab49eb24-667f-4a4e-9421-b4d915bff416", - "ip_version": 4, - "ipv6_address_mode": null, - "ipv6_ra_mode": null, - "name": "", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "ntp_servers": [], - "status": "ACTIVE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - }, - { - "allocation_pools": [ - { - "end": "192.168.10.254", - "start": "192.168.10.2" - } - ], - "cidr": "192.168.10.0/24", - "description": "", - "dns_nameservers": [ - "0.0.0.0" - ], - "enable_dhcp": true, - "gateway_ip": "192.168.10.1", - "host_routes": [], - "id": "f6aa2d33-f3ae-4c4e-82f7-0d4ab4c67678", - "ip_version": 4, - "ipv6_address_mode": null, - "ipv6_ra_mode": null, - "name": "", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "ntp_servers": [], - "status": "ACTIVE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - ] - } -` -const GetResponse = ` -{ - "subnet": { - "allocation_pools": [ - { - "end": "192.168.2.254", - "start": "192.168.2.2" - } - ], - "cidr": "192.168.2.0/24", - "description": "", - "dns_nameservers": [ - "0.0.0.0" - ], - "enable_dhcp": true, - "gateway_ip": "192.168.2.1", - "host_routes": [], - "id": "ab49eb24-667f-4a4e-9421-b4d915bff416", - "ip_version": 4, - "ipv6_address_mode": null, - "ipv6_ra_mode": null, - "name": "", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "ntp_servers": [], - "status": "ACTIVE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } - ` -const CreateResponse = ` -{ - "subnet": { - "allocation_pools": [ - { - "end": "192.168.10.254", - "start": "192.168.10.2" - } - ], - "cidr": "192.168.10.0/24", - "description": "", - "dns_nameservers": [ - "0.0.0.0" - ], - "enable_dhcp": true, - "gateway_ip": "192.168.10.1", - "host_routes": [], - "id": "f6aa2d33-f3ae-4c4e-82f7-0d4ab4c67678", - "ip_version": 4, - "name": "", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "ntp_servers": [], - "status": "ACTIVE", - "tags": {}, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } - ` -const CreateRequest = ` -{ - "subnet": { - "cidr": "192.168.10.0/24", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782" - } -} -` -const UpdateResponse = ` -{ - "subnet": { - "allocation_pools": [ - { - "end": "192.168.2.254", - "start": "192.168.2.2" - } - ], - "cidr": "192.168.2.0/24", - "description": "UPDATED", - "dns_nameservers": [ - "0.0.0.0", - "1.1.1.1" - ], - "enable_dhcp": false, - "gateway_ip": "192.168.10.1", - "host_routes": [ - { - "destination": "10.2.0.0/24", - "nexthop": "10.1.0.10" - } - ], - "id": "ab49eb24-667f-4a4e-9421-b4d915bff416", - "ip_version": 4, - "ipv6_address_mode": null, - "ipv6_ra_mode": null, - "name": "UPDATED", - "network_id": "8f36b88a-443f-4d97-9751-34d34af9e782", - "ntp_servers": [ - "2.2.2.2" - ], - "status": "PENDING_UPDATE", - "tags": { - "updated": "true" - }, - "tenant_id": "dcb2d589c0c646d0bad45c0cf9f90cf1" - } - } -` -const UpdateRequest = ` -{ - "subnet": { - "description": "UPDATED", - "dns_nameservers": [ - "0.0.0.0", - "1.1.1.1" - ], - "enable_dhcp": false, - "gateway_ip": "192.168.10.1", - "host_routes": [{ - "destination": "10.2.0.0/24", - "nexthop": "10.1.0.10" - }], - "name": "UPDATED", - "ntp_servers": [ - "2.2.2.2" - ], - "tags": { - "updated": "true" - } - } -} -` - -var Subnet1 = subnets.Subnet{ - AllocationPools: []subnets.AllocationPool{ - { - End: "192.168.2.254", - Start: "192.168.2.2", - }, - }, - CIDR: "192.168.2.0/24", - Description: "", - DNSNameservers: []string{ - "0.0.0.0", - }, - EnableDHCP: true, - GatewayIP: "192.168.2.1", - HostRoutes: []subnets.HostRoute{}, - ID: "ab49eb24-667f-4a4e-9421-b4d915bff416", - IPVersion: 4, - Name: "", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - NTPServers: []string{}, - Status: "ACTIVE", - Tags: map[string]string{}, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var Subnet2 = subnets.Subnet{ - AllocationPools: []subnets.AllocationPool{ - { - End: "192.168.10.254", - Start: "192.168.10.2", - }, - }, - CIDR: "192.168.10.0/24", - Description: "", - DNSNameservers: []string{ - "0.0.0.0", - }, - EnableDHCP: true, - GatewayIP: "192.168.10.1", - HostRoutes: []subnets.HostRoute{}, - ID: "f6aa2d33-f3ae-4c4e-82f7-0d4ab4c67678", - IPVersion: 4, - Name: "", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - NTPServers: []string{}, - Status: "ACTIVE", - Tags: map[string]string{}, - TenantID: "dcb2d589c0c646d0bad45c0cf9f90cf1", -} - -var ExpectedSubnetSlice = []subnets.Subnet{Subnet1, Subnet2} diff --git a/v3/ecl/network/v2/subnets/testing/request_test.go b/v3/ecl/network/v2/subnets/testing/request_test.go deleted file mode 100644 index 2b80064..0000000 --- a/v3/ecl/network/v2/subnets/testing/request_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - fake "github.com/nttcom/eclcloud/v3/ecl/network/v2/common" - "github.com/nttcom/eclcloud/v3/ecl/network/v2/subnets" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestListSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fake.ServiceClient() - count := 0 - - subnets.List(client, subnets.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := subnets.ExtractSubnets(page) - if err != nil { - t.Errorf("Failed to extrace ports: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedSubnetSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := subnets.Get(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416").Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &Subnet1, s) -} - -func TestCreateSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - - fmt.Fprintf(w, CreateResponse) - }) - - options := &subnets.CreateOpts{ - CIDR: "192.168.10.0/24", - NetworkID: "8f36b88a-443f-4d97-9751-34d34af9e782", - } - s, err := subnets.Create(fake.ServiceClient(), options).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &Subnet2, s) -} - -func TestRequiredCreateOptsSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - res := subnets.Create(fake.ServiceClient(), subnets.CreateOpts{}) - if res.Err == nil { - t.Fatalf("Expected error, got none") - } -} - -func TestUpdateSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, UpdateResponse) - }) - - description := "UPDATED" - dnsNameservers := []string{ - "0.0.0.0", - "1.1.1.1", - } - enableDHCP := false - gatewayIP := "192.168.10.1" - hostRoutes := []subnets.HostRoute{{ - DestinationCIDR: "10.2.0.0/24", - NextHop: "10.1.0.10", - }} - name := "UPDATED" - ntpServers := []string{ - "2.2.2.2", - } - tags := map[string]string{ - "updated": "true", - } - - options := subnets.UpdateOpts{ - Description: &description, - DNSNameservers: dnsNameservers, - EnableDHCP: &enableDHCP, - GatewayIP: &gatewayIP, - HostRoutes: &hostRoutes, - Name: &name, - NTPServers: &ntpServers, - Tags: &tags, - } - - s, err := subnets.Update(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416", options).Extract() - th.AssertNoErr(t, err) - - th.CheckEquals(t, description, s.Description) - th.CheckDeepEquals(t, dnsNameservers, s.DNSNameservers) - th.CheckEquals(t, enableDHCP, s.EnableDHCP) - th.CheckEquals(t, gatewayIP, s.GatewayIP) - th.CheckDeepEquals(t, hostRoutes, s.HostRoutes) - th.CheckEquals(t, name, s.Name) - th.CheckDeepEquals(t, ntpServers, s.NTPServers) - th.CheckDeepEquals(t, tags, s.Tags) -} - -func TestDeleteSubnet(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v2.0/subnets/ab49eb24-667f-4a4e-9421-b4d915bff416", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := subnets.Delete(fake.ServiceClient(), "ab49eb24-667f-4a4e-9421-b4d915bff416") - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/network/v2/subnets/urls.go b/v3/ecl/network/v2/subnets/urls.go deleted file mode 100644 index 6f86bdc..0000000 --- a/v3/ecl/network/v2/subnets/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package subnets - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("subnets", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("subnets") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/doc.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/doc.go deleted file mode 100644 index 1058a9b..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/doc.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Package tenant_connection_requests manages and retrieves Tenant Connection Request in the Enterprise Cloud Provider Connectivity Service. - -Example to List Tenant Connection Request - - allPages, err := tenant_connection_requests.List(tcrClient).AllPages() - if err != nil { - panic(err) - } - - allTenantConnectionRequests, err := tenant_connection_requests.ExtractTenantConnectionRequests(allPages) - if err != nil { - panic(err) - } - - for _, tenantConnectionRequest := range allTenantConnectionRequests { - fmt.Printf("%+v\n", tenantConnectionRequest) - } - -Example to Get a Tenant Connection Request - - tenant_connection_request_id := "85a1dc30-2e48-11ea-9e55-525403060300" - - tenantConnectionRequest, err := tenant_connection_requests.Get(tcrClient, tenant_connection_request_id).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", tenantConnectionRequest) - -Example to Create a Tenant Connection Request - - createOpts := tenant_connection_requests.CreateOpts{ - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - Name: "create_test_name", - Description: "create_test_desc", - Tags: map[string]string{"foo", "bar"}, - } - - result := tenant_connection_requests.Create(tcrClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Update a Tenant Connection Request - - tenant_connection_request_id := "85a1dc30-2e48-11ea-9e55-525403060300" - updateOpts := tenant_connection_requests.UpdateOpts{ - Name: "update_test_name", - Description: "update_test_desc", - Tags: map[string]string{ - "keyword1": "value1", - "keyword2": "value2", - }, - NameOther: "update_test_name_other", - DescriptionOther: "update_test_desc_other", - TagsOther: map[string]string{ - "keyword1": "value1", - "keyword2": "value2", - }, - } - - result := tenant_connection_requests.Update(tcrClient, tenant_connection_request_id, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a Tenant Connection Request - - tenant_connection_request_id := "85a1dc30-2e48-11ea-9e55-525403060300" - - result := tenant_connection_requests.Delete(tcrClient, tenant_connection_request_id) - if result.Err != nil { - panic(result.Err) - } - -*/ -package tenant_connection_requests diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/requests.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/requests.go deleted file mode 100644 index 6cc6e3c..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/requests.go +++ /dev/null @@ -1,129 +0,0 @@ -package tenant_connection_requests - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToTenantConnectionRequestListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - TenantConnectionRequestID string `q:"tenant_connection_request_id"` - Status string `q:"status"` - Name string `q:"name"` - TenantID string `q:"tenant_id"` - NameOther string `q:"name_other"` - TenantIDOther string `q:"tenant_id_other"` - NetworkID string `q:"network_id"` - ApprovalRequestID string `q:"approval_request_id"` -} - -// ToTenantConnectionRequestListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToTenantConnectionRequestListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List retrieves a list of Tenant Connection Requests. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToTenantConnectionRequestListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return TenantConnectionRequestPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details of an Tenant Connection Request. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToTenantConnectionRequestCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a Tenant Connection Request. -type CreateOpts struct { - TenantIDOther string `json:"tenant_id_other" required:"true"` - NetworkID string `json:"network_id" required:"true"` - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Tags map[string]string `json:"tags,omitempty"` -} - -// ToTenantConnectionRequestCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToTenantConnectionRequestCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "tenant_connection_request") -} - -// Create creates a new Tenant Connection Request. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToTenantConnectionRequestCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a Tenant Connection Request. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToTenantConnectionRequestUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a Tenant Connection Request. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` - NameOther *string `json:"name_other,omitempty"` - DescriptionOther *string `json:"description_other,omitempty"` - TagsOther *map[string]string `json:"tags_other,omitempty"` -} - -// ToResourceUpdateCreateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToTenantConnectionRequestUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "tenant_connection_request") -} - -// Update modifies the attributes of a Tenant Connection Request. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToTenantConnectionRequestUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/results.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/results.go deleted file mode 100644 index 78cd9ba..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/results.go +++ /dev/null @@ -1,80 +0,0 @@ -package tenant_connection_requests - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// TenantConnectionRequest represents Tenant Connection Request. -type TenantConnectionRequest struct { - ID string `json:"id"` - Status string `json:"status"` - Name string `json:"name"` - Description string `json:"description"` - Tags map[string]string `json:"tags"` - TenantID string `json:"tenant_id"` - NameOther string `json:"name_other"` - DescriptionOther string `json:"description_other"` - TagsOther map[string]string `json:"tags_other"` - TenantIDOther string `json:"tenant_id_other"` - NetworkID string `json:"network_id"` - ApprovalRequestID string `json:"approval_request_id"` -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a Tenant Connection Request. -type GetResult struct { - commonResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a Tenant Connection Request. -type CreateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a Tenant Connection Request. -type UpdateResult struct { - commonResult -} - -// TenantConnectionRequestPage is a single page of Tenant Connection Request results. -type TenantConnectionRequestPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Tenant Connection Request contains any results. -func (r TenantConnectionRequestPage) IsEmpty() (bool, error) { - resources, err := ExtractTenantConnectionRequests(r) - return len(resources) == 0, err -} - -// ExtractTenantConnectionRequests returns a slice of Tenant Connection Requests contained in a -// single page of results. -func ExtractTenantConnectionRequests(r pagination.Page) ([]TenantConnectionRequest, error) { - var s struct { - TenantConnectionRequest []TenantConnectionRequest `json:"tenant_connection_requests"` - } - err := (r.(TenantConnectionRequestPage)).ExtractInto(&s) - return s.TenantConnectionRequest, err -} - -// Extract interprets any commonResult as a Tenant Connection Request. -func (r commonResult) Extract() (*TenantConnectionRequest, error) { - var s struct { - TenantConnectionRequest *TenantConnectionRequest `json:"tenant_connection_request"` - } - err := r.ExtractInto(&s) - return s.TenantConnectionRequest, err -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/doc.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/doc.go deleted file mode 100644 index 7370972..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Tenant Connection Request unit tests -package testing diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/fixtures.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/fixtures.go deleted file mode 100644 index 5f13f6d..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/fixtures.go +++ /dev/null @@ -1,457 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/provider_connectivity/v2/tenant_connection_requests" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -// ListResult provides a single page of tenant_connection_request results. -const ListResult = ` -{ - "tenant_connection_requests": [ - { - "id": "5fbcc350-bd33-11e7-afb6-0050569c850d", - "name": "test_name1", - "description": "test_desc1", - "tags": { - "test_tags1": "test1" - }, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "", - "description_other": "", - "tags_other": {}, - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registering", - "approval_request_id": "req0000010454" - }, - { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "created_name", - "description": "created_desc", - "tags": { - "test_tags2": "test2" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tags_other": { - "test_tags_other2": "test2" - }, - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "tenant_connection_request": { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "created_name", - "description": "created_desc", - "tags": { - "test_tags2":"test2" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tags_other": { - "test_tags_other2":"test2" - }, - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } -} -` - -// CreateRequest provides the input to a Create request. -const CreateRequest = ` -{ - "tenant_connection_request": { - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "name": "test_name1", - "description": "test_desc1", - "tags": { - "test_tags1": "test1" - } - } -} -` - -// CreateResponse provides the output from a Create request. -const CreateResponse = ` -{ - "tenant_connection_request": { - "id": "5fbcc350-bd33-11e7-afb6-0050569c850d", - "name": "test_name1", - "description": "test_desc1", - "tags": { - "test_tags1": "test1" - }, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "", - "description_other": "", - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "tags_other": {}, - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registering", - "approval_request_id": "req0000010454" - } -} -` - -// UpdateRequest provides the input to as Update request. -const UpdateRequest = ` -{ - "tenant_connection_request":{ - "name": "updated_name", - "description": "updated_desc", - "tags": { - "k2":"v2" - } - } -} -` - -// UpdateResult provides an update result. -const UpdateResult = ` -{ - "tenant_connection_request": { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "updated_name", - "description": "updated_desc", - "tags": { - "k2": "v2" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tags_other": { - "test_tags_other2": "test2" - }, - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } -} -` - -// UpdateOtherMetadataRequest provides the input to as Update to other metadata request. -const UpdateOtherMetadataRequest = ` -{ - "tenant_connection_request":{ - "name_other": "updated_name_other", - "description_other": "updated_desc_other", - "tags_other": { - "k3":"v3" - } - } -} -` - -// UpdateOtherMetadataResult provides an update to other metadata result. -const UpdateOtherMetadataResult = ` -{ - "tenant_connection_request": { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "created_name", - "description": "created_desc", - "tags": { - "test_tags2": "test2" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "updated_name_other", - "description_other": "updated_desc_other", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tags_other": { - "k3": "v3" - }, - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } -} -` - -// UpdateBlankRequest provides the input to as Update with blank request. -const UpdateBlankRequest = ` -{ - "tenant_connection_request":{ - "name": "", - "description": "", - "tags": {} - } -} -` - -// UpdateBlankResult provides an update with blank result. -const UpdateBlankResult = ` -{ - "tenant_connection_request": { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "", - "description": "", - "tags": {}, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tags_other": { - "test_tags_other2": "test2" - }, - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } -} -` - -// UpdateNilRequest provides the input to as Update with nil request. -const UpdateNilRequest = ` -{ - "tenant_connection_request":{ - "name": "nilupdate" - } -} -` - -// UpdateNilResult provides an update with nil result. -const UpdateNilResult = ` -{ - "tenant_connection_request": { - "id": "90381138-b572-11e7-9391-0050569c850d", - "name": "nilupdate", - "description": "created_desc", - "tags": { - "test_tags2": "test2" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tags_other": { - "test_tags_other2": "test2" - }, - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "status": "registered", - "approval_request_id": "req0000010363" - } -} -` - -// FirstTenantConnectionRequest is the first tenant_connection_request in the List request. -var FirstTenantConnectionRequest = tenant_connection_requests.TenantConnectionRequest{ - ID: "5fbcc350-bd33-11e7-afb6-0050569c850d", - Status: "registering", - Name: "test_name1", - Description: "test_desc1", - Tags: map[string]string{"test_tags1": "test1"}, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{}, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010454", -} - -// SecondTenantConnectionRequest is the second tenant_connection_request in the List request. -var SecondTenantConnectionRequest = tenant_connection_requests.TenantConnectionRequest{ - ID: "90381138-b572-11e7-9391-0050569c850d", - Status: "registered", - Name: "created_name", - Description: "created_desc", - Tags: map[string]string{"test_tags2": "test2"}, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{"test_tags_other2": "test2"}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010363", -} - -// SecondTenantConnectionRequestUpdated is how second tenant_connection_request should look after an Update. -var SecondTenantConnectionRequestUpdated = tenant_connection_requests.TenantConnectionRequest{ - ID: "90381138-b572-11e7-9391-0050569c850d", - Status: "registered", - Name: "updated_name", - Description: "updated_desc", - Tags: map[string]string{"k2": "v2"}, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{"test_tags_other2": "test2"}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010363", -} - -// SecondTenantConnectionRequestOtherMetadataUpdated is how second tenant_connection_request should look after an Update to other metadata. -var SecondTenantConnectionRequestOtherMetadataUpdated = tenant_connection_requests.TenantConnectionRequest{ - ID: "90381138-b572-11e7-9391-0050569c850d", - Status: "registered", - Name: "created_name", - Description: "created_desc", - Tags: map[string]string{"test_tags2": "test2"}, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "updated_name_other", - DescriptionOther: "updated_desc_other", - TagsOther: map[string]string{"k3": "v3"}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010363", -} - -// SecondTenantConnectionRequestBlankUpdated is how second tenant_connection_request should look after an Update with blank. -var SecondTenantConnectionRequestBlankUpdated = tenant_connection_requests.TenantConnectionRequest{ - ID: "90381138-b572-11e7-9391-0050569c850d", - Status: "registered", - Name: "", - Description: "", - Tags: map[string]string{}, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{"test_tags_other2": "test2"}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010363", -} - -// SecondTenantConnectionRequestNilUpdated is how second tenant_connection_request should look after an Update with nil. -var SecondTenantConnectionRequestNilUpdated = tenant_connection_requests.TenantConnectionRequest{ - ID: "90381138-b572-11e7-9391-0050569c850d", - Status: "registered", - Name: "nilupdate", - Description: "created_desc", - Tags: map[string]string{"test_tags2": "test2"}, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{"test_tags_other2": "test2"}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - ApprovalRequestID: "req0000010363", -} - -// ExpectedTenantConnectionRequestsSlice is the slice of tenant_connection_request expected to be returned from ListResult. -var ExpectedTenantConnectionRequestsSlice = []tenant_connection_requests.TenantConnectionRequest{FirstTenantConnectionRequest, SecondTenantConnectionRequest} - -// HandleListTenantConnectionRequestsSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that responds with a list of two tenant_connection_requests. -func HandleListTenantConnectionRequestsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connection_requests", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, ListResult) - }) -} - -// HandleGetTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that responds with a single tenant_connection_request. -func HandleGetTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", SecondTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, GetResult) - }) -} - -// HandleCreateTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request creation. -func HandleCreateTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connection_requests", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, CreateResponse) - }) -} - -// HandleDeleteTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request deletion. -func HandleDeleteTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", FirstTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request update. -func HandleUpdateTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", SecondTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateResult) - }) -} - -// HandleUpdateOtherMetadataTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request update to other metadata result. -func HandleUpdateOtherMetadataTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", SecondTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateOtherMetadataRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateOtherMetadataResult) - }) -} - -// HandleBlankUpdateTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request update with blank. -func HandleBlankUpdateTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", SecondTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateBlankRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateBlankResult) - }) -} - -// HandleNilUpdateTenantConnectionRequestSuccessfully creates an HTTP handler at `/tenant_connection_requests` on the -// test handler mux that tests tenant_connection_request update with nil. -func HandleNilUpdateTenantConnectionRequestSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connection_requests/%s", SecondTenantConnectionRequest.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateNilRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateNilResult) - }) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/requests_test.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/requests_test.go deleted file mode 100644 index f96b44c..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/testing/requests_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/provider_connectivity/v2/tenant_connection_requests" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListTenantConnectionRequests(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantConnectionRequestsSuccessfully(t) - - count := 0 - err := tenant_connection_requests.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := tenant_connection_requests.ExtractTenantConnectionRequests(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedTenantConnectionRequestsSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListTenantConnectionRequestsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantConnectionRequestsSuccessfully(t) - - allPages, err := tenant_connection_requests.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := tenant_connection_requests.ExtractTenantConnectionRequests(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedTenantConnectionRequestsSlice, actual) -} - -func TestGetTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTenantConnectionRequestSuccessfully(t) - - actual, err := tenant_connection_requests.Get(client.ServiceClient(), SecondTenantConnectionRequest.ID).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionRequest, *actual) -} - -func TestCreateTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTenantConnectionRequestSuccessfully(t) - - createOpts := tenant_connection_requests.CreateOpts{ - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - Name: "test_name1", - Description: "test_desc1", - Tags: map[string]string{"test_tags1": "test1"}, - } - - actual, err := tenant_connection_requests.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &FirstTenantConnectionRequest, actual) -} - -func TestDeleteTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTenantConnectionRequestSuccessfully(t) - - res := tenant_connection_requests.Delete(client.ServiceClient(), FirstTenantConnectionRequest.ID) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateTenantConnectionRequestSuccessfully(t) - - name := "updated_name" - description := "updated_desc" - tags := map[string]string{"k2": "v2"} - - updateOpts := tenant_connection_requests.UpdateOpts{ - Name: &name, - Description: &description, - Tags: &tags, - } - - actual, err := tenant_connection_requests.Update(client.ServiceClient(), SecondTenantConnectionRequest.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionRequestUpdated, *actual) -} - -func TestUpdateOtherMetadataTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateOtherMetadataTenantConnectionRequestSuccessfully(t) - - nameOther := "updated_name_other" - descriptionOther := "updated_desc_other" - tagsOther := map[string]string{"k3": "v3"} - - updateOpts := tenant_connection_requests.UpdateOpts{ - NameOther: &nameOther, - DescriptionOther: &descriptionOther, - TagsOther: &tagsOther, - } - - actual, err := tenant_connection_requests.Update(client.ServiceClient(), SecondTenantConnectionRequest.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionRequestOtherMetadataUpdated, *actual) -} - -func TestBlankUpdateTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleBlankUpdateTenantConnectionRequestSuccessfully(t) - - name := "" - description := "" - tags := map[string]string{} - - updateOpts := tenant_connection_requests.UpdateOpts{ - Name: &name, - Description: &description, - Tags: &tags, - } - - actual, err := tenant_connection_requests.Update(client.ServiceClient(), SecondTenantConnectionRequest.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionRequestBlankUpdated, *actual) -} - -func TestNilUpdateTenantConnectionRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNilUpdateTenantConnectionRequestSuccessfully(t) - - name := "nilupdate" - - updateOpts := tenant_connection_requests.UpdateOpts{ - Name: &name, - } - - actual, err := tenant_connection_requests.Update(client.ServiceClient(), SecondTenantConnectionRequest.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionRequestNilUpdated, *actual) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/urls.go b/v3/ecl/provider_connectivity/v2/tenant_connection_requests/urls.go deleted file mode 100644 index b04b1a8..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connection_requests/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package tenant_connection_requests - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenant_connection_requests") -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connection_requests", id) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenant_connection_requests") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connection_requests", id) -} - -func updateURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connection_requests", id) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/doc.go b/v3/ecl/provider_connectivity/v2/tenant_connections/doc.go deleted file mode 100644 index 3d82c48..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/doc.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Package tenant_connections manages and retrieves Tenant Connection in the Enterprise Cloud Provider Connectivity Service. - -Example to List Tenant Connection - - allPages, err := tenant_connections.List(tcClient).AllPages() - if err != nil { - panic(err) - } - - allTenantConnections, err := tenant_connections.ExtractTenantConnections(allPages) - if err != nil { - panic(err) - } - - for _, tenantConnection := range allTenantConnections { - fmt.Printf("%+v\n", tenantConnection) - } - -Example to Get a Tenant Connection - - tenant_connection_id := "ea5d975c-bd31-11e7-bcac-0050569c850d" - - tenantConnection, err := tenant_connections.Get(tcClient, tenant_connection_id).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", tenantConnection) - -Example to Create a Tenant Connection - - createOpts := tenant_connections.CreateOpts{ - Name: "create_test_name", - Description: "create_test_desc", - Tags: map[string]string{ - "test_tags": "test", - }, - TenantConnectionRequestID: "21b344d8-be11-11e7-bf3c-0050569c850d", - DeviceType: "ECL::VirtualNetworkAppliance::VSRX", - DeviceID: "c291f4c4-a680-4db0-8b88-7e579f0aaa37", - DeviceInterfaceID: "interface_2", - AttachmentOpts: tenant_connections.Vna{ - FixedIPs: []tenant_connections.VnaFixedIPs{ - IPAddress: "192.168.1.3", - }, - }, - } - - result := tenant_connections.Create(tcClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Update a Tenant Connection - - tenant_connection_id := "ea5d975c-bd31-11e7-bcac-0050569c850d" - - updateOpts := tenant_connections.UpdateOpts{ - Name: "test_name", - Description: "test_desc", - Tags: map[string]string{ - "test_tags": "test", - }, - NameOther: "test_name_other", - DescriptionOther: "test_desc_other", - TagsOther: map[string]string{ - "test_tags_other": "test_other", - }, - } - - result := tenant_connections.Update(tcClient, tenant_connection_id, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a Tenant Connection - - tenant_connection_id := "ea5d975c-bd31-11e7-bcac-0050569c850d" - - result := tenant_connections.Delete(tcClient, tenant_connection_id) - if result.Err != nil { - panic(result.Err) - } - -*/ -package tenant_connections diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/requests.go b/v3/ecl/provider_connectivity/v2/tenant_connections/requests.go deleted file mode 100644 index 77a8be1..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/requests.go +++ /dev/null @@ -1,171 +0,0 @@ -package tenant_connections - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToTenantConnectionListQuery() (string, error) -} - -// ListOpts provides options to filter the List results. -type ListOpts struct { - TenantConnectionRequestID string `q:"tenant_connection_request_id"` - Status string `q:"status"` - Name string `q:"name"` - TenantID string `q:"tenant_id"` - NameOther string `q:"name_other"` - TenantIDOther string `q:"tenant_id_other"` - NetworkID string `q:"network_id"` - DeviceType string `q:"device_type"` - DeviceID string `q:"device_id"` - DeviceInterfaceID string `q:"device_interface_id"` - PortID string `q:"port_id"` -} - -// ToTenantConnectionListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToTenantConnectionListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), nil -} - -// List retrieves a list of Tenant Connection. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToTenantConnectionListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return TenantConnectionPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details of an Tenant Connection. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToTenantConnectionCreateMap() (map[string]interface{}, error) -} - -// ServerFixedIPs contains the IP Address and the SubnetID. -type ServerFixedIPs struct { - SubnetID string `json:"subnet_id,omitempty"` - IPAddress string `json:"ip_address,omitempty"` -} - -// AddressPair contains the IP Address and the MAC address. -type AddressPair struct { - IPAddress string `json:"ip_address,omitempty"` - MACAddress string `json:"mac_address,omitempty"` -} - -// VnaFixedIPs represents ip address part of virtual network appliance. -type VnaFixedIPs struct { - IPAddress string `json:"ip_address,omitempty"` -} - -// Vna represents the parameter when device_type is VSRX. -type Vna struct { - FixedIPs []VnaFixedIPs `json:"fixed_ips,omitempty"` -} - -// ComputeServer represents the parameter when device_type is Compute Server. -type ComputeServer struct { - AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"` - FixedIPs []ServerFixedIPs `json:"fixed_ips,omitempty"` -} - -// BaremetalServer represents the parameter when device_type is Baremetal Server. -type BaremetalServer struct { - AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"` - FixedIPs []ServerFixedIPs `json:"fixed_ips,omitempty"` - SegmentationID int `json:"segmentation_id,omitempty"` - SegmentationType string `json:"segmentation_type,omitempty"` -} - -// CreateOpts provides options used to create a Tenant Connection. -type CreateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - TenantConnectionRequestID string `json:"tenant_connection_request_id" required:"true"` - DeviceType string `json:"device_type" required:"true"` - DeviceID string `json:"device_id" required:"true"` - DeviceInterfaceID string `json:"device_interface_id,omitempty"` - AttachmentOpts interface{} `json:"attachment_opts,omitempty"` -} - -// ToTenantConnectionCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToTenantConnectionCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "tenant_connection") -} - -// Create creates a new Tenant Connection. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToTenantConnectionCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a Tenant Connection. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToTenantConnectionUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a Tenant Connection. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` - NameOther *string `json:"name_other,omitempty"` - DescriptionOther *string `json:"description_other,omitempty"` - TagsOther *map[string]string `json:"tags_other,omitempty"` -} - -// ToTenantConnectionUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToTenantConnectionUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "tenant_connection") -} - -// Update modifies the attributes of a Tenant Connection. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToTenantConnectionUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/results.go b/v3/ecl/provider_connectivity/v2/tenant_connections/results.go deleted file mode 100644 index 0492643..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/results.go +++ /dev/null @@ -1,87 +0,0 @@ -package tenant_connections - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// TenantConnection represents Tenant Connection. -// TagsOther is interface{} because the data type returned by Create API depends on the value of device_type. -// When the device_type of Create Request is ECL::Compute::Server, the data type of tags_other is map[]. -// When the device_type of Create Request is ECL::Baremetal::Server or ECL::VirtualNetworkAppliance::VSRX, the data type of tags_other is string. -type TenantConnection struct { - ID string `json:"id"` - TenantConnectionRequestID string `json:"tenant_connection_request_id"` - Name string `json:"name"` - Description string `json:"description"` - Tags map[string]string `json:"tags"` - TenantID string `json:"tenant_id"` - NameOther string `json:"name_other"` - DescriptionOther string `json:"description_other"` - TagsOther interface{} `json:"tags_other"` - TenantIDOther string `json:"tenant_id_other"` - NetworkID string `json:"network_id"` - DeviceType string `json:"device_type"` - DeviceID string `json:"device_id"` - DeviceInterfaceID string `json:"device_interface_id"` - PortID string `json:"port_id"` - Status string `json:"status"` -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a Tenant Connection. -type GetResult struct { - commonResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a Tenant Connection. -type CreateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a Tenant Connection. -type UpdateResult struct { - commonResult -} - -// TenantConnectionPage is a single page of Tenant Connection results. -type TenantConnectionPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Tenant Connection contains any results. -func (r TenantConnectionPage) IsEmpty() (bool, error) { - resources, err := ExtractTenantConnections(r) - return len(resources) == 0, err -} - -// ExtractTenantConnections returns a slice of Tenant Connections contained in a -// single page of results. -func ExtractTenantConnections(r pagination.Page) ([]TenantConnection, error) { - var s struct { - TenantConnection []TenantConnection `json:"tenant_connections"` - } - err := (r.(TenantConnectionPage)).ExtractInto(&s) - return s.TenantConnection, err -} - -// Extract interprets any commonResult as a Tenant Connection. -func (r commonResult) Extract() (*TenantConnection, error) { - var s struct { - TenantConnection *TenantConnection `json:"tenant_connection"` - } - err := r.ExtractInto(&s) - return s.TenantConnection, err -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/doc.go b/v3/ecl/provider_connectivity/v2/tenant_connections/testing/doc.go deleted file mode 100644 index fb04ea5..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Tenant Connection unit tests -package testing diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/fixtures.go b/v3/ecl/provider_connectivity/v2/tenant_connections/testing/fixtures.go deleted file mode 100644 index a729dbb..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/fixtures.go +++ /dev/null @@ -1,722 +0,0 @@ -package testing - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3/ecl/provider_connectivity/v2/tenant_connections" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" - "net/http" - "testing" -) - -// ListResult provides a single page of tenant_connection results. -const ListResult = ` -{ - "tenant_connections": [ - { - "id": "2a23e5a6-bd34-11e7-afb6-0050569c850d", - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tenant_connection_request_id": "5fbcc350-bd33-11e7-afb6-0050569c850d", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "device_type": "ECL::Compute::Server", - "device_id": "8c235a3b-8dee-41a1-b81a-64e06edc0986", - "device_interface_id": "", - "port_id": "b404ed73-9438-41a1-91ed-49d0e403be64", - "status": "creating", - "name": "test_name_1", - "description": "test_desc_1", - "tags": { - "test_tags1": "test1" - }, - "name_other": "", - "description_other": "", - "tags_other": {} - }, - { - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down", - "name": "test_name_2", - "description": "test_desc_2", - "tags": { - "test_tags2": "test2" - }, - "name_other": "test_name_other_2", - "description_other": "test_desc_other_2", - "tags_other": { - "test_tags_other2": "test2" - } - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "tenant_connection": { - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down", - "name": "test_name_2", - "description": "test_desc_2", - "tags": { - "test_tags2": "test2" - }, - "name_other": "test_name_other_2", - "description_other": "test_desc_other_2", - "tags_other": { - "test_tags_other2": "test2" - } - } -} -` - -// CreateAttachComputeServerRequest provides the input to a Create request. -const CreateAttachComputeServerRequest = ` -{ - "tenant_connection": { - "name": "test_name_1", - "description": "test_desc_1", - "tags": { - "test_tags1": "test1" - }, - "tenant_connection_request_id": "21b344d8-be11-11e7-bf3c-0050569c850d", - "device_type": "ECL::Compute::Server", - "device_id": "8c235a3b-8dee-41a1-b81a-64e06edc0986", - "attachment_opts": { - "fixed_ips": [ - { - "ip_address": "192.168.1.1", - "subnet_id": "1f424165-2202-4022-ad70-0fa6f9ec99e1" - } - ], - "allowed_address_pairs": [ - { - "ip_address": "192.168.1.2", - "mac_address": "11:22:33:aa:bb:cc" - } - ] - } - } -} -` - -// CreateAttachComputeServerResponse provides the output from a Create request. -const CreateAttachComputeServerResponse = ` -{ - "tenant_connection":{ - "id": "2a23e5a6-bd34-11e7-afb6-0050569c850d", - "tenant_connection_request_id": "5fbcc350-bd33-11e7-afb6-0050569c850d", - "name": "test_name_1", - "description": "test_desc_1", - "tags": { - "test_tags1": "test1" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tags_other": {}, - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "network_id": "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - "device_type": "ECL::Compute::Server", - "device_id": "8c235a3b-8dee-41a1-b81a-64e06edc0986", - "device_interface_id": "", - "port_id": "b404ed73-9438-41a1-91ed-49d0e403be64", - "status": "creating" - } -} -` - -// CreateAttachBaremetalServerRequest provides the input to a Create request. -const CreateAttachBaremetalServerRequest = ` -{ - "tenant_connection": { - "name": "attach_bare_name", - "description": "attach_bare_desc", - "tags": { - "test_tags1": "test1" - }, - "tenant_connection_request_id": "147c4ffa-481e-11ea-8088-525400060300", - "device_type": "ECL::Baremetal::Server", - "device_interface_id": "46eb7624-d462-46c2-8ac7-f988a15d3280", - "device_id": "0acab22f-8993-451c-8a6b-398b0244f578", - "attachment_opts": { - "segmentation_id": 10, - "segmentation_type": "flat", - "fixed_ips": [ - { - "ip_address": "192.168.1.1", - "subnet_id": "1f424165-2202-4022-ad70-0fa6f9ec99e1" - } - ], - "allowed_address_pairs": [ - { - "ip_address": "192.168.1.2", - "mac_address": "11:22:33:aa:bb:cc" - } - ] - } - } -} -` - -// CreateAttachBaremetalServerResponse provides the output from a Create request. -const CreateAttachBaremetalServerResponse = ` -{ - "tenant_connection":{ - "id": "0d956a2e-4958-11ea-8088-525400060300", - "tenant_connection_request_id": "147c4ffa-481e-11ea-8088-525400060300", - "name": "attach_bare_name", - "description": "attach_bare_desc", - "tags": { - "test_tags1": "test1" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tags_other": "{}", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "network_id": "061dbaa9-a3e0-4343-b3fc-0a619db66854", - "device_type": "ECL::Baremetal::Server", - "device_id": "0acab22f-8993-451c-8a6b-398b0244f578", - "device_interface_id": "46eb7624-d462-46c2-8ac7-f988a15d3280", - "port_id": "87449d66-4e99-4cf7-9b93-9f153548ccc7", - "status": "creating" - } -} -` - -// CreateAttachVnaRequest provides the input to a Create request. -const CreateAttachVnaRequest = ` -{ - "tenant_connection": { - "name": "attach_vna_name", - "description": "attach_vna_desc", - "tags": { - "test_tags1": "test1" - }, - "tenant_connection_request_id": "67d76b00-3804-11ea-8088-525400060300", - "device_type": "ECL::VirtualNetworkAppliance::VSRX", - "device_interface_id": "interface_2", - "device_id": "c291f4c4-a680-4db0-8b88-7e579f0aaa37", - "attachment_opts": { - "fixed_ips": [ - { - "ip_address": "192.168.1.3" - } - ] - } - } -} -` - -// CreateAttachVnaResponse provides the output from a Create request. -const CreateAttachVnaResponse = ` -{ - "tenant_connection":{ - "id": "f6331886-3804-11ea-95a8-525400060400", - "tenant_connection_request_id": "67d76b00-3804-11ea-8088-525400060300", - "name": "attach_vna_name", - "description": "attach_vna_desc", - "tags": { - "test_tags1": "test1" - }, - "tenant_id": "7e91b19b9baa423793ee74a8e1ff2be1", - "name_other": "", - "description_other": "", - "tags_other": "{}", - "tenant_id_other": "c7f3a68a73e845d4ba6a42fb80fce03f", - "network_id": "061dbaa9-a3e0-4343-b3fc-0a619db66854", - "device_interface_id": "interface_2", - "device_type": "ECL::VirtualNetworkAppliance::VSRX", - "device_id": "c291f4c4-a680-4db0-8b88-7e579f0aaa37", - "port_id": "", - "status": "active" - } -} -` - -// UpdateRequest provides the input to as Update request. -const UpdateRequest = ` -{ - "tenant_connection": { - "name": "update_name", - "description": "update_desc", - "tags": { - "update_tags": "update" - } - } -} -` - -// UpdateResult provides an update result. -const UpdateResult = ` -{ - "tenant_connection":{ - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "name": "update_name", - "description": "update_desc", - "tags": { - "update_tags": "update" - }, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "test_name_other_2", - "description_other": "test_desc_other_2", - "tags_other": { - "test_tags_other2": "test2" - }, - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down" - } -} -` - -// UpdateOtherMetadataRequest provides the input to as Update to other metadata request. -const UpdateOtherMetadataRequest = ` -{ - "tenant_connection": { - "name_other": "update_name_other", - "description_other": "update_desc_other", - "tags_other": { - "test_tags_other": "update" - } - } -} -` - -// UpdateOtherMetadataResult provides an update to other metadata result. -const UpdateOtherMetadataResult = ` -{ - "tenant_connection":{ - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "name": "test_name_2", - "description": "test_desc_2", - "tags": { - "test_tags2": "test2" - }, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "update_name_other", - "description_other": "update_desc_other", - "tags_other": { - "test_tags_other": "update" - }, - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down" - } -} -` - -// UpdateBlankRequest provides the input to as Update with blank request. -const UpdateBlankRequest = ` -{ - "tenant_connection": { - "name": "", - "description": "", - "tags": {} - } -} -` - -// UpdateBlankResult provides an update with blank result. -const UpdateBlankResult = ` -{ - "tenant_connection":{ - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "name": "", - "description": "", - "tags": {}, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "test_name_other_2", - "description_other": "test_desc_other_2", - "tags_other": {"test_tags_other2": "test2"}, - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down" - } -} -` - -// UpdateNilRequest provides the input to as Update with nil request. -const UpdateNilRequest = ` -{ - "tenant_connection": { - "name": "nilupdate" - } -} -` - -// UpdateNilResult provides an update with blank with nil result. -const UpdateNilResult = ` -{ - "tenant_connection":{ - "id": "ea5d975c-bd31-11e7-bcac-0050569c850d", - "tenant_connection_request_id": "90381138-b572-11e7-9391-0050569c850d", - "name": "nilupdate", - "description": "test_desc_2", - "tags": { - "test_tags2": "test2" - }, - "tenant_id": "c7f3a68a73e845d4ba6a42fb80fce03f", - "name_other": "test_name_other_2", - "description_other": "test_desc_other_2", - "tags_other": { - "test_tags_other2": "test2" - }, - "tenant_id_other": "7e91b19b9baa423793ee74a8e1ff2be1", - "network_id": "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - "device_type": "ECL::Compute::Server", - "device_id": "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - "device_interface_id": "", - "port_id": "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - "status": "down" - } -} -` - -// FirstTenantConnection is the first tenant_connection in the List request. -var FirstTenantConnection = tenant_connections.TenantConnection{ - ID: "2a23e5a6-bd34-11e7-afb6-0050569c850d", - TenantConnectionRequestID: "5fbcc350-bd33-11e7-afb6-0050569c850d", - Name: "test_name_1", - Description: "test_desc_1", - Tags: map[string]string{ - "test_tags1": "test1", - }, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: map[string]string{}, - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "77cfc6b0-d032-4e5a-b6fb-4cce2537f4d1", - DeviceType: "ECL::Compute::Server", - DeviceID: "8c235a3b-8dee-41a1-b81a-64e06edc0986", - DeviceInterfaceID: "", - PortID: "b404ed73-9438-41a1-91ed-49d0e403be64", - Status: "creating", -} - -// SecondTenantConnection is the second tenant_connection in the List request. -var SecondTenantConnection = tenant_connections.TenantConnection{ - ID: "ea5d975c-bd31-11e7-bcac-0050569c850d", - TenantConnectionRequestID: "90381138-b572-11e7-9391-0050569c850d", - Name: "test_name_2", - Description: "test_desc_2", - Tags: map[string]string{ - "test_tags2": "test2", - }, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "test_name_other_2", - DescriptionOther: "test_desc_other_2", - TagsOther: map[string]string{ - "test_tags_other2": "test2", - }, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - DeviceType: "ECL::Compute::Server", - DeviceID: "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - DeviceInterfaceID: "", - PortID: "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - Status: "down", -} - -// CreateTenantConnectionAttachBaremetalServer is the tenant_connection in the Create Attach Baremetal Server request. -var CreateTenantConnectionAttachBaremetalServer = tenant_connections.TenantConnection{ - ID: "0d956a2e-4958-11ea-8088-525400060300", - TenantConnectionRequestID: "147c4ffa-481e-11ea-8088-525400060300", - Name: "attach_bare_name", - Description: "attach_bare_desc", - Tags: map[string]string{ - "test_tags1": "test1", - }, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: "{}", - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "061dbaa9-a3e0-4343-b3fc-0a619db66854", - DeviceType: "ECL::Baremetal::Server", - DeviceID: "0acab22f-8993-451c-8a6b-398b0244f578", - DeviceInterfaceID: "46eb7624-d462-46c2-8ac7-f988a15d3280", - PortID: "87449d66-4e99-4cf7-9b93-9f153548ccc7", - Status: "creating", -} - -// CreateTenantConnectionAttachVna is the tenant_connection in the Create Attach Vna request. -var CreateTenantConnectionAttachVna = tenant_connections.TenantConnection{ - ID: "f6331886-3804-11ea-95a8-525400060400", - TenantConnectionRequestID: "67d76b00-3804-11ea-8088-525400060300", - Name: "attach_vna_name", - Description: "attach_vna_desc", - Tags: map[string]string{ - "test_tags1": "test1", - }, - TenantID: "7e91b19b9baa423793ee74a8e1ff2be1", - NameOther: "", - DescriptionOther: "", - TagsOther: "{}", - TenantIDOther: "c7f3a68a73e845d4ba6a42fb80fce03f", - NetworkID: "061dbaa9-a3e0-4343-b3fc-0a619db66854", - DeviceType: "ECL::VirtualNetworkAppliance::VSRX", - DeviceID: "c291f4c4-a680-4db0-8b88-7e579f0aaa37", - DeviceInterfaceID: "interface_2", - PortID: "", - Status: "active", -} - -// SecondTenantConnectionUpdated is how second tenant_connection should look after an Update. -var SecondTenantConnectionUpdated = tenant_connections.TenantConnection{ - ID: "ea5d975c-bd31-11e7-bcac-0050569c850d", - TenantConnectionRequestID: "90381138-b572-11e7-9391-0050569c850d", - Name: "update_name", - Description: "update_desc", - Tags: map[string]string{ - "update_tags": "update", - }, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "test_name_other_2", - DescriptionOther: "test_desc_other_2", - TagsOther: map[string]string{ - "test_tags_other2": "test2", - }, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - DeviceType: "ECL::Compute::Server", - DeviceID: "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - DeviceInterfaceID: "", - PortID: "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - Status: "down", -} - -// SecondTenantConnectionOtherMetadataUpdated is how second tenant_connection should look after an Update to other metadata. -var SecondTenantConnectionOtherMetadataUpdated = tenant_connections.TenantConnection{ - ID: "ea5d975c-bd31-11e7-bcac-0050569c850d", - TenantConnectionRequestID: "90381138-b572-11e7-9391-0050569c850d", - Name: "test_name_2", - Description: "test_desc_2", - Tags: map[string]string{ - "test_tags2": "test2", - }, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "update_name_other", - DescriptionOther: "update_desc_other", - TagsOther: map[string]string{ - "test_tags_other": "update", - }, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - DeviceType: "ECL::Compute::Server", - DeviceID: "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - DeviceInterfaceID: "", - PortID: "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - Status: "down", -} - -// SecondTenantConnectionBlankUpdated is how second tenant_connection should look after an Update with blank. -var SecondTenantConnectionBlankUpdated = tenant_connections.TenantConnection{ - ID: "ea5d975c-bd31-11e7-bcac-0050569c850d", - TenantConnectionRequestID: "90381138-b572-11e7-9391-0050569c850d", - Name: "", - Description: "", - Tags: map[string]string{}, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "test_name_other_2", - DescriptionOther: "test_desc_other_2", - TagsOther: map[string]string{"test_tags_other2": "test2"}, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - DeviceType: "ECL::Compute::Server", - DeviceID: "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - DeviceInterfaceID: "", - PortID: "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - Status: "down", -} - -// SecondTenantConnectionNilUpdated is how second tenant_connection should look after an Update with nil. -var SecondTenantConnectionNilUpdated = tenant_connections.TenantConnection{ - ID: "ea5d975c-bd31-11e7-bcac-0050569c850d", - TenantConnectionRequestID: "90381138-b572-11e7-9391-0050569c850d", - Name: "nilupdate", - Description: "test_desc_2", - Tags: map[string]string{ - "test_tags2": "test2", - }, - TenantID: "c7f3a68a73e845d4ba6a42fb80fce03f", - NameOther: "test_name_other_2", - DescriptionOther: "test_desc_other_2", - TagsOther: map[string]string{ - "test_tags_other2": "test2", - }, - TenantIDOther: "7e91b19b9baa423793ee74a8e1ff2be1", - NetworkID: "c4d5fc41-b7e8-4f19-96f4-85299e54373c", - DeviceType: "ECL::Compute::Server", - DeviceID: "7cc34d4b-a345-4e51-b3d9-62540faca7bf", - DeviceInterfaceID: "", - PortID: "c9c3de44-0720-4acd-87c1-9c76f0f77cac", - Status: "down", -} - -// ExpectedTenantConnectionsSlice is the slice of tenant_connection expected to be returned from ListResult. -var ExpectedTenantConnectionsSlice = []tenant_connections.TenantConnection{FirstTenantConnection, SecondTenantConnection} - -// HandleListTenantConnectionsSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that responds with a list of two tenant_connections. -func HandleListTenantConnectionsSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connections", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, ListResult) - }) -} - -// HandleGetTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that responds with a single tenant_connection. -func HandleGetTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", SecondTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, GetResult) - }) -} - -// HandleCreateTenantConnectionAttachComputeServerSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests creation of tenant_connection with Compute Server attached. -func HandleCreateTenantConnectionAttachComputeServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connections", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateAttachComputeServerRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, CreateAttachComputeServerResponse) - }) -} - -// HandleCreateTenantConnectionAttachBaremetalServerSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests creation of tenant_connection with Baremetal Server attached. -func HandleCreateTenantConnectionAttachBaremetalServerSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connections", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateAttachBaremetalServerRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, CreateAttachBaremetalServerResponse) - }) -} - -// HandleCreateTenantConnectionAttachVnaSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that that tests creation of tenant_connection with Vna attached. -func HandleCreateTenantConnectionAttachVnaSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/tenant_connections", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateAttachVnaRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, CreateAttachVnaResponse) - }) -} - -// HandleDeleteTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests tenant_connection deletion. -func HandleDeleteTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", FirstTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) -} - -// HandleUpdateTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests tenant_connection update. -func HandleUpdateTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", SecondTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateResult) - }) -} - -// HandleUpdateOtherMetadataTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests tenant_connection update to other metadata. -func HandleUpdateOtherMetadataTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", SecondTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateOtherMetadataRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateOtherMetadataResult) - }) -} - -// HandleBlankUpdateTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests tenant_connection update with blank. -func HandleBlankUpdateTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", SecondTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateBlankRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateBlankResult) - }) -} - -// HandleNilUpdateTenantConnectionSuccessfully creates an HTTP handler at `/tenant_connections` on the -// test handler mux that tests tenant_connection update with nil. -func HandleNilUpdateTenantConnectionSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/tenant_connections/%s", SecondTenantConnection.ID), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateNilRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, UpdateNilResult) - }) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/requests_test.go b/v3/ecl/provider_connectivity/v2/tenant_connections/testing/requests_test.go deleted file mode 100644 index fae6c5a..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/testing/requests_test.go +++ /dev/null @@ -1,234 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/provider_connectivity/v2/tenant_connections" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListTenantConnections(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantConnectionsSuccessfully(t) - - count := 0 - err := tenant_connections.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := tenant_connections.ExtractTenantConnections(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedTenantConnectionsSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListTenantConnectionsAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListTenantConnectionsSuccessfully(t) - - allPages, err := tenant_connections.List(client.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - actual, err := tenant_connections.ExtractTenantConnections(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedTenantConnectionsSlice, actual) -} - -func TestGetTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetTenantConnectionSuccessfully(t) - - actual, err := tenant_connections.Get(client.ServiceClient(), SecondTenantConnection.ID).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnection, *actual) -} - -func TestCreateTenantConnectionAttachComputeServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTenantConnectionAttachComputeServerSuccessfully(t) - - createOpts := tenant_connections.CreateOpts{ - Name: "test_name_1", - Description: "test_desc_1", - Tags: map[string]string{"test_tags1": "test1"}, - TenantConnectionRequestID: "21b344d8-be11-11e7-bf3c-0050569c850d", - DeviceType: "ECL::Compute::Server", - DeviceID: "8c235a3b-8dee-41a1-b81a-64e06edc0986", - DeviceInterfaceID: "", - AttachmentOpts: tenant_connections.ComputeServer{ - AllowedAddressPairs: []tenant_connections.AddressPair{ - { - IPAddress: "192.168.1.2", - MACAddress: "11:22:33:aa:bb:cc", - }, - }, - FixedIPs: []tenant_connections.ServerFixedIPs{ - { - SubnetID: "1f424165-2202-4022-ad70-0fa6f9ec99e1", - IPAddress: "192.168.1.1", - }, - }, - }, - } - - actual, err := tenant_connections.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &FirstTenantConnection, actual) -} - -func TestCreateTenantConnectionAttachBaremetalServer(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTenantConnectionAttachBaremetalServerSuccessfully(t) - - createOpts := tenant_connections.CreateOpts{ - Name: "attach_bare_name", - Description: "attach_bare_desc", - Tags: map[string]string{"test_tags1": "test1"}, - TenantConnectionRequestID: "147c4ffa-481e-11ea-8088-525400060300", - DeviceType: "ECL::Baremetal::Server", - DeviceID: "0acab22f-8993-451c-8a6b-398b0244f578", - DeviceInterfaceID: "46eb7624-d462-46c2-8ac7-f988a15d3280", - AttachmentOpts: tenant_connections.BaremetalServer{ - AllowedAddressPairs: []tenant_connections.AddressPair{ - { - IPAddress: "192.168.1.2", - MACAddress: "11:22:33:aa:bb:cc", - }, - }, - FixedIPs: []tenant_connections.ServerFixedIPs{ - { - SubnetID: "1f424165-2202-4022-ad70-0fa6f9ec99e1", - IPAddress: "192.168.1.1", - }, - }, - SegmentationID: 10, - SegmentationType: "flat", - }, - } - - actual, err := tenant_connections.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &CreateTenantConnectionAttachBaremetalServer, actual) -} - -func TestCreateTenantConnectionAttachVna(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateTenantConnectionAttachVnaSuccessfully(t) - - createOpts := tenant_connections.CreateOpts{ - Name: "attach_vna_name", - Description: "attach_vna_desc", - Tags: map[string]string{"test_tags1": "test1"}, - TenantConnectionRequestID: "67d76b00-3804-11ea-8088-525400060300", - DeviceType: "ECL::VirtualNetworkAppliance::VSRX", - DeviceID: "c291f4c4-a680-4db0-8b88-7e579f0aaa37", - DeviceInterfaceID: "interface_2", - AttachmentOpts: tenant_connections.Vna{ - FixedIPs: []tenant_connections.VnaFixedIPs{ - { - IPAddress: "192.168.1.3", - }, - }, - }, - } - - actual, err := tenant_connections.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, &CreateTenantConnectionAttachVna, actual) -} - -func TestDeleteTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteTenantConnectionSuccessfully(t) - - res := tenant_connections.Delete(client.ServiceClient(), FirstTenantConnection.ID) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateTenantConnectionSuccessfully(t) - - name := "update_name" - description := "update_desc" - tags := map[string]string{"update_tags": "update"} - - updateOpts := tenant_connections.UpdateOpts{ - Name: &name, - Description: &description, - Tags: &tags, - } - - actual, err := tenant_connections.Update(client.ServiceClient(), SecondTenantConnection.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionUpdated, *actual) -} - -func TestUpdateOtherMetadataTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateOtherMetadataTenantConnectionSuccessfully(t) - - nameOther := "update_name_other" - descriptionOther := "update_desc_other" - tagsOther := map[string]string{"test_tags_other": "update"} - - updateOpts := tenant_connections.UpdateOpts{ - NameOther: &nameOther, - DescriptionOther: &descriptionOther, - TagsOther: &tagsOther, - } - - actual, err := tenant_connections.Update(client.ServiceClient(), SecondTenantConnection.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionOtherMetadataUpdated, *actual) -} - -func TestBlankUpdateTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleBlankUpdateTenantConnectionSuccessfully(t) - - name := "" - description := "" - tags := map[string]string{} - - updateOpts := tenant_connections.UpdateOpts{ - Name: &name, - Description: &description, - Tags: &tags, - } - - actual, err := tenant_connections.Update(client.ServiceClient(), SecondTenantConnection.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionBlankUpdated, *actual) -} - -func TestNilUpdateTenantConnection(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleNilUpdateTenantConnectionSuccessfully(t) - - name := "nilupdate" - - updateOpts := tenant_connections.UpdateOpts{ - Name: &name, - } - - actual, err := tenant_connections.Update(client.ServiceClient(), SecondTenantConnection.ID, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondTenantConnectionNilUpdated, *actual) -} diff --git a/v3/ecl/provider_connectivity/v2/tenant_connections/urls.go b/v3/ecl/provider_connectivity/v2/tenant_connections/urls.go deleted file mode 100644 index 1d6c10a..0000000 --- a/v3/ecl/provider_connectivity/v2/tenant_connections/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package tenant_connections - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenant_connections") -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connections", id) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenant_connections") -} - -func deleteURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connections", id) -} - -func updateURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("tenant_connections", id) -} diff --git a/v3/ecl/rca/v1/users/doc.go b/v3/ecl/rca/v1/users/doc.go deleted file mode 100644 index 97ce3dd..0000000 --- a/v3/ecl/rca/v1/users/doc.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Package users manages and retrieves users in the Enterprise Cloud Remote Console Access Service. - -Example to List users - - allPages, err := users.List(rcaClient).AllPages() - if err != nil { - panic(err) - } - - allUsers, err := users.ExtractUsers(allPages) - if err != nil { - panic(err) - } - - for _, user := range allUsers { - fmt.Printf("%+v\n", user) - } - -Example to Get a user - - username := "02471b45-3de0-4fc8-8469-a7cc52c378df" - - user, err := users.Get(rcaClient, username).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", user) - -Example to Create a user - - createOpts := users.CreateOpts{ - Password: "dummy_passw@rd", - } - - result := users.Create(rcaClient, createOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Update a user - - username := "02471b45-3de0-4fc8-8469-a7cc52c378df" - updateOpts := users.UpdateOpts{ - Password: "dummy_passw@rd", - } - - result := users.Update(rcaClient, username, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a user - - username := "02471b45-3de0-4fc8-8469-a7cc52c378df" - - result := users.Delete(rcaClient, username) - if result.Err != nil { - panic(result.Err) - } - -*/ -package users diff --git a/v3/ecl/rca/v1/users/requests.go b/v3/ecl/rca/v1/users/requests.go deleted file mode 100644 index 471ace0..0000000 --- a/v3/ecl/rca/v1/users/requests.go +++ /dev/null @@ -1,86 +0,0 @@ -package users - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// List retrieves a list of users. -func List(client *eclcloud.ServiceClient) pagination.Pager { - url := listURL(client) - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return UserPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details of a user. -func Get(client *eclcloud.ServiceClient, name string) (r GetResult) { - _, r.Err = client.Get(getURL(client, name), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToResourceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts provides options used to create a user. -type CreateOpts struct { - Password string `json:"password"` -} - -// ToResourceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToResourceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "user") -} - -// Create creates a new user. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToResourceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete deletes a user. -func Delete(client *eclcloud.ServiceClient, name string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, name), &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToResourceUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a user. -type UpdateOpts struct { - Password string `json:"password"` -} - -// ToResourceUpdateCreateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToResourceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "user") -} - -// Update modifies the attributes of a user. -func Update(client *eclcloud.ServiceClient, name string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToResourceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, name), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/rca/v1/users/results.go b/v3/ecl/rca/v1/users/results.go deleted file mode 100644 index a4067c6..0000000 --- a/v3/ecl/rca/v1/users/results.go +++ /dev/null @@ -1,77 +0,0 @@ -package users - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// User represents VPN user. -type User struct { - Name string `json:"name"` - Password string `json:"password"` - VPNEndpoints []VPNEndpoint `json:"vpn_endpoints"` -} - -// VPNEndpoint represents VPN Endpoint. -type VPNEndpoint struct { - Endpoint string `json:"endpoint"` - Type string `json:"type"` -} - -type commonResult struct { - eclcloud.Result -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as a user. -type GetResult struct { - commonResult -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a user. -type CreateResult struct { - commonResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a user. -type UpdateResult struct { - commonResult -} - -// UserPage is a single page of user results. -type UserPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of users contains any results. -func (r UserPage) IsEmpty() (bool, error) { - resources, err := ExtractUsers(r) - return len(resources) == 0, err -} - -// ExtractUsers returns a slice of users contained in a single page of -// results. -func ExtractUsers(r pagination.Page) ([]User, error) { - var s struct { - Users []User `json:"users"` - } - err := (r.(UserPage)).ExtractInto(&s) - return s.Users, err -} - -// Extract interprets any commonResult as a user. -func (r commonResult) Extract() (*User, error) { - var s struct { - User *User `json:"user"` - } - err := r.ExtractInto(&s) - return s.User, err -} diff --git a/v3/ecl/rca/v1/users/testing/fixtures.go b/v3/ecl/rca/v1/users/testing/fixtures.go deleted file mode 100644 index b530ef5..0000000 --- a/v3/ecl/rca/v1/users/testing/fixtures.go +++ /dev/null @@ -1,196 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/rca/v1/users" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -var ( - password = "dummy_passw@rd" - passwordUpdated = "dummy_passw@rd_updated" -) - -// ListResult provides a single page of user results. -const ListResult = ` -{ - "users": [ - { - "name": "ef5778e553a24d789c15c689e30adf5d", - "vpn_endpoints": [ - { - "endpoint": "https://rca-sslvpn1-jp1.ecl.ntt.com", - "type": "SSL-VPN" - } - ] - }, - { - "name": "8bbe05d4bec747189e0dab81e486969f-1005", - "vpn_endpoints": [ - { - "endpoint": "https://rca-sslvpn1-jp1.ecl.ntt.com", - "type": "SSL-VPN" - } - ] - } - ] -} -` - -// GetResult provides a Get result. -const GetResult = ` -{ - "user": { - "name": "8bbe05d4bec747189e0dab81e486969f-1005", - "vpn_endpoints": [ - { - "endpoint": "https://rca-sslvpn1-jp1.ecl.ntt.com", - "type": "SSL-VPN" - } - ] - } -} -` - -// CreateRequest provides the input to a Create request. -const CreateRequest = ` -{ - "user": { - "password": "dummy_passw@rd" - } -} -` - -// CreateResponse provides the output from a Create request. -const CreateResponse = ` -{ - "user": { - "name": "8bbe05d4bec747189e0dab81e486969f-1005", - "password": "dummy_passw@rd", - "vpn_endpoints": [ - { - "endpoint": "https://rca-sslvpn1-jp1.ecl.ntt.com", - "type": "SSL-VPN" - } - ] - } -} -` - -// UpdateRequest provides the input to as Update request. -const UpdateRequest = ` -{ - "user": { - "password": "dummy_passw@rd_updated" - } -} -` - -// UpdateResult provides an update result. -const UpdateResult = GetResult - -// FirstUser is the first user in the List request. -var FirstUser = users.User{ - Name: "ef5778e553a24d789c15c689e30adf5d", - VPNEndpoints: []users.VPNEndpoint{ - { - Endpoint: "https://rca-sslvpn1-jp1.ecl.ntt.com", - Type: "SSL-VPN", - }, - }, -} - -// SecondUser is the second user in the List request. -var SecondUser = users.User{ - Name: "8bbe05d4bec747189e0dab81e486969f-1005", - VPNEndpoints: []users.VPNEndpoint{ - { - Endpoint: "https://rca-sslvpn1-jp1.ecl.ntt.com", - Type: "SSL-VPN", - }, - }, -} - -// SecondUserUpdated is how SecondUser should look after an Update. -var SecondUserUpdated = users.User{ - Name: "8bbe05d4bec747189e0dab81e486969f-1005", - VPNEndpoints: []users.VPNEndpoint{ - { - Endpoint: "https://rca-sslvpn1-jp1.ecl.ntt.com", - Type: "SSL-VPN", - }, - }, -} - -// ExpectedUsersSlice is the slice of users expected to be returned from ListResult. -var ExpectedUsersSlice = []users.User{FirstUser, SecondUser} - -// HandleListUsersSuccessfully creates an HTTP handler at `/users` on the -// test handler mux that responds with a list of two users. -func HandleListUsersSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ListResult) - }) -} - -// HandleGetUserSuccessfully creates an HTTP handler at `/users` on the -// test handler mux that responds with a single user. -func HandleGetUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/users/%s", SecondUser.Name), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "Accept", "application/json") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, GetResult) - }) -} - -// HandleCreateUserSuccessfully creates an HTTP handler at `/users` on the -// test handler mux that tests user creation. -func HandleCreateUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, CreateResponse) - }) -} - -// HandleDeleteUserSuccessfully creates an HTTP handler at `/users` on the -// test handler mux that tests user deletion. -func HandleDeleteUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/users/%s", FirstUser.Name), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - w.WriteHeader(http.StatusOK) - }) -} - -// HandleUpdateUserSuccessfully creates an HTTP handler at `/users` on the -// test handler mux that tests user update. -func HandleUpdateUserSuccessfully(t *testing.T) { - th.Mux.HandleFunc(fmt.Sprintf("/users/%s", SecondUser.Name), func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - th.TestJSONRequest(t, r, UpdateRequest) - - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, UpdateResult) - }) -} diff --git a/v3/ecl/rca/v1/users/testing/requests_test.go b/v3/ecl/rca/v1/users/testing/requests_test.go deleted file mode 100644 index 686cf50..0000000 --- a/v3/ecl/rca/v1/users/testing/requests_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/rca/v1/users" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListUsers(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsersSuccessfully(t) - - count := 0 - err := users.List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { - count++ - - actual, err := users.ExtractUsers(page) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, ExpectedUsersSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.AssertEquals(t, count, 1) -} - -func TestListUsersAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleListUsersSuccessfully(t) - - allPages, err := users.List(client.ServiceClient()).AllPages() - th.AssertNoErr(t, err) - actual, err := users.ExtractUsers(allPages) - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, ExpectedUsersSlice, actual) -} - -func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleGetUserSuccessfully(t) - - actual, err := users.Get(client.ServiceClient(), SecondUser.Name).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondUser, *actual) -} - -func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleCreateUserSuccessfully(t) - - createOpts := users.CreateOpts{ - Password: password, - } - - actual, err := users.Create(client.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.AssertEquals(t, SecondUser.Name, actual.Name) - th.AssertEquals(t, password, actual.Password) - th.AssertDeepEquals(t, SecondUser.VPNEndpoints, actual.VPNEndpoints) -} - -func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleDeleteUserSuccessfully(t) - - res := users.Delete(client.ServiceClient(), FirstUser.Name) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - HandleUpdateUserSuccessfully(t) - - updateOpts := users.UpdateOpts{ - Password: passwordUpdated, - } - - actual, err := users.Update(client.ServiceClient(), SecondUser.Name, updateOpts).Extract() - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, SecondUserUpdated, *actual) -} diff --git a/v3/ecl/rca/v1/users/urls.go b/v3/ecl/rca/v1/users/urls.go deleted file mode 100644 index 8335c66..0000000 --- a/v3/ecl/rca/v1/users/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package users - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func getURL(client *eclcloud.ServiceClient, name string) string { - return client.ServiceURL("users", name) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func deleteURL(client *eclcloud.ServiceClient, name string) string { - return client.ServiceURL("users", name) -} - -func updateURL(client *eclcloud.ServiceClient, name string) string { - return client.ServiceURL("users", name) -} diff --git a/v3/ecl/security_order/v2/host_based/doc.go b/v3/ecl/security_order/v2/host_based/doc.go deleted file mode 100644 index 75eaef7..0000000 --- a/v3/ecl/security_order/v2/host_based/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package host_based contains Host Based Security functionality. -package host_based diff --git a/v3/ecl/security_order/v2/host_based/requests.go b/v3/ecl/security_order/v2/host_based/requests.go deleted file mode 100644 index 4ddc9b1..0000000 --- a/v3/ecl/security_order/v2/host_based/requests.go +++ /dev/null @@ -1,139 +0,0 @@ -package host_based - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// GetOptsBuilder allows extensions to add additional parameters to -// the order progress API request -type GetOptsBuilder interface { - ToServiceOrderQuery() (string, error) -} - -// GetOpts represents result of host based security API response. -type GetOpts struct { - TenantID string `q:"tenant_id"` -} - -// ToServiceOrderQuery formats a GetOpts into a query string. -func (opts GetOpts) ToServiceOrderQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Get retrieves details of an order progress, by SoId. -func Get(client *eclcloud.ServiceClient, opts GetOptsBuilder) (r GetResult) { - url := getURL(client) - if opts != nil { - query, _ := opts.ToServiceOrderQuery() - url += query - } - - _, r.Err = client.Get(url, &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToHostBasedCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a Host based security. -type CreateOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - Locale string `json:"locale,omitempty"` - ServiceOrderService string `json:"service_order_service" required:"true"` - MaxAgentValue int `json:"max_agent_value" required:"true"` - MailAddress string `json:"mailaddress" required:"true"` - DSMLang string `json:"dsm_lang" required:"true"` - TimeZone string `json:"time_zone" required:"true"` -} - -// ToHostBasedCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToHostBasedCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new Host based security. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToHostBasedCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// DeleteOptsBuilder allows extensions to add additional parameters to -// the Delete request. -type DeleteOptsBuilder interface { - ToHostBasedDeleteMap() (map[string]interface{}, error) -} - -// DeleteOpts represents parameters used to cancel Host Based Security. -type DeleteOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - Locale string `json:"locale,omitempty"` - MailAddress string `json:"mailaddress" required:"true"` -} - -// ToHostBasedDeleteMap formats a DeleteOpts into a delete request. -func (opts DeleteOpts) ToHostBasedDeleteMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Delete deletes a device. -func Delete(client *eclcloud.ServiceClient, opts DeleteOptsBuilder) (r DeleteResult) { - b, err := opts.ToHostBasedDeleteMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return - -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToHostBasedUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a Host Based Security. -type UpdateOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - Locale string `json:"locale,omitempty"` - MailAddress string `json:"mailaddress" required:"true"` - // Set this in case of Type M1 Change - ServiceOrderService *string `json:"service_order_service,omitempty"` - // Set this in case of Type M2 Change - MaxAgentValue *int `json:"max_agent_value,omitempty"` -} - -// ToHostBasedUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToHostBasedUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of a Host Based Security. -func Update(client *eclcloud.ServiceClient, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToHostBasedUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(updateURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/security_order/v2/host_based/results.go b/v3/ecl/security_order/v2/host_based/results.go deleted file mode 100644 index 7943dd7..0000000 --- a/v3/ecl/security_order/v2/host_based/results.go +++ /dev/null @@ -1,85 +0,0 @@ -package host_based - -import ( - "github.com/nttcom/eclcloud/v3" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a Host Based Security resource. -func (r commonResult) Extract() (*HostBasedOrder, error) { - var hbo HostBasedOrder - err := r.ExtractInto(&hbo) - return &hbo, err -} - -// Extract interprets any commonResult as a Host Based Security if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Host Based Security. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Host Based Security. -type GetResult struct { - commonResult -} - -// HostBasedSecurity represents a Host Based Security's each order. -type HostBasedSecurity struct { - Code string `json:"code"` - Message string `json:"message"` - Region string `json:"region"` - TenantName string `json:"tenant_name"` - TenantDescription string `json:"tenant_description"` - ContractID string `json:"contract_id"` - ServiceOrderService string `json:"service_order_service"` - MaxAgentValue interface{} `json:"max_agent_value"` - TimeZone string `json:"time_zone"` - CustomerName string `json:"customer_name"` - MailAddress string `json:"mailaddress"` - DSMLang string `json:"dsm_lang"` - TenantFlg bool `json:"tenant_flg"` - Status int `json:"status"` -} - -// Extract is a function that accepts a result -// and extracts a Host Based Security resource. -func (r GetResult) Extract() (*HostBasedSecurity, error) { - var h HostBasedSecurity - err := r.ExtractInto(&h) - return &h, err -} - -// ExtractInto interprets any commonResult as a Host Based Security if possible. -func (r GetResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Host Based Security. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - commonResult -} - -// HostBasedOrder represents a Host Based Security's each order. -type HostBasedOrder struct { - ID string `json:"soId"` - Code string `json:"code"` - Message string `json:"message"` - Status int `json:"status"` -} diff --git a/v3/ecl/security_order/v2/host_based/testing/doc.go b/v3/ecl/security_order/v2/host_based/testing/doc.go deleted file mode 100644 index 085b2c7..0000000 --- a/v3/ecl/security_order/v2/host_based/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains host based security unittests -package testing diff --git a/v3/ecl/security_order/v2/host_based/testing/fixtures.go b/v3/ecl/security_order/v2/host_based/testing/fixtures.go deleted file mode 100644 index 273df35..0000000 --- a/v3/ecl/security_order/v2/host_based/testing/fixtures.go +++ /dev/null @@ -1,139 +0,0 @@ -package testing - -import ( - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/host_based" -) - -const getResponse = ` -{ - "code": "DEP-01", - "message": "Successful completion", - "region": "jp4", - "tenant_name": "Test Tenant", - "tenant_description": "Test Tenant", - "contract_id": "econ9999999999", - "service_order_service": "Managed Anti-Virus", - "max_agent_value": 1, - "customer_name": "Customer", - "time_zone": "Asia/Tokyo", - "mailaddress": "terraform@example.com", - "dsm_lang": "ja", - "tenant_flg": true, - "status": 1 -} -` - -var expectedResult = security.HostBasedSecurity{ - Code: "DEP-01", - Message: "Successful completion", - Region: "jp4", - TenantName: "Test Tenant", - TenantDescription: "Test Tenant", - ContractID: "econ9999999999", - ServiceOrderService: "Managed Anti-Virus", - MaxAgentValue: float64(1), - TimeZone: "Asia/Tokyo", - CustomerName: "Customer", - MailAddress: "terraform@example.com", - DSMLang: "ja", - TenantFlg: true, - Status: 1, -} - -var createRequest = ` -{ - "sokind": "N", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "locale": "ja", - "service_order_service": "Managed Anti-Virus", - "max_agent_value": 1, - "mailaddress": "terraform@example.com", - "dsm_lang": "ja", - "time_zone": "Asia/Tokyo" -}` - -var createResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var createResult = security.HostBasedOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var updateRequestM1 = ` -{ - "sokind": "M1", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "locale": "ja", - "mailaddress": "terraform@example.com", - "service_order_service": "Managed Anti-Virus" -}` - -var updateResponseM1 = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var updateResultM1 = security.HostBasedOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var updateRequestM2 = ` -{ - "sokind": "M2", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "locale": "ja", - "mailaddress": "terraform@example.com", - "max_agent_value": 10 -}` - -var updateResponseM2 = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var updateResultM2 = security.HostBasedOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var deleteRequest = ` -{ - "sokind": "C", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "locale": "ja", - "mailaddress": "terraform@example.com" -}` - -var deleteResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var deleteResult = security.HostBasedOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} diff --git a/v3/ecl/security_order/v2/host_based/testing/requests_test.go b/v3/ecl/security_order/v2/host_based/testing/requests_test.go deleted file mode 100644 index 84c5aa4..0000000 --- a/v3/ecl/security_order/v2/host_based/testing/requests_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/host_based" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestGetHostBasedSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/ScreenEventHBSOrderInfoGet" - fmt.Println(url) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := security.Get(fakeclient.ServiceClient(), nil).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedResult, actual) -} - -func TestCreateHostBasedSecurity(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/SoEntryHBS", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - createOpts := security.CreateOpts{ - SOKind: "N", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Locale: "ja", - ServiceOrderService: "Managed Anti-Virus", - MaxAgentValue: 1, - MailAddress: "terraform@example.com", - DSMLang: "ja", - TimeZone: "Asia/Tokyo", - } - - actual, err := security.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createResult, actual) -} - -func TestUpdateHostBasedSecurityTypeM1(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryHBS" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequestM1) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, updateResponseM1) - }) - - updateOpts := security.UpdateOpts{ - SOKind: "M1", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Locale: "ja", - MailAddress: "terraform@example.com", - } - - serviceOrderService := "Managed Anti-Virus" - updateOpts.ServiceOrderService = &serviceOrderService - actual, err := security.Update(fakeclient.ServiceClient(), updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &updateResultM1, actual) -} - -func TestUpdateHostBasedSecurityTypeM2(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryHBS" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequestM2) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, updateResponseM2) - }) - - updateOpts := security.UpdateOpts{ - SOKind: "M2", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Locale: "ja", - MailAddress: "terraform@example.com", - } - - maxAgentValue := 10 - updateOpts.MaxAgentValue = &maxAgentValue - actual, err := security.Update(fakeclient.ServiceClient(), updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &updateResultM2, actual) -} - -func TestDeleteDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryHBS" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, deleteRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, deleteResponse) - }) - - deleteOpts := security.DeleteOpts{ - SOKind: "C", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Locale: "ja", - MailAddress: "terraform@example.com", - } - - actual, err := security.Delete(fakeclient.ServiceClient(), deleteOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &deleteResult, actual) -} diff --git a/v3/ecl/security_order/v2/host_based/urls.go b/v3/ecl/security_order/v2/host_based/urls.go deleted file mode 100644 index 0cdb692..0000000 --- a/v3/ecl/security_order/v2/host_based/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package host_based - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/ScreenEventHBSOrderInfoGet") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryHBS") -} - -func deleteURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryHBS") -} - -func updateURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryHBS") -} diff --git a/v3/ecl/security_order/v2/network_based_device_ha/doc.go b/v3/ecl/security_order/v2/network_based_device_ha/doc.go deleted file mode 100644 index e5f191e..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package network_based_device_ha contains HA device functionality on security. -package network_based_device_ha diff --git a/v3/ecl/security_order/v2/network_based_device_ha/requests.go b/v3/ecl/security_order/v2/network_based_device_ha/requests.go deleted file mode 100644 index 07f2216..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/requests.go +++ /dev/null @@ -1,162 +0,0 @@ -package network_based_device_ha - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToHADeviceQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -type ListOpts struct { - TenantID string `q:"tenant_id"` - Locale string `q:"locale"` -} - -// ToHADeviceQuery formats a ListOpts into a query string. -func (opts ListOpts) ToHADeviceQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the Devices to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToHADeviceQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return HADevicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToHADeviceCreateMap() (map[string]interface{}, error) -} - -// GtHostInCreate represents parameters used to create a HA Device. -type GtHostInCreate struct { - OperatingMode string `json:"operatingmode" required:"true"` - LicenseKind string `json:"licensekind" required:"true"` - AZGroup string `json:"azgroup" required:"true"` - - HALink1NetworkID string `json:"halink1networkid" required:"true"` - HALink1SubnetID string `json:"halink1subnetid" required:"true"` - HALink1IPAddress string `json:"halink1ipaddress" required:"true"` - - HALink2NetworkID string `json:"halink2networkid" required:"true"` - HALink2SubnetID string `json:"halink2subnetid" required:"true"` - HALink2IPAddress string `json:"halink2ipaddress" required:"true"` -} - -// CreateOpts represents parameters used to create a device. -type CreateOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - Locale string `json:"locale,omitempty"` - GtHost [2]GtHostInCreate `json:"gt_host" required:"true"` -} - -// ToHADeviceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToHADeviceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new device. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToHADeviceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// DeleteOptsBuilder allows extensions to add additional parameters to -// the Delete request. -type DeleteOptsBuilder interface { - ToHADeviceDeleteMap() (map[string]interface{}, error) -} - -// GtHostInDelete represents parameters used to delete a HA Device. -type GtHostInDelete struct { - HostName string `json:"hostname" required:"true"` -} - -// DeleteOpts represents parameters used to delete a device. -type DeleteOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - GtHost [2]GtHostInDelete `json:"gt_host" required:"true"` -} - -// ToHADeviceDeleteMap formats a DeleteOpts into a delete request. -func (opts DeleteOpts) ToHADeviceDeleteMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Delete deletes a device. -func Delete(client *eclcloud.ServiceClient, deviceType string, opts DeleteOptsBuilder) (r DeleteResult) { - b, err := opts.ToHADeviceDeleteMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return - -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToHADeviceUpdateMap() (map[string]interface{}, error) -} - -// GtHostInUpdate represents parameters used to update a HA Device. -type GtHostInUpdate struct { - OperatingMode string `json:"operatingmode" required:"true"` - LicenseKind string `json:"licensekind" required:"true"` - HostName string `json:"hostname" required:"true"` -} - -// UpdateOpts represents parameters to update a HA Device. -type UpdateOpts struct { - SOKind string `json:"sokind" required:"true"` - Locale string `json:"locale,omitempty"` - TenantID string `json:"tenant_id" required:"true"` - GtHost [2]GtHostInUpdate `json:"gt_host" required:"true"` -} - -// ToHADeviceUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToHADeviceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of a device. -func Update(client *eclcloud.ServiceClient, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToHADeviceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(updateURL(client), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/security_order/v2/network_based_device_ha/results.go b/v3/ecl/security_order/v2/network_based_device_ha/results.go deleted file mode 100644 index 28db67e..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/results.go +++ /dev/null @@ -1,104 +0,0 @@ -package network_based_device_ha - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a HA Device resource. -func (r commonResult) Extract() (*HADeviceOrder, error) { - var sdo HADeviceOrder - err := r.ExtractInto(&sdo) - return &sdo, err -} - -// Extract interprets any commonResult as a HA Device if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a HA Device. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a HA Device. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a HA Device. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - commonResult -} - -// HADevice represents the result of a each element in -// response of HA Device api result. -type HADevice struct { - ID int `json:"id"` - Cell []string `json:"cell"` -} - -// HADeviceOrder represents a HA Device's each order. -type HADeviceOrder struct { - ID string `json:"soId"` - Code string `json:"code"` - Message string `json:"message"` - Status int `json:"status"` -} - -// HADevicePage is the page returned by a pager -// when traversing over a collection of HA Device. -type HADevicePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of HA Device -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r HADevicePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"ha_device_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a HADevicePage struct is empty. -func (r HADevicePage) IsEmpty() (bool, error) { - is, err := ExtractHADevices(r) - return len(is) == 0, err -} - -// ExtractHADevices accepts a Page struct, -// specifically a HADevicePage struct, and extracts the elements -// into a slice of HA Device structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractHADevices(r pagination.Page) ([]HADevice, error) { - var s []HADevice - err := ExtractHADevicesInto(r, &s) - return s, err -} - -// ExtractHADevicesInto interprets the results of a single page from a List() call, -// producing a slice of Device entities. -func ExtractHADevicesInto(r pagination.Page, v interface{}) error { - return r.(HADevicePage).Result.ExtractIntoSlicePtr(v, "rows") -} diff --git a/v3/ecl/security_order/v2/network_based_device_ha/testing/doc.go b/v3/ecl/security_order/v2/network_based_device_ha/testing/doc.go deleted file mode 100644 index 499badf..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains network based security HA device unittests -package testing diff --git a/v3/ecl/security_order/v2/network_based_device_ha/testing/fixtures.go b/v3/ecl/security_order/v2/network_based_device_ha/testing/fixtures.go deleted file mode 100644 index 5239152..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/testing/fixtures.go +++ /dev/null @@ -1,149 +0,0 @@ -package testing - -import ( - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/network_based_device_ha" -) - -const listResponse = ` -{ - "status": 1, - "code": "FOV-01", - "message": "Successful completion", - "records": 2, - "rows": [ - { - "cell": ["false", "1", "1902F60E", "CES12085", "FW_HA", "02", "ha", "zone1-groupa", "jp4_zone1", "dummyNetworkID1", "dummySubnetID1", "192.168.1.3", "dummyNetworkID2", "dummySubnetID2", "192.168.2.3"], - "id": 1 - }, - { - "cell": ["false", "2", "1902F60E", "CES12086", "FW_HA", "02", "ha", "zone1-groupb", "jp4_zone1", "dummyNetworkID1", "dummySubnetID1", "192.168.1.4", "dummyNetworkID2", "dummySubnetID2", "192.168.2.4"], - "id": 2 - } - ] -} -` - -var expectedDevicesSlice = []security.HADevice{firstDevice, secondDevice} - -var firstDevice = security.HADevice{ - ID: 1, - Cell: []string{ - "false", "1", "1902F60E", "CES12085", "FW_HA", "02", "ha", "zone1-groupa", "jp4_zone1", "dummyNetworkID1", "dummySubnetID1", "192.168.1.3", "dummyNetworkID2", "dummySubnetID2", "192.168.2.3", - }, -} - -var secondDevice = security.HADevice{ - ID: 2, - Cell: []string{ - "false", "2", "1902F60E", "CES12086", "FW_HA", "02", "ha", "zone1-groupb", "jp4_zone1", "dummyNetworkID1", "dummySubnetID1", "192.168.1.4", "dummyNetworkID2", "dummySubnetID2", "192.168.2.4", - }, -} - -var createRequest = ` -{ - "gt_host": [ - { - "azgroup": "zone1-groupa", - "licensekind": "02", - "operatingmode": "FW_HA", - "halink1ipaddress": "192.168.1.3", - "halink1networkid": "c5b1b0a8-45a3-4c99-b808-84e7c13e557f", - "halink1subnetid": "9a2116e2-52be-439c-9587-506a1a5d288d", - "halink2ipaddress": "192.168.2.3", - "halink2networkid": "a8df4d5f-8752-4574-a255-dc749acd458f", - "halink2subnetid": "a2ff5669-8422-421c-bb85-a6d691ecf223" - }, - { - "azgroup": "zone1-groupb", - "licensekind": "02", - "operatingmode": "FW_HA", - "halink1ipaddress": "192.168.1.4", - "halink1networkid": "c5b1b0a8-45a3-4c99-b808-84e7c13e557f", - "halink1subnetid": "9a2116e2-52be-439c-9587-506a1a5d288d", - "halink2ipaddress": "192.168.2.4", - "halink2networkid": "a8df4d5f-8752-4574-a255-dc749acd458f", - "halink2subnetid": "a2ff5669-8422-421c-bb85-a6d691ecf223" - } - ], - "locale": "ja", - "sokind": "AH", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var createResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var createResult = security.HADeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var updateRequest = ` -{ - "gt_host": [ - { - "hostname": "CES11811", - "licensekind": "08", - "operatingmode": "UTM_HA" - }, - { - "hostname": "CES11812", - "licensekind": "08", - "operatingmode": "UTM_HA" - } - ], - "locale": "en", - "sokind": "MH", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var updateResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var updateResult = security.HADeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var deleteRequest = ` -{ - "gt_host": [ - { - "hostname": "CES11811" - }, - { - "hostname": "CES11812" - } - ], - "sokind": "DH", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var deleteResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var deleteResult = security.HADeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} diff --git a/v3/ecl/security_order/v2/network_based_device_ha/testing/requests_test.go b/v3/ecl/security_order/v2/network_based_device_ha/testing/requests_test.go deleted file mode 100644 index 76dad69..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/testing/requests_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/network_based_device_ha" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/ScreenEventFGHADeviceGet", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := security.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := security.ExtractHADevices(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedDevicesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDeviceZoneAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/ScreenEventFGHADeviceGet", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := security.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allDevices, err := security.ExtractHADevices(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allDevices)) -} - -func TestCreateDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/SoEntryFGHA", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - gtHost1 := security.GtHostInCreate{ - AZGroup: "zone1-groupa", - LicenseKind: "02", - OperatingMode: "FW_HA", - HALink1IPAddress: "192.168.1.3", - HALink1NetworkID: "c5b1b0a8-45a3-4c99-b808-84e7c13e557f", - HALink1SubnetID: "9a2116e2-52be-439c-9587-506a1a5d288d", - HALink2IPAddress: "192.168.2.3", - HALink2NetworkID: "a8df4d5f-8752-4574-a255-dc749acd458f", - HALink2SubnetID: "a2ff5669-8422-421c-bb85-a6d691ecf223", - } - - gtHost2 := security.GtHostInCreate{ - AZGroup: "zone1-groupb", - LicenseKind: "02", - OperatingMode: "FW_HA", - HALink1IPAddress: "192.168.1.4", - HALink1NetworkID: "c5b1b0a8-45a3-4c99-b808-84e7c13e557f", - HALink1SubnetID: "9a2116e2-52be-439c-9587-506a1a5d288d", - HALink2IPAddress: "192.168.2.4", - HALink2NetworkID: "a8df4d5f-8752-4574-a255-dc749acd458f", - HALink2SubnetID: "a2ff5669-8422-421c-bb85-a6d691ecf223", - } - - createOpts := security.CreateOpts{ - SOKind: "AH", - Locale: "ja", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [2]security.GtHostInCreate{gtHost1, gtHost2}, - } - - actual, err := security.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createResult, actual) -} - -func TestUpdateDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryFGHA" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, updateResponse) - }) - - gtHost1 := security.GtHostInUpdate{ - OperatingMode: "UTM_HA", - LicenseKind: "08", - HostName: "CES11811", - } - - gtHost2 := security.GtHostInUpdate{ - OperatingMode: "UTM_HA", - LicenseKind: "08", - HostName: "CES11812", - } - - updateOpts := security.UpdateOpts{ - SOKind: "MH", - Locale: "en", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [2]security.GtHostInUpdate{gtHost1, gtHost2}, - } - - actual, err := security.Update(fakeclient.ServiceClient(), updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &updateResult, actual) -} - -func TestDeleteDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryFGHA" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, deleteRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, deleteResponse) - }) - - gtHost1 := security.GtHostInDelete{ - HostName: "CES11811", - } - - gtHost2 := security.GtHostInDelete{ - HostName: "CES11812", - } - - deleteOpts := security.DeleteOpts{ - SOKind: "DH", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [2]security.GtHostInDelete{gtHost1, gtHost2}, - } - - actual, err := security.Delete(fakeclient.ServiceClient(), "CES11811", deleteOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &deleteResult, actual) -} diff --git a/v3/ecl/security_order/v2/network_based_device_ha/urls.go b/v3/ecl/security_order/v2/network_based_device_ha/urls.go deleted file mode 100644 index 2e6b015..0000000 --- a/v3/ecl/security_order/v2/network_based_device_ha/urls.go +++ /dev/null @@ -1,21 +0,0 @@ -package network_based_device_ha - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/ScreenEventFGHADeviceGet") -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryFGHA") -} - -func deleteURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryFGHA") -} - -func updateURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("API/SoEntryFGHA") -} diff --git a/v3/ecl/security_order/v2/network_based_device_single/doc.go b/v3/ecl/security_order/v2/network_based_device_single/doc.go deleted file mode 100644 index b752fd5..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package network_based_device_single contains single device functionality on security. -package network_based_device_single diff --git a/v3/ecl/security_order/v2/network_based_device_single/requests.go b/v3/ecl/security_order/v2/network_based_device_single/requests.go deleted file mode 100644 index 5c37b03..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/requests.go +++ /dev/null @@ -1,154 +0,0 @@ -package network_based_device_single - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToSingleDeviceQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -type ListOpts struct { - TenantID string `q:"tenant_id"` - Locale string `q:"locale"` -} - -// ToSingleDeviceQuery formats a ListOpts into a query string. -func (opts ListOpts) ToSingleDeviceQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the Devices to which the current token has access. -func List(client *eclcloud.ServiceClient, deviceType string, opts ListOptsBuilder) pagination.Pager { - url := listURL(client, deviceType) - if opts != nil { - query, err := opts.ToSingleDeviceQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return SingleDevicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToSingleDeviceCreateMap() (map[string]interface{}, error) -} - -// GtHostInCreate represents parameters used to create a Single Device. -type GtHostInCreate struct { - OperatingMode string `json:"operatingmode" required:"true"` - LicenseKind string `json:"licensekind" required:"true"` - AZGroup string `json:"azgroup" required:"true"` -} - -// CreateOpts represents parameters used to create a device. -type CreateOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - Locale string `json:"locale,omitempty"` - GtHost [1]GtHostInCreate `json:"gt_host" required:"true"` -} - -// ToSingleDeviceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToSingleDeviceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new device. -func Create(client *eclcloud.ServiceClient, deviceType string, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToSingleDeviceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client, deviceType), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// DeleteOptsBuilder allows extensions to add additional parameters to -// the Delete request. -type DeleteOptsBuilder interface { - ToSingleDeviceDeleteMap() (map[string]interface{}, error) -} - -// GtHostInDelete represents parameters used to delete a Single Device. -type GtHostInDelete struct { - HostName string `json:"hostname" required:"true"` -} - -// DeleteOpts represents parameters used to delete a device. -type DeleteOpts struct { - SOKind string `json:"sokind" required:"true"` - TenantID string `json:"tenant_id" required:"true"` - GtHost [1]GtHostInDelete `json:"gt_host" required:"true"` -} - -// ToSingleDeviceDeleteMap formats a DeleteOpts into a delete request. -func (opts DeleteOpts) ToSingleDeviceDeleteMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Delete deletes a device. -func Delete(client *eclcloud.ServiceClient, deviceType string, opts DeleteOptsBuilder) (r DeleteResult) { - b, err := opts.ToSingleDeviceDeleteMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client, deviceType), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return - -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToSingleDeviceUpdateMap() (map[string]interface{}, error) -} - -// GtHostInUpdate represents parameters used to update a Single Device. -type GtHostInUpdate struct { - OperatingMode string `json:"operatingmode" required:"true"` - LicenseKind string `json:"licensekind" required:"true"` - HostName string `json:"hostname" required:"true"` -} - -// UpdateOpts represents parameters to update a Single Device. -type UpdateOpts struct { - SOKind string `json:"sokind" required:"true"` - Locale string `json:"locale,omitempty"` - TenantID string `json:"tenant_id" required:"true"` - GtHost [1]GtHostInUpdate `json:"gt_host" required:"true"` -} - -// ToSingleDeviceUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToSingleDeviceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of a device. -func Update(client *eclcloud.ServiceClient, deviceType string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToSingleDeviceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(updateURL(client, deviceType), &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/security_order/v2/network_based_device_single/results.go b/v3/ecl/security_order/v2/network_based_device_single/results.go deleted file mode 100644 index 48ded15..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/results.go +++ /dev/null @@ -1,104 +0,0 @@ -package network_based_device_single - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a Single Device resource. -func (r commonResult) Extract() (*SingleDeviceOrder, error) { - var sdo SingleDeviceOrder - err := r.ExtractInto(&sdo) - return &sdo, err -} - -// Extract interprets any commonResult as a Single Device if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Single Device. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Single Device. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Single Device. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - commonResult -} - -// SingleDevice represents the result of a each element in -// response of single device api result. -type SingleDevice struct { - ID int `json:"id"` - Cell []string `json:"cell"` -} - -// SingleDeviceOrder represents a Single Device's each order. -type SingleDeviceOrder struct { - ID string `json:"soId"` - Code string `json:"code"` - Message string `json:"message"` - Status int `json:"status"` -} - -// SingleDevicePage is the page returned by a pager -// when traversing over a collection of Single Device. -type SingleDevicePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of Single Device -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r SingleDevicePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"single_device_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a SingleDevicePage struct is empty. -func (r SingleDevicePage) IsEmpty() (bool, error) { - is, err := ExtractSingleDevices(r) - return len(is) == 0, err -} - -// ExtractSingleDevices accepts a Page struct, -// specifically a SingleDevicePage struct, and extracts the elements -// into a slice of Single Device structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractSingleDevices(r pagination.Page) ([]SingleDevice, error) { - var s []SingleDevice - err := ExtractSingleDevicesInto(r, &s) - return s, err -} - -// ExtractSingleDevicesInto interprets the results of a single page from a List() call, -// producing a slice of Device entities. -func ExtractSingleDevicesInto(r pagination.Page, v interface{}) error { - return r.(SingleDevicePage).Result.ExtractIntoSlicePtr(v, "rows") -} diff --git a/v3/ecl/security_order/v2/network_based_device_single/testing/doc.go b/v3/ecl/security_order/v2/network_based_device_single/testing/doc.go deleted file mode 100644 index dd8abff..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains network based security single device unittests -package testing diff --git a/v3/ecl/security_order/v2/network_based_device_single/testing/fixtures.go b/v3/ecl/security_order/v2/network_based_device_single/testing/fixtures.go deleted file mode 100644 index e2e003d..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/testing/fixtures.go +++ /dev/null @@ -1,124 +0,0 @@ -package testing - -import ( - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/network_based_device_single" -) - -const listResponse = ` -{ - "status": 1, - "code": "FOV-01", - "message": "Successful completion", - "records": 2, - "rows": [ - { - "id": 1, - "cell": ["false", "1", "CES11810", "FW", "02", "standalone", "zone1-groupb", "jp4_zone1"] - }, - { - "id": 2, - "cell": ["false", "1", "CES11811", "FW", "02", "standalone", "zone1-groupb", "jp4_zone1"] - } - ] -} -` - -var expectedDevicesSlice = []security.SingleDevice{firstDevice, secondDevice} - -var firstDevice = security.SingleDevice{ - ID: 1, - Cell: []string{ - "false", "1", "CES11810", "FW", "02", "standalone", "zone1-groupb", "jp4_zone1", - }, -} - -var secondDevice = security.SingleDevice{ - ID: 2, - Cell: []string{ - "false", "1", "CES11811", "FW", "02", "standalone", "zone1-groupb", "jp4_zone1", - }, -} - -var createRequest = ` -{ - "gt_host":[ - { - "azgroup": "zone1-groupb", - "licensekind":"02", - "operatingmode":"FW" - } - ], - "locale": "ja", - "sokind": "A", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var createResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var createResult = security.SingleDeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var updateRequest = ` -{ - "gt_host": [ - { - "hostname": "CES11811", - "licensekind": "08", - "operatingmode": "UTM" - } - ], - "locale": "en", - "sokind": "M", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var updateResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var updateResult = security.SingleDeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} - -var deleteRequest = ` -{ - "gt_host": [ - { - "hostname": "CES11811" - } - ], - "sokind": "D", - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5" -}` - -var deleteResponse = ` -{ - "status": 1, - "code": "FOV-02", - "message": "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - "soId": "FGS_3B6A7602ACD04E16B6EBEF215AE8E642" -}` - -var deleteResult = security.SingleDeviceOrder{ - Status: 1, - Code: "FOV-02", - Message: "オーダーを受け付けました。ProgressRateにて状況を確認できます。", - ID: "FGS_3B6A7602ACD04E16B6EBEF215AE8E642", -} diff --git a/v3/ecl/security_order/v2/network_based_device_single/testing/requests_test.go b/v3/ecl/security_order/v2/network_based_device_single/testing/requests_test.go deleted file mode 100644 index 8f4f4d6..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/testing/requests_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - security "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/network_based_device_single" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/ScreenEventFGSDeviceGet", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := security.List(fakeclient.ServiceClient(), "UTM", nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := security.ExtractSingleDevices(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedDevicesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDeviceZoneAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/ScreenEventFGSDeviceGet", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := security.List(fakeclient.ServiceClient(), "UTM", nil).AllPages() - th.AssertNoErr(t, err) - allDevices, err := security.ExtractSingleDevices(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allDevices)) -} - -func TestCreateDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/API/SoEntryFGS", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - gtHost := security.GtHostInCreate{ - AZGroup: "zone1-groupb", - LicenseKind: "02", - OperatingMode: "FW", - } - createOpts := security.CreateOpts{ - SOKind: "A", - Locale: "ja", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [1]security.GtHostInCreate{gtHost}, - } - - actual, err := security.Create(fakeclient.ServiceClient(), "UTM", createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createResult, actual) -} - -func TestUpdateDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryFGS" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, updateResponse) - }) - - gtHost := security.GtHostInUpdate{ - OperatingMode: "UTM", - LicenseKind: "08", - HostName: "CES11811", - } - updateOpts := security.UpdateOpts{ - SOKind: "M", - Locale: "en", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [1]security.GtHostInUpdate{gtHost}, - } - - actual, err := security.Update(fakeclient.ServiceClient(), "CES11811", updateOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &updateResult, actual) -} - -func TestDeleteDevice(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/SoEntryFGS" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, deleteRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, deleteResponse) - }) - - gtHost := security.GtHostInDelete{ - HostName: "CES11811", - } - deleteOpts := security.DeleteOpts{ - SOKind: "D", - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - GtHost: [1]security.GtHostInDelete{gtHost}, - } - - actual, err := security.Delete(fakeclient.ServiceClient(), "CES11811", deleteOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &deleteResult, actual) -} diff --git a/v3/ecl/security_order/v2/network_based_device_single/urls.go b/v3/ecl/security_order/v2/network_based_device_single/urls.go deleted file mode 100644 index 1f2ce5b..0000000 --- a/v3/ecl/security_order/v2/network_based_device_single/urls.go +++ /dev/null @@ -1,38 +0,0 @@ -package network_based_device_single - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func getURLPartFromDeviceType(deviceType string) string { - if deviceType == "WAF" { - return "WAF" - } - return "S" -} - -func listURL(client *eclcloud.ServiceClient, deviceType string) string { - part := getURLPartFromDeviceType(deviceType) - url := fmt.Sprintf("API/ScreenEventFG%sDeviceGet", part) - return client.ServiceURL(url) -} - -func createURL(client *eclcloud.ServiceClient, deviceType string) string { - part := getURLPartFromDeviceType(deviceType) - url := fmt.Sprintf("API/SoEntryFG%s", part) - return client.ServiceURL(url) -} - -func deleteURL(client *eclcloud.ServiceClient, deviceType string) string { - part := getURLPartFromDeviceType(deviceType) - url := fmt.Sprintf("API/SoEntryFG%s", part) - return client.ServiceURL(url) -} - -func updateURL(client *eclcloud.ServiceClient, deviceType string) string { - part := getURLPartFromDeviceType(deviceType) - url := fmt.Sprintf("API/SoEntryFG%s", part) - return client.ServiceURL(url) -} diff --git a/v3/ecl/security_order/v2/service_order_status/doc.go b/v3/ecl/security_order/v2/service_order_status/doc.go deleted file mode 100644 index f55fa76..0000000 --- a/v3/ecl/security_order/v2/service_order_status/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package service_order_status contains order management functionality on security -package service_order_status diff --git a/v3/ecl/security_order/v2/service_order_status/requests.go b/v3/ecl/security_order/v2/service_order_status/requests.go deleted file mode 100644 index 83834de..0000000 --- a/v3/ecl/security_order/v2/service_order_status/requests.go +++ /dev/null @@ -1,36 +0,0 @@ -package service_order_status - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// GetOptsBuilder allows extensions to add additional parameters to -// the order progress API request -type GetOptsBuilder interface { - ToServiceOrderQuery() (string, error) -} - -// GetOpts represents result of order progress API response. -type GetOpts struct { - TenantID string `q:"tenant_id"` - Locale string `q:"locale"` - SoID string `q:"soid"` -} - -// ToServiceOrderQuery formats a GetOpts into a query string. -func (opts GetOpts) ToServiceOrderQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Get retrieves details of an order progress, by SoId. -func Get(client *eclcloud.ServiceClient, deviceType string, opts GetOptsBuilder) (r GetResult) { - url := getURL(client, deviceType) - if opts != nil { - query, _ := opts.ToServiceOrderQuery() - url += query - } - - _, r.Err = client.Get(url, &r.Body, nil) - return -} diff --git a/v3/ecl/security_order/v2/service_order_status/results.go b/v3/ecl/security_order/v2/service_order_status/results.go deleted file mode 100644 index 88b8196..0000000 --- a/v3/ecl/security_order/v2/service_order_status/results.go +++ /dev/null @@ -1,36 +0,0 @@ -package service_order_status - -import ( - "github.com/nttcom/eclcloud/v3" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts an Order Progress resource. -func (r commonResult) Extract() (*OrderProgress, error) { - var sd OrderProgress - err := r.ExtractInto(&sd) - return &sd, err -} - -// Extract interprets any commonResult as an Order Progress, if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as an Order. -type GetResult struct { - commonResult -} - -// OrderProgress represents an Order Progress response. -type OrderProgress struct { - Status int `json:"status"` - Code string `json:"code"` - Message string `json:"message"` - ProgressRate int `json:"progressRate"` -} diff --git a/v3/ecl/security_order/v2/service_order_status/testing/doc.go b/v3/ecl/security_order/v2/service_order_status/testing/doc.go deleted file mode 100644 index 6b493c6..0000000 --- a/v3/ecl/security_order/v2/service_order_status/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains service order status unit tests -package testing diff --git a/v3/ecl/security_order/v2/service_order_status/testing/fixtures.go b/v3/ecl/security_order/v2/service_order_status/testing/fixtures.go deleted file mode 100644 index 8303574..0000000 --- a/v3/ecl/security_order/v2/service_order_status/testing/fixtures.go +++ /dev/null @@ -1,21 +0,0 @@ -package testing - -import ( - order "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/service_order_status" -) - -const getResponse = ` -{ - "status": 1, - "code": "FOV-05", - "message": "We accepted the order. Please wait", - "progressRate": 45 -} -` - -var expectedResult = order.OrderProgress{ - Status: 1, - Code: "FOV-05", - Message: "We accepted the order. Please wait", - ProgressRate: 45, -} diff --git a/v3/ecl/security_order/v2/service_order_status/testing/requests_test.go b/v3/ecl/security_order/v2/service_order_status/testing/requests_test.go deleted file mode 100644 index 7bf1e1b..0000000 --- a/v3/ecl/security_order/v2/service_order_status/testing/requests_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - order "github.com/nttcom/eclcloud/v3/ecl/security_order/v2/service_order_status" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestGetOrder(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/API/ScreenEventFGSOrderProgressRate" - fmt.Println(url) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := order.Get(fakeclient.ServiceClient(), "UTM", nil).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedResult, actual) -} diff --git a/v3/ecl/security_order/v2/service_order_status/urls.go b/v3/ecl/security_order/v2/service_order_status/urls.go deleted file mode 100644 index a4d5005..0000000 --- a/v3/ecl/security_order/v2/service_order_status/urls.go +++ /dev/null @@ -1,24 +0,0 @@ -package service_order_status - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, deviceType string) string { - var part string - switch deviceType { - case "WAF": - part = "FGWAF" - break - case "HostBased": - part = "HBS" - break - default: - part = "FGS" - } - - url := fmt.Sprintf("API/ScreenEvent%sOrderProgressRate", part) - return client.ServiceURL(url) -} diff --git a/v3/ecl/security_portal/v2/device_interfaces/doc.go b/v3/ecl/security_portal/v2/device_interfaces/doc.go deleted file mode 100644 index 4ae5098..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package device_interfaces contains device management functionality in security portal API -package device_interfaces diff --git a/v3/ecl/security_portal/v2/device_interfaces/requests.go b/v3/ecl/security_portal/v2/device_interfaces/requests.go deleted file mode 100644 index f8071df..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/requests.go +++ /dev/null @@ -1,40 +0,0 @@ -package device_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToDeviceInterfaceQuery() (string, error) -} - -// ListOpts converts tenant id and token as query string -type ListOpts struct { - TenantID string `q:"tenantid"` - UserToken string `q:"usertoken"` -} - -// ToDeviceInterfaceQuery formats a ListOpts into a query string. -func (opts ListOpts) ToDeviceInterfaceQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// device interfaces. -func List(client *eclcloud.ServiceClient, serverUUID string, opts ListOptsBuilder) pagination.Pager { - url := listURL(client, serverUUID) - if opts != nil { - query, err := opts.ToDeviceInterfaceQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return DeviceInterfacePage{pagination.LinkedPageBase{PageResult: r}} - }) -} diff --git a/v3/ecl/security_portal/v2/device_interfaces/results.go b/v3/ecl/security_portal/v2/device_interfaces/results.go deleted file mode 100644 index 0da8c63..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/results.go +++ /dev/null @@ -1,65 +0,0 @@ -package device_interfaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// DeviceInterface represents the result of a each element in -// response of device interface api result. -type DeviceInterface struct { - OSIPAddress string `json:"os_ip_address"` - MSAPortID string `json:"msa_port_id"` - OSPortName string `json:"os_port_name"` - OSPortID string `json:"os_port_id"` - OSNetworkID string `json:"os_network_id"` - OSPortStatus string `json:"os_port_status"` - OSMACAddress string `json:"os_mac_address"` - OSSubnetID string `json:"os_subnet_id"` -} - -// DeviceInterfacePage is the page returned by a pager -// when traversing over a collection of Device Interface. -type DeviceInterfacePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of Single Device Interface -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r DeviceInterfacePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"device_interfaces"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a DeviceInterfacePage struct is empty. -func (r DeviceInterfacePage) IsEmpty() (bool, error) { - is, err := ExtractDeviceInterfaces(r) - return len(is) == 0, err -} - -// ExtractDeviceInterfaces accepts a Page struct, -// specifically a DeviceInterfacePage struct, and extracts the elements -// into a slice of Device Interface structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractDeviceInterfaces(r pagination.Page) ([]DeviceInterface, error) { - var d []DeviceInterface - err := ExtractDeviceInterfacesInto(r, &d) - return d, err -} - -// ExtractDeviceInterfacesInto interprets the results of a single page from a List() call, -// producing a slice of Device Interface entities. -func ExtractDeviceInterfacesInto(r pagination.Page, v interface{}) error { - return r.(DeviceInterfacePage).Result.ExtractIntoSlicePtr(v, "device_interfaces") -} diff --git a/v3/ecl/security_portal/v2/device_interfaces/testing/doc.go b/v3/ecl/security_portal/v2/device_interfaces/testing/doc.go deleted file mode 100644 index 7c9a653..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains device interfaces unit tests -package testing diff --git a/v3/ecl/security_portal/v2/device_interfaces/testing/fixtures.go b/v3/ecl/security_portal/v2/device_interfaces/testing/fixtures.go deleted file mode 100644 index b71367d..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/testing/fixtures.go +++ /dev/null @@ -1,60 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/device_interfaces" -) - -const deviceUUID = "cad6e00a-2af9-491c-b732-ca5688d147f5" - -const listResponse = ` -{ - "device_interfaces": [ - { - "os_ip_address": "192.168.1.50", - "msa_port_id": "port4", - "os_port_name": "port4-CES11892", - "os_port_id": "82ebe045-9c9a-4088-8b33-cb0d590079aa", - "os_network_id": "5ef9c597-15fe-431c-84b9-88d00d567202", - "os_port_status": "ACTIVE", - "os_mac_address": "fa:16:3e:05:ff:66", - "os_subnet_id": "48ea24c7-fe48-4a54-9ed0-528aa09cebc7" - }, - { - "os_ip_address": "192.168.2.50", - "msa_port_id": "port7", - "os_port_name": "port7-CES11892", - "os_port_id": "82ebe045-9c9a-4088-8b33-cb0d590079aa", - "os_network_id": "5ef9c597-15fe-431c-84b9-88d00d567203", - "os_port_status": "ACTIVE", - "os_mac_address": "fa:16:3e:05:ff:67", - "os_subnet_id": "48ea24c7-fe48-4a54-9ed0-528aa09cebc8" - } - ] -} -` - -var expectedDeviceInterfacesSlice = []device_interfaces.DeviceInterface{ - firstDeviceInterface, secondDeviceInterface, -} - -var firstDeviceInterface = device_interfaces.DeviceInterface{ - OSIPAddress: "192.168.1.50", - MSAPortID: "port4", - OSPortName: "port4-CES11892", - OSPortID: "82ebe045-9c9a-4088-8b33-cb0d590079aa", - OSNetworkID: "5ef9c597-15fe-431c-84b9-88d00d567202", - OSPortStatus: "ACTIVE", - OSMACAddress: "fa:16:3e:05:ff:66", - OSSubnetID: "48ea24c7-fe48-4a54-9ed0-528aa09cebc7", -} - -var secondDeviceInterface = device_interfaces.DeviceInterface{ - OSIPAddress: "192.168.2.50", - MSAPortID: "port7", - OSPortName: "port7-CES11892", - OSPortID: "82ebe045-9c9a-4088-8b33-cb0d590079aa", - OSNetworkID: "5ef9c597-15fe-431c-84b9-88d00d567203", - OSPortStatus: "ACTIVE", - OSMACAddress: "fa:16:3e:05:ff:67", - OSSubnetID: "48ea24c7-fe48-4a54-9ed0-528aa09cebc8", -} diff --git a/v3/ecl/security_portal/v2/device_interfaces/testing/requests_test.go b/v3/ecl/security_portal/v2/device_interfaces/testing/requests_test.go deleted file mode 100644 index f5ef2e0..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/testing/requests_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/device_interfaces" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDeviceInterfaces(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/ecl-api/devices/%s/interfaces", deviceUUID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := device_interfaces.List(fakeclient.ServiceClient(), deviceUUID, nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := device_interfaces.ExtractDeviceInterfaces(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedDeviceInterfacesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDeviceInterfaceAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/ecl-api/devices/%s/interfaces", deviceUUID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := device_interfaces.List(fakeclient.ServiceClient(), deviceUUID, nil).AllPages() - th.AssertNoErr(t, err) - allDeviceInterfaces, err := device_interfaces.ExtractDeviceInterfaces(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allDeviceInterfaces)) -} diff --git a/v3/ecl/security_portal/v2/device_interfaces/urls.go b/v3/ecl/security_portal/v2/device_interfaces/urls.go deleted file mode 100644 index 987c4d4..0000000 --- a/v3/ecl/security_portal/v2/device_interfaces/urls.go +++ /dev/null @@ -1,12 +0,0 @@ -package device_interfaces - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func listURL(client *eclcloud.ServiceClient, serverUUID string) string { - url := fmt.Sprintf("ecl-api/devices/%s/interfaces", serverUUID) - return client.ServiceURL(url) -} diff --git a/v3/ecl/security_portal/v2/devices/doc.go b/v3/ecl/security_portal/v2/devices/doc.go deleted file mode 100644 index 6a88b4d..0000000 --- a/v3/ecl/security_portal/v2/devices/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package devices contains device management functionality in security portal API -package devices diff --git a/v3/ecl/security_portal/v2/devices/requests.go b/v3/ecl/security_portal/v2/devices/requests.go deleted file mode 100644 index b6f5140..0000000 --- a/v3/ecl/security_portal/v2/devices/requests.go +++ /dev/null @@ -1,40 +0,0 @@ -package devices - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToDevicesQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -type ListOpts struct { - TenantID string `q:"tenantid"` - UserToken string `q:"usertoken"` -} - -// ToDevicesQuery formats a ListOpts into a query string. -func (opts ListOpts) ToDevicesQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over -// a collection of devices. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToDevicesQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return DevicePage{pagination.LinkedPageBase{PageResult: r}} - }) -} diff --git a/v3/ecl/security_portal/v2/devices/results.go b/v3/ecl/security_portal/v2/devices/results.go deleted file mode 100644 index 03c9ee7..0000000 --- a/v3/ecl/security_portal/v2/devices/results.go +++ /dev/null @@ -1,64 +0,0 @@ -package devices - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Device represents the result of a each element in -// response of device api result. -type Device struct { - MSADeviceID string `json:"msa_device_id"` - OSServerID string `json:"os_server_id"` - OSServerName string `json:"os_server_name"` - OSAvailabilityZone string `json:"os_availability_zone"` - OSAdminUserName string `json:"os_admin_username"` - MSADeviceType string `json:"msa_device_type"` - OSServerStatus string `json:"os_server_status"` -} - -// DevicePage is the page returned by a pager -// when traversing over a collection of Device. -type DevicePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of Device -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r DevicePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"devices"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a Device struct is empty. -func (r DevicePage) IsEmpty() (bool, error) { - is, err := ExtractDevices(r) - return len(is) == 0, err -} - -// ExtractDevices accepts a Page struct, -// specifically a DevicePage struct, and extracts the elements -// into a slice of Device structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractDevices(r pagination.Page) ([]Device, error) { - var d []Device - err := ExtractDevicesInto(r, &d) - return d, err -} - -// ExtractDevicesInto interprets the results of a single page from a List() call, -// producing a slice of Device entities. -func ExtractDevicesInto(r pagination.Page, v interface{}) error { - return r.(DevicePage).Result.ExtractIntoSlicePtr(v, "devices") -} diff --git a/v3/ecl/security_portal/v2/devices/testing/doc.go b/v3/ecl/security_portal/v2/devices/testing/doc.go deleted file mode 100644 index d541ffa..0000000 --- a/v3/ecl/security_portal/v2/devices/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains devices unit tests -package testing diff --git a/v3/ecl/security_portal/v2/devices/testing/fixtures.go b/v3/ecl/security_portal/v2/devices/testing/fixtures.go deleted file mode 100644 index 44f70bc..0000000 --- a/v3/ecl/security_portal/v2/devices/testing/fixtures.go +++ /dev/null @@ -1,51 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/devices" -) - -const listResponse = ` -{ - "devices": [ - { - "msa_device_id": "CES11810", - "os_server_id": "392a90bf-2c1b-45fd-8221-096894fff39d", - "os_server_name": "UTM-CES11878", - "os_availability_zone": "zone1-groupb", - "os_admin_username": "jp4_sdp_mss_utm_admin", - "msa_device_type": "FW", - "os_server_status": "ACTIVE" - }, - { - "msa_device_id": "CES11811", - "os_server_id": "12768064-e7c9-44d1-b01d-e66f138a278e", - "os_server_name": "WAF-CES11816", - "os_availability_zone": "zone1-groupb", - "os_admin_username": "jp4_sdp_mss_utm_admin", - "msa_device_type": "WAF", - "os_server_status": "ACTIVE" - } - ] -}` - -var expectedDevicesSlice = []devices.Device{firstDevice, secondDevice} - -var firstDevice = devices.Device{ - MSADeviceID: "CES11810", - OSServerID: "392a90bf-2c1b-45fd-8221-096894fff39d", - OSServerName: "UTM-CES11878", - OSAvailabilityZone: "zone1-groupb", - OSAdminUserName: "jp4_sdp_mss_utm_admin", - MSADeviceType: "FW", - OSServerStatus: "ACTIVE", -} - -var secondDevice = devices.Device{ - MSADeviceID: "CES11811", - OSServerID: "12768064-e7c9-44d1-b01d-e66f138a278e", - OSServerName: "WAF-CES11816", - OSAvailabilityZone: "zone1-groupb", - OSAdminUserName: "jp4_sdp_mss_utm_admin", - MSADeviceType: "WAF", - OSServerStatus: "ACTIVE", -} diff --git a/v3/ecl/security_portal/v2/devices/testing/requests_test.go b/v3/ecl/security_portal/v2/devices/testing/requests_test.go deleted file mode 100644 index 9f2fb8a..0000000 --- a/v3/ecl/security_portal/v2/devices/testing/requests_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/devices" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListDevices(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ecl-api/devices", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := devices.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := devices.ExtractDevices(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedDevicesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListDeviceAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/ecl-api/devices", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := devices.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allDevices, err := devices.ExtractDevices(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allDevices)) -} diff --git a/v3/ecl/security_portal/v2/devices/urls.go b/v3/ecl/security_portal/v2/devices/urls.go deleted file mode 100644 index da31626..0000000 --- a/v3/ecl/security_portal/v2/devices/urls.go +++ /dev/null @@ -1,9 +0,0 @@ -package devices - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("ecl-api/devices") -} diff --git a/v3/ecl/security_portal/v2/ha_ports/doc.go b/v3/ecl/security_portal/v2/ha_ports/doc.go deleted file mode 100644 index 6412766..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package ha_ports contains port management functionality in security portal API -package ha_ports diff --git a/v3/ecl/security_portal/v2/ha_ports/requests.go b/v3/ecl/security_portal/v2/ha_ports/requests.go deleted file mode 100644 index d1f538e..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/requests.go +++ /dev/null @@ -1,78 +0,0 @@ -package ha_ports - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToPortUpdateMap() (map[string]interface{}, error) -} - -// SinglePort represents parameters to update a Single Port. -type SinglePort struct { - EnablePort string `json:"enable_port" required:"true"` - IPAddress []string `json:"ip_address,omitempty"` - NetworkID string `json:"network_id,omitempty"` - SubnetID string `json:"subnet_id,omitempty"` - MTU string `json:"mtu,omitempty"` - Comment string `json:"comment,omitempty"` - - EnablePing string `json:"enable_ping,omitempty"` - VRRPGroupID string `json:"vrrp_grp_id,omitempty"` - VRRPID string `json:"vrrp_id,omitempty"` - VRRPIPAddress string `json:"vrrp_ip,omitempty"` - Preempt string `json:"preempt,omitempty"` -} - -// UpdateOpts represents options used to update a port. -type UpdateOpts struct { - Port []SinglePort `json:"port" required:"true"` -} - -// ToPortUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// UpdateQueryOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateQueryOptsBuilder interface { - ToUpdateQuery() (string, error) -} - -// UpdateQueryOpts represents query strings for updating port. -type UpdateQueryOpts struct { - TenantID string `q:"tenantid"` - UserToken string `q:"usertoken"` -} - -// ToUpdateQuery formats a ListOpts into a query string. -func (opts UpdateQueryOpts) ToUpdateQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Update modifies the attributes of a port. -func Update(client *eclcloud.ServiceClient, - hostName string, - opts UpdateOptsBuilder, - qOpts UpdateQueryOptsBuilder) (r UpdateResult) { - b, err := opts.ToPortUpdateMap() - if err != nil { - r.Err = err - return - } - - url := updateURL(client, hostName) - if qOpts != nil { - query, _ := qOpts.ToUpdateQuery() - url += query - } - - _, r.Err = client.Put(url, &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/security_portal/v2/ha_ports/results.go b/v3/ecl/security_portal/v2/ha_ports/results.go deleted file mode 100644 index dd992f5..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/results.go +++ /dev/null @@ -1,69 +0,0 @@ -package ha_ports - -import ( - "encoding/json" - "strconv" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a Port resource. -func (r commonResult) Extract() (*UpdateProcess, error) { - var p UpdateProcess - err := r.ExtractInto(&p) - return &p, err -} - -// Extract interprets any commonResult as a Port if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Port. -type UpdateResult struct { - commonResult -} - -// UpdateProcess represents the result of a each element in -// response of port api result. -type UpdateProcess struct { - Message string `json:"message"` - ProcessID int `json:"processId"` - ID string `json:"-"` -} - -// ProcessPage is the page returned by a pager -// when traversing over a collection of Single Port. -type ProcessPage struct { - pagination.LinkedPageBase -} - -// UnmarshalJSON function overrides original functionality, -// to parse processId as unique identifier of process. -// Note: -// ID parameter in each struct must be string, -// but in api result of process polling API, -// processId is returned as integer value. -// This function solves this problem. -func (r *UpdateProcess) UnmarshalJSON(b []byte) error { - type tmp UpdateProcess - var s struct { - tmp - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = UpdateProcess(s.tmp) - - r.ID = strconv.Itoa(r.ProcessID) - - return err -} diff --git a/v3/ecl/security_portal/v2/ha_ports/testing/doc.go b/v3/ecl/security_portal/v2/ha_ports/testing/doc.go deleted file mode 100644 index 134142d..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains ports unit tests -package testing diff --git a/v3/ecl/security_portal/v2/ha_ports/testing/fixtures.go b/v3/ecl/security_portal/v2/ha_ports/testing/fixtures.go deleted file mode 100644 index d9a85e5..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/testing/fixtures.go +++ /dev/null @@ -1,29 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/ports" -) - -const updateRequest = `{ - "port": [ - { - "comment": "port 0 comment", - "enable_port":"true", - "ip_address": "192.168.1.50/24", - "mtu":"1500", - "network_id": "32314bd2-3583-4fb9-b622-9b121e04e007", - "subnet_id": "7fd77711-abae-4828-93f1-f3d682a8771f" - } - ] -}` - -const updateResponse = `{ - "message": "The process launch request has been accepted", - "processId": 85385 -}` - -var expectedResult = ports.UpdateProcess{ - Message: "The process launch request has been accepted", - ProcessID: 85385, - ID: "85385", -} diff --git a/v3/ecl/security_portal/v2/ha_ports/testing/requests_test.go b/v3/ecl/security_portal/v2/ha_ports/testing/requests_test.go deleted file mode 100644 index 525a65a..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/testing/requests_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/ports" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestUpdatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/ecl-api/ports/utm/CES11995" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, updateResponse) - }) - - updateOpts := ports.UpdateOpts{ - Port: []ports.SinglePort{ - { - Comment: "port 0 comment", - EnablePort: "true", - IPAddress: "192.168.1.50/24", - MTU: "1500", - NetworkID: "32314bd2-3583-4fb9-b622-9b121e04e007", - SubnetID: "7fd77711-abae-4828-93f1-f3d682a8771f", - }, - }, - } - - actual, err := ports.Update( - fakeclient.ServiceClient(), - "utm", - "CES11995", - updateOpts, - nil).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedResult, actual) -} diff --git a/v3/ecl/security_portal/v2/ha_ports/urls.go b/v3/ecl/security_portal/v2/ha_ports/urls.go deleted file mode 100644 index 3e54b13..0000000 --- a/v3/ecl/security_portal/v2/ha_ports/urls.go +++ /dev/null @@ -1,12 +0,0 @@ -package ha_ports - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func updateURL(client *eclcloud.ServiceClient, hostName string) string { - url := fmt.Sprintf("ecl-api/ports/utm/ha/%s", hostName) - return client.ServiceURL(url) -} diff --git a/v3/ecl/security_portal/v2/ports/doc.go b/v3/ecl/security_portal/v2/ports/doc.go deleted file mode 100644 index 6c06631..0000000 --- a/v3/ecl/security_portal/v2/ports/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package ports contains port management functionality in security portal API -package ports diff --git a/v3/ecl/security_portal/v2/ports/requests.go b/v3/ecl/security_portal/v2/ports/requests.go deleted file mode 100644 index 9428d5f..0000000 --- a/v3/ecl/security_portal/v2/ports/requests.go +++ /dev/null @@ -1,73 +0,0 @@ -package ports - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToPortUpdateMap() (map[string]interface{}, error) -} - -// SinglePort represents parameters to update a Single Port. -type SinglePort struct { - EnablePort string `json:"enable_port" required:"true"` - IPAddress string `json:"ip_address,omitempty"` - NetworkID string `json:"network_id,omitempty"` - SubnetID string `json:"subnet_id,omitempty"` - MTU string `json:"mtu,omitempty"` - Comment string `json:"comment,omitempty"` -} - -// UpdateOpts represents options used to update a port. -type UpdateOpts struct { - Port []SinglePort `json:"port" required:"true"` -} - -// ToPortUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// UpdateQueryOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateQueryOptsBuilder interface { - ToUpdateQuery() (string, error) -} - -// UpdateQueryOpts represents query strings for updating port. -type UpdateQueryOpts struct { - TenantID string `q:"tenantid"` - UserToken string `q:"usertoken"` -} - -// ToUpdateQuery formats a ListOpts into a query string. -func (opts UpdateQueryOpts) ToUpdateQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Update modifies the attributes of a port. -func Update(client *eclcloud.ServiceClient, - serviceType string, - hostName string, - opts UpdateOptsBuilder, - qOpts UpdateQueryOptsBuilder) (r UpdateResult) { - b, err := opts.ToPortUpdateMap() - if err != nil { - r.Err = err - return - } - - url := updateURL(client, serviceType, hostName) - if qOpts != nil { - query, _ := qOpts.ToUpdateQuery() - url += query - } - - _, r.Err = client.Put(url, &b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} diff --git a/v3/ecl/security_portal/v2/ports/results.go b/v3/ecl/security_portal/v2/ports/results.go deleted file mode 100644 index 1adf04f..0000000 --- a/v3/ecl/security_portal/v2/ports/results.go +++ /dev/null @@ -1,69 +0,0 @@ -package ports - -import ( - "encoding/json" - "strconv" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a Port resource. -func (r commonResult) Extract() (*UpdateProcess, error) { - var p UpdateProcess - err := r.ExtractInto(&p) - return &p, err -} - -// Extract interprets any commonResult as a Port if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Port. -type UpdateResult struct { - commonResult -} - -// UpdateProcess represents the result of a each element in -// response of port api result. -type UpdateProcess struct { - Message string `json:"message"` - ProcessID int `json:"processId"` - ID string `json:"-"` -} - -// ProcessPage is the page returned by a pager -// when traversing over a collection of Single Port. -type ProcessPage struct { - pagination.LinkedPageBase -} - -// UnmarshalJSON function overrides original functionality, -// to parse processId as unique identifier of process. -// Note: -// ID parameter in each struct must be string, -// but in api result of process polling API, -// processId is returned as integer value. -// This function solves this problem. -func (r *UpdateProcess) UnmarshalJSON(b []byte) error { - type tmp UpdateProcess - var s struct { - tmp - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = UpdateProcess(s.tmp) - - r.ID = strconv.Itoa(r.ProcessID) - - return err -} diff --git a/v3/ecl/security_portal/v2/ports/testing/doc.go b/v3/ecl/security_portal/v2/ports/testing/doc.go deleted file mode 100644 index 134142d..0000000 --- a/v3/ecl/security_portal/v2/ports/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains ports unit tests -package testing diff --git a/v3/ecl/security_portal/v2/ports/testing/fixtures.go b/v3/ecl/security_portal/v2/ports/testing/fixtures.go deleted file mode 100644 index d9a85e5..0000000 --- a/v3/ecl/security_portal/v2/ports/testing/fixtures.go +++ /dev/null @@ -1,29 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/ports" -) - -const updateRequest = `{ - "port": [ - { - "comment": "port 0 comment", - "enable_port":"true", - "ip_address": "192.168.1.50/24", - "mtu":"1500", - "network_id": "32314bd2-3583-4fb9-b622-9b121e04e007", - "subnet_id": "7fd77711-abae-4828-93f1-f3d682a8771f" - } - ] -}` - -const updateResponse = `{ - "message": "The process launch request has been accepted", - "processId": 85385 -}` - -var expectedResult = ports.UpdateProcess{ - Message: "The process launch request has been accepted", - ProcessID: 85385, - ID: "85385", -} diff --git a/v3/ecl/security_portal/v2/ports/testing/requests_test.go b/v3/ecl/security_portal/v2/ports/testing/requests_test.go deleted file mode 100644 index 525a65a..0000000 --- a/v3/ecl/security_portal/v2/ports/testing/requests_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/ports" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestUpdatePort(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := "/ecl-api/ports/utm/CES11995" - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusOK) - w.Header().Add("Content-Type", "application/json") - fmt.Fprint(w, updateResponse) - }) - - updateOpts := ports.UpdateOpts{ - Port: []ports.SinglePort{ - { - Comment: "port 0 comment", - EnablePort: "true", - IPAddress: "192.168.1.50/24", - MTU: "1500", - NetworkID: "32314bd2-3583-4fb9-b622-9b121e04e007", - SubnetID: "7fd77711-abae-4828-93f1-f3d682a8771f", - }, - }, - } - - actual, err := ports.Update( - fakeclient.ServiceClient(), - "utm", - "CES11995", - updateOpts, - nil).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedResult, actual) -} diff --git a/v3/ecl/security_portal/v2/ports/urls.go b/v3/ecl/security_portal/v2/ports/urls.go deleted file mode 100644 index 0d53d60..0000000 --- a/v3/ecl/security_portal/v2/ports/urls.go +++ /dev/null @@ -1,12 +0,0 @@ -package ports - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func updateURL(client *eclcloud.ServiceClient, deviceType string, hostName string) string { - url := fmt.Sprintf("ecl-api/ports/%s/%s", deviceType, hostName) - return client.ServiceURL(url) -} diff --git a/v3/ecl/security_portal/v2/processes/doc.go b/v3/ecl/security_portal/v2/processes/doc.go deleted file mode 100644 index 160ef42..0000000 --- a/v3/ecl/security_portal/v2/processes/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package process contains port management functionality on security -package processes diff --git a/v3/ecl/security_portal/v2/processes/requests.go b/v3/ecl/security_portal/v2/processes/requests.go deleted file mode 100644 index 913370f..0000000 --- a/v3/ecl/security_portal/v2/processes/requests.go +++ /dev/null @@ -1,35 +0,0 @@ -package processes - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// GetOptsBuilder allows extensions to add additional parameters to -// the order API request -type GetOptsBuilder interface { - ToProcessQuery() (string, error) -} - -// GetOpts represents result of order API response. -type GetOpts struct { - TenantID string `q:"tenantid"` - UserToken string `q:"usertoken"` -} - -// ToProcessQuery formats a GetOpts into a query string. -func (opts GetOpts) ToProcessQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Get retrieves details on a single order, by ID. -func Get(client *eclcloud.ServiceClient, processID string, opts GetOptsBuilder) (r GetResult) { - url := getURL(client, processID) - if opts != nil { - query, _ := opts.ToProcessQuery() - url += query - } - - _, r.Err = client.Get(url, &r.Body, nil) - return -} diff --git a/v3/ecl/security_portal/v2/processes/results.go b/v3/ecl/security_portal/v2/processes/results.go deleted file mode 100644 index c805e4e..0000000 --- a/v3/ecl/security_portal/v2/processes/results.go +++ /dev/null @@ -1,36 +0,0 @@ -package processes - -import ( - "github.com/nttcom/eclcloud/v3" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a Process. -func (r commonResult) Extract() (*ProcessInstance, error) { - var pr ProcessInstance - err := r.ExtractInto(&pr) - return &pr, err -} - -// Extract interprets any commonResult as a Process, if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "processInstance") -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Process. -type GetResult struct { - commonResult -} - -type ProcessStatus struct { - Status string `json:"status"` -} - -type ProcessInstance struct { - Status ProcessStatus `json:"status"` -} diff --git a/v3/ecl/security_portal/v2/processes/testing/doc.go b/v3/ecl/security_portal/v2/processes/testing/doc.go deleted file mode 100644 index d64fb4a..0000000 --- a/v3/ecl/security_portal/v2/processes/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains processes unit tests -package testing diff --git a/v3/ecl/security_portal/v2/processes/testing/fixtures.go b/v3/ecl/security_portal/v2/processes/testing/fixtures.go deleted file mode 100644 index 5c48802..0000000 --- a/v3/ecl/security_portal/v2/processes/testing/fixtures.go +++ /dev/null @@ -1,186 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/processes" -) - -const processID = "85385" - -const getResponse = ` -{ - "processInstance": { - "processId": { - "id": 85385, - "lastExecNumber": 1, - "name": "ntt/FortiVA_Port_Management/Process_Manage_UTM_Interfaces/Process_Manage_UTM_Interfaces", - "submissionType": "RUN" - }, - "serviceId": { - "id": 19382, - "name": "FortiVA_Port_Management", - "serviceReference": "PORT_MNGT_CES11892", - "state": null - }, - "status": { - "comment": "Ping Monitoring started for the device 11892.", - "duration": 0, - "endingDate": "2019-07-26 04:34:56.0", - "execNumber": 1, - "processInstanceId": 85385, - "processName": "ntt/FortiVA_Port_Management/Process_Manage_UTM_Interfaces/Process_Manage_UTM_Interfaces", - "startingDate": "2019-07-26 04:24:45.0", - "status": "RUNNING", - "taskStatusList": [ - { - "comment": "IP Address inputs verified successfully.", - "endingDate": "2019-07-26 04:24:48.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:24:45.0", - "status": "ENDED", - "taskId": 1, - "taskName": "Verify IP Address, MTU Inputs" - }, - { - "comment": "Ping Monitoring stopped for the device 11892.", - "endingDate": "2019-07-26 04:26:49.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:24:48.0", - "status": "ENDED", - "taskId": 2, - "taskName": "Stop Ping Monitoring" - }, - { - "comment": "Openstack Server 158eb01a-8d45-45c8-a9ff-1fba8f1ab7e3 stopped successfully.\nServer Status : SHUTOFF\nTask State : -\nPower State : Shutdown\n", - "endingDate": "2019-07-26 04:27:03.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:26:49.0", - "status": "ENDED", - "taskId": 3, - "taskName": "Stop the UTM" - }, - { - "comment": "IP Address 100.76.96.230 is now unreachable from MSA.\nPING Status : Destination Host Unreachable\n", - "endingDate": "2019-07-26 04:27:13.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:27:03.0", - "status": "ENDED", - "taskId": 4, - "taskName": "Wait for UTM Ping unreachability from MSA" - }, - { - "comment": "Ports deleted successfully.", - "endingDate": "2019-07-26 04:28:29.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:27:13.0", - "status": "ENDED", - "taskId": 5, - "taskName": "Delete Ports" - }, - { - "comment": "Ports created successfully.\nPort Id : 34c7389d-1428-4f98-a37c-9c2e32aab255\nPort Id : 3d09053b-fad8-45c4-bf71-501c0fc2b58a\nPort Id : 0262d90c-6056-4308-8b76-8e851f0132f5\nPort Id : 5fcabdf2-8a20-4337-bd10-02f5c5000ca1\nPort Id : 53211b09-f82b-40d5-bf5b-7289a298cbdf\nPort Id : 9ce2d3b7-7ae0-400d-8e41-16dc9b94f95e\nPort Id : a36493fe-43d2-4dc1-a39e-c96898e9c0be\n", - "endingDate": "2019-07-26 04:29:50.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:28:29.0", - "status": "ENDED", - "taskId": 6, - "taskName": "Create Ports" - }, - { - "comment": "Ports attached successfully to the Server 158eb01a-8d45-45c8-a9ff-1fba8f1ab7e3.", - "endingDate": "2019-07-26 04:31:33.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:29:50.0", - "status": "ENDED", - "taskId": 7, - "taskName": "Attach Ports" - }, - { - "comment": "Openstack Server 158eb01a-8d45-45c8-a9ff-1fba8f1ab7e3 started successfully.\nServer Status : ACTIVE\nTask State : -\nPower State : Running\n", - "endingDate": "2019-07-26 04:31:47.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:31:33.0", - "status": "ENDED", - "taskId": 8, - "taskName": "Start the UTM" - }, - { - "comment": "IP Address 100.76.96.230 is now reachable from MSA.\nPING Status : OK\n", - "endingDate": "2019-07-26 04:32:30.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:31:47.0", - "status": "ENDED", - "taskId": 9, - "taskName": "Wait for UTM Ping reachability from MSA" - }, - { - "comment": "OK LICENSE IS VALID", - "endingDate": "2019-07-26 04:32:56.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:32:30.0", - "status": "ENDED", - "taskId": 10, - "taskName": "Verify License Validity" - }, - { - "comment": "Ports updated successfully on Fortigate Device 11892.\n", - "endingDate": "2019-07-26 04:33:17.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:32:56.0", - "status": "ENDED", - "taskId": 11, - "taskName": "Update UTM" - }, - { - "comment": "Device 11892 Backup completed successfully.\nBackup Status : ENDED\nBackup Message : BACKUP processed\n\nBackup Revision Id : 209408\n", - "endingDate": "2019-07-26 04:33:28.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:33:17.0", - "status": "ENDED", - "taskId": 12, - "taskName": "Device Backup" - }, - { - "comment": "Ping Monitoring started for the device 11892.", - "endingDate": "2019-07-26 04:34:56.0", - "execNumber": 1, - "newParameters": {}, - "processInstanceId": 85385, - "startingDate": "2019-07-26 04:33:28.0", - "status": "ENDED", - "taskId": 13, - "taskName": "Start Ping Monitoring" - } - ] - } - } -}` - -var expectedProcess = processes.ProcessInstance{ - Status: processes.ProcessStatus{ - Status: "RUNNING", - }, -} diff --git a/v3/ecl/security_portal/v2/processes/testing/requests_test.go b/v3/ecl/security_portal/v2/processes/testing/requests_test.go deleted file mode 100644 index 6bee009..0000000 --- a/v3/ecl/security_portal/v2/processes/testing/requests_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/security_portal/v2/processes" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestGetProcess(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/ecl-api/process/%s/status", processID) - fmt.Println(url) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := processes.Get(fakeclient.ServiceClient(), processID, nil).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &expectedProcess, actual) -} diff --git a/v3/ecl/security_portal/v2/processes/urls.go b/v3/ecl/security_portal/v2/processes/urls.go deleted file mode 100644 index deb93d7..0000000 --- a/v3/ecl/security_portal/v2/processes/urls.go +++ /dev/null @@ -1,12 +0,0 @@ -package processes - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, processID string) string { - url := fmt.Sprintf("ecl-api/process/%s/status", processID) - return client.ServiceURL(url) -} diff --git a/v3/ecl/sss/v2/approval_requests/doc.go b/v3/ecl/sss/v2/approval_requests/doc.go deleted file mode 100644 index 49196e5..0000000 --- a/v3/ecl/sss/v2/approval_requests/doc.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Package approval_requests manages and retrieves approval requests in the Enterprise Cloud. - -Example to List approval requests - - allPages, err := approval_requests.List(client).AllPages() - if err != nil { - panic(err) - } - - allApprovalRequests, err := approval_requests.ExtractApprovalRequests(allPages) - if err != nil { - panic(err) - } - - for _, approvalRequest := range allApprovalRequests { - fmt.Printf("%+v\n", approvalRequest) - } - -Example to Get an approval requests - - requestID := "02471b45-3de0-4fc8-8469-a7cc52c378df" - - approvalRequest, err := approval_requests.Get(client, requestID).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", approvalRequest) - -Example to Update an approval request - - requestID := "02471b45-3de0-4fc8-8469-a7cc52c378df" - updateOpts := approval_requests.UpdateOpts{ - Status: "approved", - } - - result := approval_requests.Update(client, requestID, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -*/ -package approval_requests diff --git a/v3/ecl/sss/v2/approval_requests/requests.go b/v3/ecl/sss/v2/approval_requests/requests.go deleted file mode 100644 index 5b16446..0000000 --- a/v3/ecl/sss/v2/approval_requests/requests.go +++ /dev/null @@ -1,77 +0,0 @@ -package approval_requests - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToApprovalRequestListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the approval request attributes you want to see returned. -type ListOpts struct { - Status string `q:"status"` - Service string `q:"service"` -} - -// ToApprovalRequestListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToApprovalRequestListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List retrieves a list of approval requests. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToApprovalRequestListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return ApprovalRequestPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details of an approval request. -func Get(client *eclcloud.ServiceClient, name string) (r GetResult) { - _, r.Err = client.Get(getURL(client, name), &r.Body, nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToResourceUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update an approval request. -type UpdateOpts struct { - Status string `json:"status" required:"true"` -} - -// ToResourceUpdateMap formats a UpdateOpts to update approval request. -func (opts UpdateOpts) ToResourceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of an approval request. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToResourceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) - return -} diff --git a/v3/ecl/sss/v2/approval_requests/results.go b/v3/ecl/sss/v2/approval_requests/results.go deleted file mode 100644 index 4dc4275..0000000 --- a/v3/ecl/sss/v2/approval_requests/results.go +++ /dev/null @@ -1,95 +0,0 @@ -package approval_requests - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type Action struct { - Service string `json:"service"` - Region string `json:"region"` - APIPath string `json:"api_path"` - Method string `json:"method"` - // Basically JSON is passed to Action.Body, - // but depending on the value of the service, it may be a String, so it is set to interface{}. - // If service is "provider-connectivity", body's type is JSON. - // If service is "network", body's type is String. - Body interface{} `json:"body"` -} - -type Description struct { - Lang string `json:"lang"` - Text string `json:"text"` -} - -// ApprovalRequest represents an ECL SSS Approval Request. -type ApprovalRequest struct { - RequestID string `json:"request_id"` - ExternalRequestID string `json:"external_request_id"` - ApproverType string `json:"approver_type"` - ApproverID string `json:"approver_id"` - RequestUserID string `json:"request_user_id"` - Service string `json:"service"` - Actions []Action `json:"actions"` - Descriptions []Description `json:"descriptions"` - RequestUser interface{} `json:"request_user"` - Approver bool `json:"approver"` - ApprovalDeadLine interface{} `json:"approval_deadline"` - ApprovalExpire interface{} `json:"approval_expire"` - RegisteredTime interface{} `json:"registered_time"` - UpdatedTime interface{} `json:"updated_time"` - Status string `json:"status"` -} - -type commonResult struct { - eclcloud.Result -} - -func (r commonResult) Extract() (*ApprovalRequest, error) { - var ar ApprovalRequest - err := r.ExtractInto(&ar) - return &ar, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "") -} - -// GetResult is the response from a Get operation. Call its Extract method -// to interpret it as an approval request. -type GetResult struct { - commonResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as an approval request. -type UpdateResult struct { - commonResult -} - -// ApprovalRequestPage is a single page of approval request results. -type ApprovalRequestPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of approval requests contains any results. -func (r ApprovalRequestPage) IsEmpty() (bool, error) { - resources, err := ExtractApprovalRequests(r) - return len(resources) == 0, err -} - -// ExtractApprovalRequests returns a slice of approval requests -// contained in a single page of results. -func ExtractApprovalRequests(r pagination.Page) ([]ApprovalRequest, error) { - var s struct { - ApprovalRequests []ApprovalRequest `json:"approval_requests"` - } - err := (r.(ApprovalRequestPage)).ExtractInto(&s) - return s.ApprovalRequests, err -} - -// ExtractApprovalRequestsInto interprets the results of a single page from a List() call, -// producing a slice of Approval Request entities. -func ExtractApprovalRequestsInto(r pagination.Page, v interface{}) error { - return r.(ApprovalRequestPage).Result.ExtractIntoSlicePtr(v, "") -} diff --git a/v3/ecl/sss/v2/approval_requests/testing/doc.go b/v3/ecl/sss/v2/approval_requests/testing/doc.go deleted file mode 100644 index c513bc0..0000000 --- a/v3/ecl/sss/v2/approval_requests/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// sss approval request unit tests -package testing diff --git a/v3/ecl/sss/v2/approval_requests/testing/fixtures.go b/v3/ecl/sss/v2/approval_requests/testing/fixtures.go deleted file mode 100644 index f0c0315..0000000 --- a/v3/ecl/sss/v2/approval_requests/testing/fixtures.go +++ /dev/null @@ -1,203 +0,0 @@ -package testing - -import ( - "fmt" - - ar "github.com/nttcom/eclcloud/v3/ecl/sss/v2/approval_requests" -) - -const idApprovalRequest1 = "9a76dca6-d8cd-4391-aac6f-2ea052f10f4" -const idApprovalRequest2 = "fc578e8b-dea2-4f8c-aa7e-9026fa173632" - -var listResponse = fmt.Sprintf(` -{ - "approval_requests": [ - { - "request_id": "%s", - "external_request_id": "test007", - "approver_type":"tenant_owner", - "approver_id":"11a98bf9cb144af5a204c9da566d2bd0", - "request_user_id":"ecid9999888881", - "service":"provider-connectivity", - "actions" : [ - { - "service": "provider-connectivity", - "region": "jp1", - "api_path": "/v2.0/tenant_connections_requests", - "method": "POST", - "body": { - "tenant_connection_request": { - "tenant_id_other": "d2f19c353e6d4c519e530c6a78438b33", - "network_id": "ea7eea8c-0d91-4553-9ecb-01f81e2c3989" - } - } - } - ], - "descriptions": [ - { - "lang": "en", - "text": "approval request test" - } - ], - "request_user": false, - "approver": true, - "approval_deadline": "2017-02-05 09:45:22", - "approval_expire": null, - "registered_time": "2017-01-31 07:43:13", - "updated_time": null, - "status": "registered" - }, - { - "request_id": "%s", - "external_request_id": "test006", - "approver_type":"tenant_owner", - "approver_id":"66a98bf9cb1238192a204c9da566dbd0", - "request_user_id":"ecid9999888882", - "service":"network", - "actions" : [ - { - "service": "network", - "region": "jp1", - "api_path": "/network/v1/firewall", - "method": "POST", - "body": "{\n\t\"firewall\": {\n\t\t\"availability_zone\": \"zone1-groupa\",\n\t\t\"default_gateway\": \"\",\n\t\t\"description\": \"abcdefghijklmnopqrstuvwxyz\",\n\t\t\"firewall_plan_id\": \"bd12784a-c66e-4f13-9f72-5143d64762b6\",\n\t\t\"name\": \"abcdefghijklmnopqrstuvwxyz\",\n\t\t\"tenant_id\": \"6a156ddf2ecd497ca786ff2da6df5aa8\"\n\t}\n}" - } - ], - "descriptions": [ - { - "lang": "en", - "text": "approval request test" - } - ], - "request_user": false, - "approver": true, - "approval_deadline": "2016-12-25 09:45:22", - "approval_expire": null, - "registered_time": "2016-12-13 02:20:21", - "updated_time": null, - "status": "expired" - } - ] -} -`, - idApprovalRequest1, - idApprovalRequest2, -) - -var expectedApprovalRequestsSlice = []ar.ApprovalRequest{ - firstApprovalRequest, - secondApprovalRequest, -} - -var firstApprovalRequest = ar.ApprovalRequest{ - RequestID: idApprovalRequest1, - ExternalRequestID: "test007", - ApproverType: "tenant_owner", - ApproverID: "11a98bf9cb144af5a204c9da566d2bd0", - RequestUserID: "ecid9999888881", - Service: "provider-connectivity", - Actions: []ar.Action{ - { - Service: "provider-connectivity", - Region: "jp1", - APIPath: "/v2.0/tenant_connections_requests", - Method: "POST", - Body: map[string]interface{}{ - "tenant_connection_request": map[string]string{ - "tenant_id_other": "d2f19c353e6d4c519e530c6a78438b33", - "network_id": "ea7eea8c-0d91-4553-9ecb-01f81e2c3989", - }, - }, - }, - }, - Descriptions: []ar.Description{ - { - Lang: "en", - Text: "approval request test", - }, - }, - RequestUser: false, - Approver: true, - ApprovalDeadLine: interface{}("2017-02-05 09:45:22"), - ApprovalExpire: interface{}(nil), - RegisteredTime: interface{}("2017-01-31 07:43:13"), - UpdatedTime: interface{}(nil), - Status: "registered", -} - -var secondApprovalRequest = ar.ApprovalRequest{ - RequestID: idApprovalRequest2, - ExternalRequestID: "test006", - ApproverType: "tenant_owner", - ApproverID: "66a98bf9cb1238192a204c9da566dbd0", - RequestUserID: "ecid9999888882", - Service: "network", - Actions: []ar.Action{ - { - Service: "network", - Region: "jp1", - APIPath: "/network/v1/firewall", - Method: "POST", - Body: "{\n\t\"firewall\": {\n\t\t\"availability_zone\": \"zone1-groupa\",\n\t\t\"default_gateway\": \"\",\n\t\t\"description\": \"abcdefghijklmnopqrstuvwxyz\",\n\t\t\"firewall_plan_id\": \"bd12784a-c66e-4f13-9f72-5143d64762b6\",\n\t\t\"name\": \"abcdefghijklmnopqrstuvwxyz\",\n\t\t\"tenant_id\": \"6a156ddf2ecd497ca786ff2da6df5aa8\"\n\t}\n}", - }, - }, - Descriptions: []ar.Description{ - { - Lang: "en", - Text: "approval request test", - }, - }, - RequestUser: false, - Approver: true, - ApprovalDeadLine: interface{}("2016-12-25 09:45:22"), - ApprovalExpire: interface{}(nil), - RegisteredTime: interface{}("2016-12-13 02:20:21"), - UpdatedTime: interface{}(nil), - Status: "expired", -} - -var getResponse = fmt.Sprintf(` - { - "request_id": "%s", - "external_request_id": "test007", - "approver_type":"tenant_owner", - "approver_id":"11a98bf9cb144af5a204c9da566d2bd0", - "request_user_id":"ecid9999888881", - "service":"provider-connectivity", - "actions" : [ - { - "service": "provider-connectivity", - "region": "jp1", - "api_path": "/v2.0/tenant_connections_requests", - "method": "POST", - "body": { - "tenant_connection_request": { - "tenant_id_other": "d2f19c353e6d4c519e530c6a78438b33", - "network_id": "ea7eea8c-0d91-4553-9ecb-01f81e2c3989" - } - } - } - ], - "descriptions": [ - { - "lang": "en", - "text": "approval request test" - } - ], - "request_user": false, - "approver": true, - "approval_deadline": "2017-02-05 09:45:22", - "approval_expire": null, - "registered_time": "2017-01-31 07:43:13", - "updated_time": null, - "status": "registered" - } -`, - idApprovalRequest1, -) - -const updateRequest = ` -{ - "status": "approved" -} -` diff --git a/v3/ecl/sss/v2/approval_requests/testing/requests_test.go b/v3/ecl/sss/v2/approval_requests/testing/requests_test.go deleted file mode 100644 index 8f09e91..0000000 --- a/v3/ecl/sss/v2/approval_requests/testing/requests_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - ar "github.com/nttcom/eclcloud/v3/ecl/sss/v2/approval_requests" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListApprovalRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/approval-requests", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := ar.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := ar.ExtractApprovalRequests(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedApprovalRequestsSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListApprovalRequestAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/approval-requests", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := ar.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allRequests, err := ar.ExtractApprovalRequests(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allRequests)) -} - -func TestGetApprovalRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/approval-requests/%s", idApprovalRequest1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := ar.Get(fakeclient.ServiceClient(), idApprovalRequest1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &firstApprovalRequest, actual) -} - -func TestUpdateApprovalRequest(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/approval-requests/%s", idApprovalRequest1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusNoContent) - }) - - updateOpts := ar.UpdateOpts{ - Status: "approved", - } - - res := ar.Update(fakeclient.ServiceClient(), idApprovalRequest1, updateOpts) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/sss/v2/approval_requests/urls.go b/v3/ecl/sss/v2/approval_requests/urls.go deleted file mode 100644 index 80acd40..0000000 --- a/v3/ecl/sss/v2/approval_requests/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package approval_requests - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("approval-requests") -} - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("approval-requests", id) -} - -func updateURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("approval-requests", id) -} diff --git a/v3/ecl/sss/v2/tenants/doc.go b/v3/ecl/sss/v2/tenants/doc.go deleted file mode 100644 index e11b7ff..0000000 --- a/v3/ecl/sss/v2/tenants/doc.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Package tenants manages and retrieves Projects in the ECL SSS Service. - -Example to List Tenants - - listOpts := tenants.ListOpts{} - - allPages, err := tenants.List(identityClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allTenants, err := tenants.ExtractProjects(allPages) - if err != nil { - panic(err) - } - - for _, tenant := range allTenants { - fmt.Printf("%+v\n", tenant) - } - -Example to Create a Tenant - - createOpts := projects.CreateOpts{ - Name: "tenant_name", - Description: "Tenant Description" - } - - tenant, err := tenants.Create(identityClient, createOpts).Extract() - if err != nil { - panic(err) - } -*/ -package tenants diff --git a/v3/ecl/sss/v2/tenants/errors.go b/v3/ecl/sss/v2/tenants/errors.go deleted file mode 100644 index 08cfa34..0000000 --- a/v3/ecl/sss/v2/tenants/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package tenants - -import "fmt" - -// InvalidListFilter is returned by the ToUserListQuery method when validation of -// a filter does not pass -type InvalidListFilter struct { - FilterName string -} - -func (e InvalidListFilter) Error() string { - s := fmt.Sprintf( - "Invalid filter name [%s]: it must be in format of NAME__COMPARATOR", - e.FilterName, - ) - return s -} diff --git a/v3/ecl/sss/v2/tenants/requests.go b/v3/ecl/sss/v2/tenants/requests.go deleted file mode 100644 index 21c9117..0000000 --- a/v3/ecl/sss/v2/tenants/requests.go +++ /dev/null @@ -1,74 +0,0 @@ -package tenants - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToTenantListQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -// Currently SSS Tenant API does not support any of query parameters. -type ListOpts struct { -} - -// ToTenantListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToTenantListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the Projects to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToTenantListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return TenantPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single tenant, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToTenantCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a tenant. -type CreateOpts struct { - // Workspace ID. - WorkspaceID string `json:"workspace_id" required:"true"` - // TenantRegion of the tenant. - TenantRegion string `json:"region" required:"true"` -} - -// ToTenantCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToTenantCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new Project. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToTenantCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, nil) - return -} diff --git a/v3/ecl/sss/v2/tenants/results.go b/v3/ecl/sss/v2/tenants/results.go deleted file mode 100644 index 8f9d03f..0000000 --- a/v3/ecl/sss/v2/tenants/results.go +++ /dev/null @@ -1,130 +0,0 @@ -package tenants - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type tenantResult struct { - eclcloud.Result -} - -// GetResult is the result of a Get request. Call its Extract method to -// interpret it as a Tenant. -type GetResult struct { - tenantResult -} - -// CreateResult is the result of a Create request. Call its Extract method to -// interpret it as a Tenant. -type CreateResult struct { - tenantResult -} - -// Tenant represents an ECL SSS Tenant. -type Tenant struct { - // ID of contract which owns these tenants. - ContractID string `json:"contract_id"` - // ID is the unique ID of the tenant. - TenantID string `json:"tenant_id"` - // Name of the tenant. - TenantName string `json:"tenant_name"` - // Description of the tenant. - Description string `json:"description"` - // TenantRegion the tenant belongs. - TenantRegion string `json:"region"` - // Time that the tenant is created. - StartTime time.Time `json:"-"` - // SSS API endpoint for the region. - RegionApiEndpoint string `json:"region_api_endpoint"` - // Users information who have access to this tenant. - User []User `json:"users"` - // Brand ID which this tenant belongs. (ex. ecl2) - BrandID string `json:"brand_id"` - // Workspace ID of the tenant. - WorkspaceID string `json:"workspace_id"` -} - -type User struct { - // ID of the users who have access to this tenant. - UserID string `json:"user_id"` - // Contract which owns the tenant. - ContractID string `json:"contract_id"` - // This user is contract owner / or not. - ContractOwner bool `json:"contract_owner"` -} - -// UnmarshalJSON creates JSON format of tenant -func (r *Tenant) UnmarshalJSON(b []byte) error { - type tmp Tenant - var s struct { - tmp - StartTime eclcloud.JSONRFC3339ZNoTNoZ `json:"start_time"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Tenant(s.tmp) - - r.StartTime = time.Time(s.StartTime) - - return err -} - -// TenantPage is a single page of Tenant results. -type TenantPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Tenants contains any results. -func (r TenantPage) IsEmpty() (bool, error) { - tenants, err := ExtractTenants(r) - return len(tenants) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r TenantPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractTenants returns a slice of Tenants contained in a single page of -// results. -func ExtractTenants(r pagination.Page) ([]Tenant, error) { - var s struct { - ContractID string `json:"contract_id"` - Tenants []Tenant `json:"tenants"` - } - - // In list response case, each json element does not have contract_id. - // It is set at out layer of each element. - // So following logic set contract_id into inside of tenants slice forcibly. - // In "show(get with ID of tenant)" case, this does not occur. - err := (r.(TenantPage)).ExtractInto(&s) - contractID := s.ContractID - - for i := 0; i < len(s.Tenants); i++ { - s.Tenants[i].ContractID = contractID - } - return s.Tenants, err -} - -// Extract interprets any projectResults as a Tenant. -func (r tenantResult) Extract() (*Tenant, error) { - var s *Tenant - err := r.ExtractInto(&s) - return s, err -} diff --git a/v3/ecl/sss/v2/tenants/testing/doc.go b/v3/ecl/sss/v2/tenants/testing/doc.go deleted file mode 100644 index 020c8c3..0000000 --- a/v3/ecl/sss/v2/tenants/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// sss tenant unit tests -package testing diff --git a/v3/ecl/sss/v2/tenants/testing/fixtures.go b/v3/ecl/sss/v2/tenants/testing/fixtures.go deleted file mode 100644 index 93d981d..0000000 --- a/v3/ecl/sss/v2/tenants/testing/fixtures.go +++ /dev/null @@ -1,160 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/tenants" -) - -const contractID = "econ8000008888" - -const workspaceID1 = "ws0000000001" -const workspaceID2 = "ws0000000002" - -const idTenant1 = "9a76dca6d8cd4391aac6f2ea052f10f4" -const idTenant2 = "27a58d42769141ff8e94920a99aeb44b" - -const nameTenant1 = "jp1_tenant01" -const nameTenant2 = "jp1_tenant02" - -const descriptionTenant1 = "jp1 tenant01" -const descriptionTenant2 = "jp1 tenant02" - -const startTime = "2018-07-26 08:40:01" - -// ListResponse is a sample response to a List call. -var ListResponse = fmt.Sprintf(` -{ - "contract_id": "%s", - "tenants": [{ - "tenant_id": "%s", - "tenant_name": "%s", - "description": "%s", - "region": "jp1", - "start_time": "%s", - "workspace_id": "%s" - }, { - "tenant_id": "%s", - "tenant_name": "%s", - "description": "%s", - "region": "jp2", - "start_time": "%s", - "workspace_id": "%s" - }] -} -`, - contractID, - // fot tenant 1 - idTenant1, - nameTenant1, - descriptionTenant1, - startTime, - workspaceID1, - // for tenant 2 - idTenant2, - nameTenant2, - descriptionTenant2, - startTime, - workspaceID2, -) - -// ExpectedTenantsSlice is the slice of results that should be parsed -// from ListResponse in the expected order. -var ExpectedTenantsSlice = []tenants.Tenant{FirstTenant, SecondTenant} - -// TenantStartTime is parsed tenant start time -var TenantStartTime, _ = time.Parse(eclcloud.RFC3339ZNoTNoZ, startTime) - -// FirstTenant is the mock object of expected tenant-1 -var FirstTenant = tenants.Tenant{ - ContractID: contractID, - TenantID: idTenant1, - TenantName: nameTenant1, - Description: descriptionTenant1, - TenantRegion: "jp1", - StartTime: TenantStartTime, - WorkspaceID: workspaceID1, -} - -// SecondTenant is the mock object of expected tenant-2 -var SecondTenant = tenants.Tenant{ - ContractID: contractID, - TenantID: idTenant2, - TenantName: nameTenant2, - Description: descriptionTenant2, - TenantRegion: "jp2", - StartTime: TenantStartTime, - WorkspaceID: workspaceID2, -} - -// GetResponse is a sample response to a Get call. -// This get result does not have action, attributes in ECL2.0 -var GetResponse = fmt.Sprintf(` -{ - "tenant_id": "%s", - "tenant_name": "%s", - "description": "%s", - "region": "jp1", - "contract_id": "%s", - "region_api_endpoint": "https://example.com:443/api", - "start_time": "%s", - "users": [{ - "user_id": "ecid8000008888", - "contract_id": "%s", - "contract_owner": true - }], - "brand_id": "ecl2", - "workspace_id": "%s" -}`, idTenant1, - nameTenant1, - descriptionTenant1, - contractID, - startTime, - contractID, - workspaceID1, -) - -// GetResponseStruct mocked actual tenant -var GetResponseStruct = tenants.Tenant{ - ContractID: contractID, - TenantID: idTenant1, - TenantName: nameTenant1, - Description: descriptionTenant1, - TenantRegion: "jp1", - StartTime: TenantStartTime, - RegionApiEndpoint: "https://example.com:443/api", - User: []tenants.User{ - { - UserID: "ecid8000008888", - ContractID: contractID, - ContractOwner: true, - }, - }, - BrandID: "ecl2", - WorkspaceID: workspaceID1, -} - -// CreateRequest is a sample request to create a tenant. -var CreateRequest = fmt.Sprintf(`{ - "workspace_id": "%s", - "region": "jp1" -}`, - workspaceID1, -) - -// CreateResponse is a sample response to a create request. -var CreateResponse = fmt.Sprintf(`{ - "workspace_id": "%s", - "tenant_id": "%s", - "tenant_name": "%s", - "description": "%s", - "region": "jp1", - "contract_id": "%s" -}`, workspaceID1, - idTenant1, - nameTenant1, - descriptionTenant1, - contractID, -) diff --git a/v3/ecl/sss/v2/tenants/testing/requests_test.go b/v3/ecl/sss/v2/tenants/testing/requests_test.go deleted file mode 100644 index 61e630e..0000000 --- a/v3/ecl/sss/v2/tenants/testing/requests_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/tenants" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListResponse) - }) - - count := 0 - err := tenants.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := tenants.ExtractTenants(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, ExpectedTenantsSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListTenantAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, ListResponse) - }) - - allPages, err := tenants.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allZones, err := tenants.ExtractTenants(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allZones)) -} - -func TestGetTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/tenants/%s", idTenant1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, GetResponse) - }) - - actual, err := tenants.Get(fakeclient.ServiceClient(), idTenant1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &GetResponseStruct, actual) -} - -func TestCreateTenant(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, CreateRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, CreateResponse) - }) - - createOpts := tenants.CreateOpts{ - WorkspaceID: workspaceID1, - TenantRegion: "jp1", - } - - // clone FirstTenant into createdTenant(Used as assertion target) - // and initialize StartTime - createdTenant := FirstTenant - createdTenant.StartTime = time.Time{} - - actual, err := tenants.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdTenant, actual) -} diff --git a/v3/ecl/sss/v2/tenants/urls.go b/v3/ecl/sss/v2/tenants/urls.go deleted file mode 100644 index df7938f..0000000 --- a/v3/ecl/sss/v2/tenants/urls.go +++ /dev/null @@ -1,15 +0,0 @@ -package tenants - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenants") -} - -func getURL(client *eclcloud.ServiceClient, tenantID string) string { - return client.ServiceURL("tenants", tenantID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("tenants") -} diff --git a/v3/ecl/sss/v2/users/doc.go b/v3/ecl/sss/v2/users/doc.go deleted file mode 100644 index b38d0fe..0000000 --- a/v3/ecl/sss/v2/users/doc.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Package users contains user management functionality on SSS. - -Example to List users - - listOpts := users.ListOpts{} - - allPages, err := users.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allUsers, err := users.ExtractUsers(allPages) - if err != nil { - panic(err) - } - - for _, user := range allUsers { - fmt.Printf("%+v\n", user) - } - -Example to Get a user - - id := "ecid0000000001" - user, err := users.Get(client, id).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", user) - -Example to Create a user - - createOpts := users.CreateOpts{ - LoginID: "sample", - MailAddress: "example@example.com", - Password: "Passw0rd", - NotifyPassword: "true", - } - - user, err := users.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a user - - userID := "ecid0000000001" - loginID := "login-id-update" - mailAddress := "update@example.com" - newPassword := "NewPassw0rd" - - updateOpts := users.UpdateOpts{ - LoginID: &loginID, - MailAddress: &mailAddress, - NewPassword: &newPassword, - } - - result := users.Update(client, userID, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a user - - userID := "ecid0000000001" - res := users.Delete(client, userID) - if res.Err != nil { - panic(res.Err) - } - -*/ -package users diff --git a/v3/ecl/sss/v2/users/requests.go b/v3/ecl/sss/v2/users/requests.go deleted file mode 100644 index 5319448..0000000 --- a/v3/ecl/sss/v2/users/requests.go +++ /dev/null @@ -1,132 +0,0 @@ -package users - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToUserListQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -// Currently SSS User API does not support any of query parameters. -type ListOpts struct { -} - -// ToUserListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToUserListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the Users to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToUserListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return UserPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single user, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to -// the Create request. -type CreateOptsBuilder interface { - ToUserCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a user. -type CreateOpts struct { - // Login id of new user. - LoginID string `json:"login_id" required:"true"` - - // Mail address of new user. - MailAddress string `json:"mail_address" required:"true"` - - // Initial password of new user. - // If this parameter is not designated, - // random initial password is generated and applied to new user. - Password string `json:"password,omitempty"` - - // If this flag is set 'true', notification e-mail will be sent to new user's email. - NotifyPassword string `json:"notify_password" required:"true"` -} - -// ToUserCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new user. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToUserCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, nil) - return -} - -// Delete deletes a user. -func Delete(client *eclcloud.ServiceClient, userID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, userID), nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to -// the Update request. -type UpdateOptsBuilder interface { - ToUserUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a user. -type UpdateOpts struct { - // New login id of the user. - LoginID *string `json:"login_id" required:"true"` - - // New email address of the user - MailAddress *string `json:"mail_address" required:"true"` - - // New password of the user - NewPassword *string `json:"new_password" required:"true"` -} - -// ToUserUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToUserUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of a user. -// SSS User PUT API does not have response body, -// so set JSONResponse option as nil. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToUserUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put( - updateURL(client, id), - b, - nil, - &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }, - ) - return -} diff --git a/v3/ecl/sss/v2/users/results.go b/v3/ecl/sss/v2/users/results.go deleted file mode 100644 index 25d645f..0000000 --- a/v3/ecl/sss/v2/users/results.go +++ /dev/null @@ -1,128 +0,0 @@ -package users - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type userResult struct { - eclcloud.Result -} - -// GetResult is the result of a Get request. Call its Extract method to -// interpret it as a User. -type GetResult struct { - userResult -} - -// CreateResult is the result of a Create request. Call its Extract method to -// interpret it as a User. -type CreateResult struct { - userResult -} - -// DeleteResult is the result of a Delete request. Call its ExtractErr method to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a User. -type UpdateResult struct { - userResult -} - -// User represents an ECL SSS User. -type User struct { - LoginID string `json:"login_id"` - MailAddress string `json:"mail_address"` - UserID string `json:"user_id"` - ContractOwner bool `json:"contract_owner"` - Superuser bool `json:"super_user"` - ApiAvailability bool `json:"api_availability"` - KeystoneName string `json:"keystone_name"` - KeystoneEndpoint string `json:"keystone_endpoint"` - SSSEndpoint string `json:"sss_endpoint"` - ContractID string `json:"contract_id"` - LoginIntegration string `json:"login_integration"` - ExternalReferenceID string `json:"external_reference_id"` - BrandID string `json:"brand_id"` - OtpActivation bool `json:"otp_activation"` - StartTime time.Time `json:"-"` -} - -// UnmarshalJSON creates JSON format of user -func (r *User) UnmarshalJSON(b []byte) error { - type tmp User - var s struct { - tmp - StartTime eclcloud.JSONRFC3339ZNoTNoZ `json:"start_time"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = User(s.tmp) - - r.StartTime = time.Time(s.StartTime) - - return err -} - -// UserPage is a single page of User results. -type UserPage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of User contains any results. -func (r UserPage) IsEmpty() (bool, error) { - users, err := ExtractUsers(r) - return len(users) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r UserPage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractUsers returns a slice of Users contained in a single page of -// results. -func ExtractUsers(r pagination.Page) ([]User, error) { - var s struct { - ContractID string `json:"contract_id"` - Users []User `json:"users"` - } - - // In list response case, each json element does not have contract_id. - // It is set at out layer of each element. - // So following logic set contract_id into inside of users slice forcibly. - // In "show(get with ID of tenant)" case, this does not occur. - err := (r.(UserPage)).ExtractInto(&s) - contractID := s.ContractID - - for i := 0; i < len(s.Users); i++ { - s.Users[i].ContractID = contractID - } - return s.Users, err -} - -// Extract interprets any projectResults as a User. -func (r userResult) Extract() (*User, error) { - var u *User - err := r.ExtractInto(&u) - return u, err -} diff --git a/v3/ecl/sss/v2/users/testing/doc.go b/v3/ecl/sss/v2/users/testing/doc.go deleted file mode 100644 index 5bf4d42..0000000 --- a/v3/ecl/sss/v2/users/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// sss user unit tests -package testing diff --git a/v3/ecl/sss/v2/users/testing/fixtures.go b/v3/ecl/sss/v2/users/testing/fixtures.go deleted file mode 100644 index 1e85386..0000000 --- a/v3/ecl/sss/v2/users/testing/fixtures.go +++ /dev/null @@ -1,144 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/users" -) - -const contractID = "econ8000008888" - -const idUser1 = "ecid1000000001" -const idUser2 = "ecid1000000002" - -const startTime = "2018-07-26 08:40:01" - -var listResponse = fmt.Sprintf(` -{ - "contract_id": "%s", - "users": [{ - "user_id": "%s", - "login_id": "login_id_1", - "mail_address": "user1@example.com", - "start_time": "%s", - "api_availability": true, - "contract_owner": true, - "super_user": true - }, { - "user_id": "%s", - "login_id": "login_id_2", - "mail_address": "user2@example.com", - "start_time": "%s", - "api_availability": true, - "contract_owner": true, - "super_user": true - }] -}`, contractID, - idUser1, startTime, - idUser2, startTime) - -var expectedUsersSlice = []users.User{firstUser, secondUser} - -var userStartTime, _ = time.Parse(eclcloud.RFC3339ZNoTNoZ, startTime) - -var firstUser = users.User{ - UserID: idUser1, - LoginID: "login_id_1", - MailAddress: "user1@example.com", - ContractID: contractID, - StartTime: userStartTime, - ApiAvailability: true, - ContractOwner: true, - Superuser: true, -} - -var secondUser = users.User{ - UserID: idUser2, - LoginID: "login_id_2", - MailAddress: "user2@example.com", - ContractID: contractID, - StartTime: userStartTime, - ApiAvailability: true, - ContractOwner: true, - Superuser: true, -} - -var getResponse = fmt.Sprintf(` -{ - "user_id": "%s", - "login_id": "login_id_1", - "mail_address": "user1@example.com", - "contract_owner": false, - "super_user": false, - "api_availability": true, - "sss_endpoint": "http://sss.com", - "keystone_endpoint": "http://keystone.com", - "keystone_name": "keystonename1", - "keystone_password": "keystonepassword1", - "start_time": "%s", - "contract_id": "%s", - "login_integration": "", - "external_reference_id": "econ0000009999", - "brand_id": "ecl2", - "auto_role_assignment_flag": false, - "external_user_type": "iop", - "otp_activation": false -}`, idUser1, - startTime, - contractID, -) - -var getResponseStruct = users.User{ - UserID: idUser1, - LoginID: "login_id_1", - MailAddress: "user1@example.com", - ContractOwner: false, - Superuser: false, - ApiAvailability: true, - SSSEndpoint: "http://sss.com", - KeystoneEndpoint: "http://keystone.com", - KeystoneName: "keystonename1", - StartTime: userStartTime, - ContractID: contractID, - LoginIntegration: "", - ExternalReferenceID: "econ0000009999", - BrandID: "ecl2", - OtpActivation: false, -} - -var createRequest = `{ - "login_id": "login_id_1", - "mail_address": "user1@example.com", - "notify_password": "false", - "password": "Passw0rd" -}` - -var createResponse = fmt.Sprintf(`{ - "login_id": "login_id_1", - "mail_address": "user1@example.com", - "user_id": "%s", - "contract_id": "%s", - "keystone_endpoint": "http://keystone.com", - "sss_endpoint": "http://sss.com", - "password": "Passw0rd" -} -`, idUser1, - contractID, -) - -var createdUser = users.User{ - LoginID: "login_id_1", - UserID: idUser1, - ContractID: contractID, - MailAddress: "user1@example.com", - KeystoneEndpoint: "http://keystone.com", - SSSEndpoint: "http://sss.com", -} - -var updateRequest = `{ - "login_id": "login_id_1_update", - "mail_address": "user1_update@example.com", - "new_password": "NewPassw0rd" -}` diff --git a/v3/ecl/sss/v2/users/testing/requests_test.go b/v3/ecl/sss/v2/users/testing/requests_test.go deleted file mode 100644 index c2c1f1e..0000000 --- a/v3/ecl/sss/v2/users/testing/requests_test.go +++ /dev/null @@ -1,152 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/users" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := users.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := users.ExtractUsers(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedUsersSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListUserAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := users.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allZones, err := users.ExtractUsers(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allZones)) -} - -func TestGetUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/users/%s", idUser1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := users.Get(fakeclient.ServiceClient(), idUser1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &getResponseStruct, actual) -} - -func TestCreateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - createOpts := users.CreateOpts{ - LoginID: "login_id_1", - MailAddress: "user1@example.com", - NotifyPassword: "false", - Password: "Passw0rd", - } - - // clone FirstTenant into createdUser(Used as assertion target) - // and initialize StartTime - // createdUser := firstUser - // createdUser.StartTime = time.Time{} - - actual, err := users.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdUser, actual) -} - -func TestUpdateUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/users/%s", idUser1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusNoContent) - }) - - loginID := "login_id_1_update" - mailAddress := "user1_update@example.com" - newPassword := "NewPassw0rd" - - updateOpts := users.UpdateOpts{ - LoginID: &loginID, - MailAddress: &mailAddress, - NewPassword: &newPassword, - } - - // In ECL2.0 user update API returns - // - StatusNoContent - // - No response body as PUT response - res := users.Update(fakeclient.ServiceClient(), idUser1, updateOpts) - th.AssertNoErr(t, res.Err) -} - -func TestDeleteUser(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/users/%s", idUser1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - res := users.Delete(fakeclient.ServiceClient(), idUser1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/sss/v2/users/urls.go b/v3/ecl/sss/v2/users/urls.go deleted file mode 100644 index d3ed26f..0000000 --- a/v3/ecl/sss/v2/users/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package users - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func getURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("users") -} - -func deleteURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} - -func updateURL(client *eclcloud.ServiceClient, userID string) string { - return client.ServiceURL("users", userID) -} diff --git a/v3/ecl/sss/v2/workspace_roles/doc.go b/v3/ecl/sss/v2/workspace_roles/doc.go deleted file mode 100644 index f04b60c..0000000 --- a/v3/ecl/sss/v2/workspace_roles/doc.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Package workspace_roles contains workspace-role management functionality on SSS. - -Example to Create a workspace-role - - workspaceID := "ws00000000001" - userID := "ecid0000000001" - - createOpts := workspace_roles.CreateOpts{ - UserID: userID, - WorkspaceID: workspaceID, - } - - role, err := workspace_roles.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", role) - -Example to Delete a workspace-role - - workspaceID := "ws00000000001" - userID := "ecid00000000001" - result := workspace_roles.Delete(client, workspaceID, userID) - if result.Err != nil { - panic(result.Err) - } - -*/ -package workspace_roles diff --git a/v3/ecl/sss/v2/workspace_roles/requests.go b/v3/ecl/sss/v2/workspace_roles/requests.go deleted file mode 100644 index 15484a2..0000000 --- a/v3/ecl/sss/v2/workspace_roles/requests.go +++ /dev/null @@ -1,36 +0,0 @@ -package workspace_roles - -import "github.com/nttcom/eclcloud/v3" - -// CreateOptsBuilder allows extensions to add additional parameters to the Create request. -type CreateOptsBuilder interface { - ToWorkspaceRoleCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a workspace-role. -type CreateOpts struct { - UserID string `json:"user_id" required:"true"` - WorkspaceID string `json:"workspace_id" required:"true"` -} - -// ToWorkspaceRoleCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToWorkspaceRoleCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new workspace-role. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToWorkspaceRoleCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, nil) - return -} - -// Delete deletes a workspace-role. -func Delete(client *eclcloud.ServiceClient, workspaceID string, userID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, workspaceID, userID), nil) - return -} diff --git a/v3/ecl/sss/v2/workspace_roles/results.go b/v3/ecl/sss/v2/workspace_roles/results.go deleted file mode 100644 index 5e207b2..0000000 --- a/v3/ecl/sss/v2/workspace_roles/results.go +++ /dev/null @@ -1,34 +0,0 @@ -package workspace_roles - -import ( - "github.com/nttcom/eclcloud/v3" -) - -type workspaceRoleResult struct { - eclcloud.Result -} - -// CreateResult is the result of a Create request. Call its Extract method to -// interpret it as a Workspace-Role. -type CreateResult struct { - workspaceRoleResult -} - -// DeleteResult is the result of a Delete request. Call its ExtractErr method to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -type WorkspaceRole struct { - UserID string `json:"user_id"` - WorkspaceID string `json:"workspace_id"` - WorkspaceName string `json:"workspace_name"` -} - -// Extract interprets any projectResults as a Workspace-Role. -func (r workspaceRoleResult) Extract() (*WorkspaceRole, error) { - var s WorkspaceRole - err := r.ExtractInto(&s) - return &s, err -} diff --git a/v3/ecl/sss/v2/workspace_roles/testing/doc.go b/v3/ecl/sss/v2/workspace_roles/testing/doc.go deleted file mode 100644 index f11fe00..0000000 --- a/v3/ecl/sss/v2/workspace_roles/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// sss workspace-role unit tests -package testing diff --git a/v3/ecl/sss/v2/workspace_roles/testing/fixtures.go b/v3/ecl/sss/v2/workspace_roles/testing/fixtures.go deleted file mode 100644 index 8475635..0000000 --- a/v3/ecl/sss/v2/workspace_roles/testing/fixtures.go +++ /dev/null @@ -1,28 +0,0 @@ -package testing - -import "github.com/nttcom/eclcloud/v3/ecl/sss/v2/workspace_roles" - -const workspaceID = "ws0000000001" - -const userID = "ecid1234567891" - -var createRequest = ` -{ - "user_id": "ecid1234567891", - "workspace_id": "ws0000000001" -} -` - -var createResponse = ` -{ - "user_id": "ecid1234567891", - "workspace_id": "ws0000000001", - "workspace_name": "testWorkspace001" -} -` - -var createdWorkspaceRole = workspace_roles.WorkspaceRole{ - UserID: userID, - WorkspaceID: workspaceID, - WorkspaceName: "testWorkspace001", -} diff --git a/v3/ecl/sss/v2/workspace_roles/testing/requests_test.go b/v3/ecl/sss/v2/workspace_roles/testing/requests_test.go deleted file mode 100644 index d8dde45..0000000 --- a/v3/ecl/sss/v2/workspace_roles/testing/requests_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/workspace_roles" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestCreateWorkspaceRole(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/workspace-roles", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - createOpts := workspace_roles.CreateOpts{ - UserID: "ecid1234567891", - WorkspaceID: "ws0000000001", - } - - actual, err := workspace_roles.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdWorkspaceRole, actual) -} - -func TestDeleteWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/workspace-roles/workspaces/%s/users/%s", workspaceID, userID) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - res := workspace_roles.Delete(fakeclient.ServiceClient(), workspaceID, userID) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/sss/v2/workspace_roles/urls.go b/v3/ecl/sss/v2/workspace_roles/urls.go deleted file mode 100644 index 7c56cb9..0000000 --- a/v3/ecl/sss/v2/workspace_roles/urls.go +++ /dev/null @@ -1,16 +0,0 @@ -package workspace_roles - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3" -) - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("workspace-roles") -} - -func deleteURL(client *eclcloud.ServiceClient, workspaceID string, userID string) string { - url := fmt.Sprintf("workspace-roles/workspaces/%s/users/%s", workspaceID, userID) - return client.ServiceURL(url) -} diff --git a/v3/ecl/sss/v2/workspaces/doc.go b/v3/ecl/sss/v2/workspaces/doc.go deleted file mode 100644 index c9278c0..0000000 --- a/v3/ecl/sss/v2/workspaces/doc.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Package workspaces contains workspace management functionality on SSS. - -Example to List workspaces - - listOpts := workspaces.ListOpts{ContractID: "econ0000000001"} - - allPages, err := workspaces.List(client, listOpts).AllPages() - if err != nil { - panic(err) - } - - allWorkspaces, err := workspaces.ExtractWorkspaces(allPages) - if err != nil { - panic(err) - } - - for _, workspace := range allWorkspaces { - fmt.Printf("%+v\n", workspace) - } - -Example to Get a workspace - - id := "ws0000000001" - workspace, err := workspaces.Get(client, id).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", workspace) - -Example to Create a workspace - - createOpts := workspaces.CreateOpts{ - WorkspaceName: "Example-Workspace", - Description: "Example Workspace", - ContractID: "econ0000000001", - } - - workspace, err := workspaces.Create(client, createOpts).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", workspace) - -Example to Update a workspace - - workspaceID := "ws0000000001" - description := "update description" - updateOpts := workspaces.UpdateOpts{Description: &description} - - result := workspaces.Update(client, workspaceID, updateOpts) - if result.Err != nil { - panic(result.Err) - } - -Example to Delete a workspace - - workspaceID := "ws0000000001" - res := workspaces.Delete(client, workspaceID) - if res.Err != nil { - panic(res.Err) - } - -*/ -package workspaces diff --git a/v3/ecl/sss/v2/workspaces/requests.go b/v3/ecl/sss/v2/workspaces/requests.go deleted file mode 100644 index 57d1fae..0000000 --- a/v3/ecl/sss/v2/workspaces/requests.go +++ /dev/null @@ -1,117 +0,0 @@ -package workspaces - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to -// the List request -type ListOptsBuilder interface { - ToWorkspaceListQuery() (string, error) -} - -// ListOpts enables filtering of a list request. -// Currently SSS Workspace API does not support any of query parameters. -type ListOpts struct { - ContractID string `q:"contract_id"` -} - -// ToWorkspaceListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToWorkspaceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List enumerates the Workspaces to which the current token has access. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToWorkspaceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return WorkspacePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves details on a single workspace, by ID. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the Create request. -type CreateOptsBuilder interface { - ToWorkspaceCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents parameters used to create a workspace. -type CreateOpts struct { - // Workspace Name. - WorkspaceName string `json:"workspace_name" required:"true"` - // Workspace description. - Description string `json:"description,omitempty"` - // ContractID to be associated with the workspace. - ContractID string `json:"contract_id,omitempty"` -} - -// ToWorkspaceCreateMap formats a CreateOpts into a create request. -func (opts CreateOpts) ToWorkspaceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Create creates a new workspace. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToWorkspaceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), &b, &r.Body, nil) - return -} - -// Delete deletes a workspace. -func Delete(client *eclcloud.ServiceClient, workspaceID string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, workspaceID), nil) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the Update request. -type UpdateOptsBuilder interface { - ToWorkspaceUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents parameters to update a workspace. -type UpdateOpts struct { - // Workspace description. - Description *string `json:"description" required:"true"` -} - -// ToWorkspaceUpdateMap formats a UpdateOpts into an update request. -func (opts UpdateOpts) ToWorkspaceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "") -} - -// Update modifies the attributes of a workspace. -// SSS Workspace PUT API does not have response body, so set JSONResponse option as nil. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToWorkspaceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put( - updateURL(client, id), - b, - nil, - &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }, - ) - return -} diff --git a/v3/ecl/sss/v2/workspaces/results.go b/v3/ecl/sss/v2/workspaces/results.go deleted file mode 100644 index a43d617..0000000 --- a/v3/ecl/sss/v2/workspaces/results.go +++ /dev/null @@ -1,129 +0,0 @@ -package workspaces - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type workspaceResult struct { - eclcloud.Result -} - -// GetResult is the result of a Get request. Call its Extract method to -// interpret it as a Workspace. -type GetResult struct { - workspaceResult -} - -// CreateResult is the result of a Create request. Call its Extract method to -// interpret it as a Workspace. -type CreateResult struct { - workspaceResult -} - -// DeleteResult is the result of a Delete request. Call its ExtractErr method to -// determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// UpdateResult is the result of an Update request. Call its Extract method to -// interpret it as a Workspace. -type UpdateResult struct { - workspaceResult -} - -type Workspace struct { - ContractID string `json:"contract_id"` - WorkspaceID string `json:"workspace_id"` - WorkspaceName string `json:"workspace_name"` - Description string `json:"description"` - StartTime time.Time `json:"-"` - Regions []Region `json:"regions"` - Users []User `json:"users"` -} - -type Region struct { - RegionName string `json:"region_name"` - TenantID string `json:"tenant_id"` -} - -type User struct { - UserID string `json:"user_id"` - ContractID string `json:"contract_id"` - ContractOwner bool `json:"contract_owner"` -} - -// UnmarshalJSON creates JSON format of workspace -func (r *Workspace) UnmarshalJSON(b []byte) error { - type tmp Workspace - var s struct { - tmp - StartTime eclcloud.JSONRFC3339ZNoTNoZ `json:"start_time"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Workspace(s.tmp) - - r.StartTime = time.Time(s.StartTime) - - return err -} - -// WorkspacePage is a single page of Workspace results. -type WorkspacePage struct { - pagination.LinkedPageBase -} - -// IsEmpty determines whether or not a page of Workspace contains any results. -func (r WorkspacePage) IsEmpty() (bool, error) { - workspaces, err := ExtractWorkspaces(r) - return len(workspaces) == 0, err -} - -// NextPageURL extracts the "next" link from the links section of the result. -func (r WorkspacePage) NextPageURL() (string, error) { - var s struct { - Links struct { - Next string `json:"next"` - Previous string `json:"previous"` - } `json:"links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return s.Links.Next, err -} - -// ExtractWorkspaces returns a slice of Workspace contained in a single page of results. -func ExtractWorkspaces(r pagination.Page) ([]Workspace, error) { - var s struct { - ContractID string `json:"contract_id"` - Workspaces []Workspace `json:"workspaces"` - } - - // In list response case, each json element does not have contract_id. - // It is set at out layer of each element. - // So following logic set contract_id into inside of workspaces slice forcibly. - // In "show(get with ID of workspace)" case, this does not occur. - err := (r.(WorkspacePage)).ExtractInto(&s) - contractID := s.ContractID - - for i := 0; i < len(s.Workspaces); i++ { - s.Workspaces[i].ContractID = contractID - } - return s.Workspaces, err -} - -// Extract interprets any projectResults as a Workspace. -func (r workspaceResult) Extract() (*Workspace, error) { - var s *Workspace - err := r.ExtractInto(&s) - return s, err -} diff --git a/v3/ecl/sss/v2/workspaces/testing/doc.go b/v3/ecl/sss/v2/workspaces/testing/doc.go deleted file mode 100644 index e362fa0..0000000 --- a/v3/ecl/sss/v2/workspaces/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// sss workspace unit tests -package testing diff --git a/v3/ecl/sss/v2/workspaces/testing/fixtures.go b/v3/ecl/sss/v2/workspaces/testing/fixtures.go deleted file mode 100644 index 3a148d4..0000000 --- a/v3/ecl/sss/v2/workspaces/testing/fixtures.go +++ /dev/null @@ -1,158 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/workspaces" -) - -const contractID = "econ0000000001" - -const workspaceID1 = "ws0000000001" -const workspaceID2 = "ws0000000002" - -const nameWorkspace1 = "jp1_workspace01" -const nameWorkspace2 = "jp1_workspace02" - -const descriptionWorkspace1 = "jp1 workspace01" -const descriptionWorkspace2 = "jp1 workspace02" - -const startTime = "2020-01-01 00:00:00" - -var workspaceStartTime, _ = time.Parse(eclcloud.RFC3339ZNoTNoZ, startTime) - -var listResponse = fmt.Sprintf(` -{ - "contract_id": "%s", - "workspaces": [ - { - "workspace_id": "%s", - "workspace_name": "%s", - "description": "%s", - "start_time": "%s" - }, - { - "workspace_id": "%s", - "workspace_name": "%s", - "description": "%s", - "start_time": "%s" - } - ] -} -`, - contractID, - workspaceID1, nameWorkspace1, descriptionWorkspace1, startTime, - workspaceID2, nameWorkspace2, descriptionWorkspace2, startTime, -) - -var firstWorkspace = workspaces.Workspace{ - ContractID: contractID, - WorkspaceID: workspaceID1, - WorkspaceName: nameWorkspace1, - Description: descriptionWorkspace1, - StartTime: workspaceStartTime, -} - -var secondWorkspace = workspaces.Workspace{ - ContractID: contractID, - WorkspaceID: workspaceID2, - WorkspaceName: nameWorkspace2, - Description: descriptionWorkspace2, - StartTime: workspaceStartTime, -} - -var expectedWorkspacesSlice = []workspaces.Workspace{firstWorkspace, secondWorkspace} - -var getResponse = fmt.Sprintf(` -{ - "contract_id": "%s", - "workspace_id": "%s", - "workspace_name": "%s", - "description": "%s", - "start_time": "%s", - "regions": [ - { - "region_name": "jp1", - "tenant_id": "9a76dca6d8cd4391aac6f2ea052f10f4" - }, - { - "region_name": "jp2", - "tenant_id": "27a58d42769141ff8e94920a99aeb44b" - } - ], - "users": [ - { - "user_id": "ecid000000001", - "contract_id": "econ0000000001", - "contract_owner": true - }, - { - "user_id": "ecid000000002", - "contract_id": "econ0000000002", - "contract_owner": false - } - ] -}`, - contractID, workspaceID1, nameWorkspace1, descriptionWorkspace1, startTime) - -var getResponseStruct = workspaces.Workspace{ - ContractID: contractID, - WorkspaceID: workspaceID1, - WorkspaceName: nameWorkspace1, - Description: descriptionWorkspace1, - StartTime: workspaceStartTime, - Regions: []workspaces.Region{ - { - RegionName: "jp1", - TenantID: "9a76dca6d8cd4391aac6f2ea052f10f4", - }, - { - RegionName: "jp2", - TenantID: "27a58d42769141ff8e94920a99aeb44b", - }, - }, - Users: []workspaces.User{ - { - UserID: "ecid000000001", - ContractID: "econ0000000001", - ContractOwner: true, - }, - { - UserID: "ecid000000002", - ContractID: "econ0000000002", - ContractOwner: false, - }, - }, -} - -var createRequest = ` -{ - "workspace_name": "sample_workspace", - "description": "sample workspace", - "contract_id": "econ0000000001" -} -` - -var createResponse = fmt.Sprintf(` -{ - "workspace_id": "%s", - "workspace_name": "sample_workspace", - "description": "sample workspace", - "contract_id": "%s" -} -`, workspaceID1, contractID) - -var createdWorkspace = workspaces.Workspace{ - ContractID: contractID, - WorkspaceID: workspaceID1, - WorkspaceName: "sample_workspace", - Description: "sample workspace", -} - -var updateRequest = ` -{ - "description": "updated workspace" -} -` diff --git a/v3/ecl/sss/v2/workspaces/testing/requests_test.go b/v3/ecl/sss/v2/workspaces/testing/requests_test.go deleted file mode 100644 index 36d2c6e..0000000 --- a/v3/ecl/sss/v2/workspaces/testing/requests_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/sss/v2/workspaces" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/workspaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - count := 0 - err := workspaces.List(fakeclient.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := workspaces.ExtractWorkspaces(page) - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, expectedWorkspacesSlice, actual) - - return true, nil - }) - th.AssertNoErr(t, err) - th.CheckEquals(t, 1, count) -} - -func TestListWorkspaceAllPages(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/workspaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, listResponse) - }) - - allPages, err := workspaces.List(fakeclient.ServiceClient(), nil).AllPages() - th.AssertNoErr(t, err) - allZones, err := workspaces.ExtractWorkspaces(allPages) - th.AssertNoErr(t, err) - th.CheckEquals(t, 2, len(allZones)) -} - -func TestGetWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/workspaces/%s", workspaceID1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, getResponse) - }) - - actual, err := workspaces.Get(fakeclient.ServiceClient(), workspaceID1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &getResponseStruct, actual) -} - -func TestCreateWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/workspaces", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, createRequest) - - w.WriteHeader(http.StatusCreated) - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, createResponse) - }) - - createOpts := workspaces.CreateOpts{ - WorkspaceName: "sample_workspace", - Description: "sample workspace", - ContractID: "econ0000000001", - } - - actual, err := workspaces.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &createdWorkspace, actual) -} - -func TestUpdateWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/workspaces/%s", workspaceID1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestJSONRequest(t, r, updateRequest) - - w.WriteHeader(http.StatusNoContent) - }) - - description := "updated workspace" - - updateOpts := workspaces.UpdateOpts{ - Description: &description, - } - - res := workspaces.Update(fakeclient.ServiceClient(), workspaceID1, updateOpts) - th.AssertNoErr(t, res.Err) -} - -func TestDeleteWorkspace(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/workspaces/%s", workspaceID1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.WriteHeader(http.StatusNoContent) - }) - - res := workspaces.Delete(fakeclient.ServiceClient(), workspaceID1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/sss/v2/workspaces/urls.go b/v3/ecl/sss/v2/workspaces/urls.go deleted file mode 100644 index 7ff8fee..0000000 --- a/v3/ecl/sss/v2/workspaces/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package workspaces - -import "github.com/nttcom/eclcloud/v3" - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("workspaces") -} - -func getURL(client *eclcloud.ServiceClient, workspaceID string) string { - return client.ServiceURL("workspaces", workspaceID) -} - -func createURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("workspaces") -} - -func deleteURL(client *eclcloud.ServiceClient, workspaceID string) string { - return client.ServiceURL("workspaces", workspaceID) -} - -func updateURL(client *eclcloud.ServiceClient, workspaceID string) string { - return client.ServiceURL("workspaces", workspaceID) -} diff --git a/v3/ecl/storage/v1/virtualstorages/doc.go b/v3/ecl/storage/v1/virtualstorages/doc.go deleted file mode 100644 index 0f6dd42..0000000 --- a/v3/ecl/storage/v1/virtualstorages/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package virtualstorages provides information and interaction with virtualstorage in the -// Enterprise Cloud Block Storage service. A volume is a detachable block storage -// device, akin to a USB hard drive. It can only be attached to one instance at -// a time. -package virtualstorages diff --git a/v3/ecl/storage/v1/virtualstorages/requests.go b/v3/ecl/storage/v1/virtualstorages/requests.go deleted file mode 100644 index 35b2bd1..0000000 --- a/v3/ecl/storage/v1/virtualstorages/requests.go +++ /dev/null @@ -1,179 +0,0 @@ -package virtualstorages - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToVirtualStorageCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a VirtualStorage. This object is passed to -// the virtualstorages.Create function. For more information about these parameters, -// see the VirtualStorage object. -type CreateOpts struct { - // The virtual storage name - Name string `json:"name" required:"true"` - // The virtual storage description - Description string `json:"description,omitempty"` - // The network_id to connect virtual storage - NetworkID string `json:"network_id" required:"true"` - // The subnet_id to connect virtual storage - SubnetID string `json:"subnet_id" required:"true"` - // The virtual storage volume_type_id - VolumeTypeID string `json:"volume_type_id" required:"true"` - // The ip address pool of virtual storage - IPAddrPool IPAddressPool `json:"ip_addr_pool" required:"true"` - // The virtual storage host_routes - HostRoutes []HostRoute `json:"host_routes,omitempty"` -} - -// ToVirtualStorageCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToVirtualStorageCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_storage") -} - -// Create will create a new VirtualStorage based on the values in CreateOpts. -// To extract the VirtualStorage object from the response, call the Extract method on the -// CreateResult. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToVirtualStorageCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// Delete will delete the existing VirtualStorage with the provided ID. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete( - deleteURL(client, id), - &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get retrieves the VirtualStorage with the provided ID. -// To extract the VirtualStorage object from the response, -// call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToVirtualStorageListQuery() (string, error) -} - -// ListOpts holds options for listing VirtualStorages. -// It is passed to the virtualstorages.List function. -type ListOpts struct { - // Now there are no definiton as query params in API specification - // But do not remove this struct in future specification change. -} - -// ToVirtualStorageListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVirtualStorageListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns VirtualStorage optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToVirtualStorageListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VirtualStoragePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToVirtualStorageUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contain options for updating an existing VirtualStorage. -// This object is passed to the virtual_storage.Update function. -// For more information about the parameters, see the VirtualStorage object. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - IPAddrPool *IPAddressPool `json:"ip_addr_pool,omitempty"` - HostRoutes *[]HostRoute `json:"host_routes,omitempty"` -} - -// ToVirtualStorageUpdateMap assembles a request body based on the contents of an -// UpdateOpts. -func (opts UpdateOpts) ToVirtualStorageUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_storage") -} - -// Update will update the VirtualStorage with provided information. -// To extract the updated VirtualStorage from the response, -// call the Extract method on the UpdateResult. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToVirtualStorageUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// IDFromName is a convenience function that returns a server's ID given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - // Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractVirtualStorages(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "virtual_storage"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "virtual_storage"} - } -} diff --git a/v3/ecl/storage/v1/virtualstorages/results.go b/v3/ecl/storage/v1/virtualstorages/results.go deleted file mode 100644 index 4012f31..0000000 --- a/v3/ecl/storage/v1/virtualstorages/results.go +++ /dev/null @@ -1,130 +0,0 @@ -package virtualstorages - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// IPAddressPool is struct which corresponds to ip_addr_pool object. -type IPAddressPool struct { - Start string `json:"start"` - End string `json:"end"` -} - -// HostRoute is struct which corresponds to host_routes object. -type HostRoute struct { - Destination string `json:"destination"` - Nexthop string `json:"nexthop"` -} - -// VirtualStorage contains all the information associated with a Virtual Storage. -type VirtualStorage struct { - // API error in virtual storage creation. - APIErrorMessage string `json:"api_error_message"` - // Unique identifier for the virtual storage. - ID string `json:"id"` - // network_id which this virtual storage is connected. - NetworkID string `json:"network_id"` - // subnet_id which this virtual storage is connected. - SubnetID string `json:"subnet_id"` - // ip_address_pool object for virtual storage. - IPAddrPool IPAddressPool `json:"ip_addr_pool"` - // List of host routes of virtual storage. - HostRoutes []HostRoute `json:"host_routes"` - // volume_type_id of virtual storage - VolumeTypeID string `json:"volume_type_id"` - // Human-readable display name for the virtual storage. - Name string `json:"name"` - // Human-readable description for the virtual storage. - Description string `json:"description"` - // Current status of the virtual storage. - Status string `json:"status"` - // The date when this volume was created. - CreatedAt time.Time `json:"-"` - // The date when this volume was last updated - UpdatedAt time.Time `json:"-"` - // Error in virtual storage creation. - ErrorMessage string `json:"error_message"` -} - -// UnmarshalJSON creates JSON format of virtual storage -func (r *VirtualStorage) UnmarshalJSON(b []byte) error { - type tmp VirtualStorage - var s struct { - tmp - CreatedAt eclcloud.JSONISO8601 `json:"created_at"` - UpdatedAt eclcloud.JSONISO8601 `json:"updated_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = VirtualStorage(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - - return err -} - -// VirtualStoragePage is a pagination.pager that is returned from a call to the List function. -type VirtualStoragePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a ListResult contains no VirtualStorages. -func (r VirtualStoragePage) IsEmpty() (bool, error) { - vss, err := ExtractVirtualStorages(r) - return len(vss) == 0, err -} - -// ExtractVirtualStorages extracts and returns VirtualStorages. -// It is used while iterating over a virtualstorages.List call. -func ExtractVirtualStorages(r pagination.Page) ([]VirtualStorage, error) { - var s []VirtualStorage - err := ExtractVirtualStoragesInto(r, &s) - return s, err -} - -type commonResult struct { - eclcloud.Result -} - -// Extract will get the VirtualStorage object out of the commonResult object. -func (r commonResult) Extract() (*VirtualStorage, error) { - var s VirtualStorage - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "virtual_storage") -} - -// ExtractVirtualStoragesInto is information expander for virtual storage -func ExtractVirtualStoragesInto(r pagination.Page, v interface{}) error { - return r.(VirtualStoragePage).Result.ExtractIntoSlicePtr(v, "virtual_storages") -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// UpdateResult contains the response body and error from an Update request. -type UpdateResult struct { - commonResult -} - -// DeleteResult contains the response body and error from a Delete request. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/storage/v1/virtualstorages/testing/doc.go b/v3/ecl/storage/v1/virtualstorages/testing/doc.go deleted file mode 100644 index 2b09490..0000000 --- a/v3/ecl/storage/v1/virtualstorages/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains virtual storage unit tests -package testing diff --git a/v3/ecl/storage/v1/virtualstorages/testing/fixtures.go b/v3/ecl/storage/v1/virtualstorages/testing/fixtures.go deleted file mode 100644 index 268a122..0000000 --- a/v3/ecl/storage/v1/virtualstorages/testing/fixtures.go +++ /dev/null @@ -1,435 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/virtualstorages" -) - -// Define parameters which are used in assertion. -// Additionally, kind of IDs are defined here. -const idVirtualStorage1 = "fb3efc23-ca8c-4eb5-b7f6-6fc66ff24f9c" -const idVirtualStorage2 = "3535de20-192d-4f5a-a74a-cd1a9c1bf747" - -const idVolumeType = "4f4971a5-899d-42b4-8442-24f17eac9683" - -const nameVirtualStorage1 = "virtual_storage_name_1" -const descriptionVirtualStorage1 = "virtual_storage_description_1" - -const nameVirtualStorage1Update = "virtual_storage_name_1-update" -const descriptionVirtualStorage1Update = "virtual_storage_description_1-update" - -const tenantID = "2d5b878c-147a-4d7c-87fd-90a8be9d255f" - -const networkID = "511f266e-a8bf-4547-ab2a-fc4d2bda9f81" -const subnetID = "9f3fd369-e4d4-4c3a-84f1-9c5ba7686297" - -const storageTime = "2015-05-17T18:14:34+0000" - -const hostRoute1Destination = "0.0.0.0/0" -const hostRoute1Nexthop = "123.123.123.1" -const hostRoute2Destination = "192.168.0.0/24" -const hostRoute2Nexthop = "123.123.123.1" -const hostRoute3Destination = "192.168.1.0/24" -const hostRoute3Nexthop = "123.123.123.1" - -const ipAddrPoolStart = "192.168.1.10" -const ipAddrPoolEnd = "192.168.1.20" - -const ipAddrPoolStartUpdate = "192.168.1.9" -const ipAddrPoolEndUpdate = "192.168.1.21" - -// ListResponse is mocked response of virtualstorages.List -var ListResponse = fmt.Sprintf(` -{ - "virtual_storages": [ - { - "id" : "%s", - "volume_type_id" : "%s", - "name" : "%s", - "description" : "%s", - "tenant_id" : "%s", - "network_id" : "%s", - "subnet_id" : "%s", - "ip_addr_pool" : { - "start" : "%s", - "end" : "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination":"%s", - "nexthop": "%s" - }], - "status" : "available", - "links": [{ - "href": "http://storage.sdp.url:port/v1.0/virtual_storages/440cf918-3ee0-4143-b289-f63e1d2000e6", - "rel": "self" - }], - "created_at" : "%s", - "updated_at" : "%s" - }, - { - "id" : "%s", - "volume_type_id" : "%s", - "name" : "virtual_storage_name_2", - "description" : "virtual_storage_description_2", - "tenant_id" : "%s", - "network_id" : "%s", - "subnet_id" : "%s", - "ip_addr_pool" : { - "start" : "%s", - "end" : "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination":"%s", - "nexthop": "%s" - }], - "status": "available", - "links": [{ - "href": "http://storage.sdp.url:port/v1.0/virtual_storages/440cf918-3ee0-4143-b289-f63e1d2000e6", - "rel": "self" - }], - "created_at" : "%s", - "updated_at" : "%s" - } - ] -}`, - // for virtual storage 1 - idVirtualStorage1, - idVolumeType, - nameVirtualStorage1, - descriptionVirtualStorage1, - tenantID, - networkID, - subnetID, - ipAddrPoolStart, - ipAddrPoolEnd, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, - storageTime, - storageTime, - // for virtual storage 2 - idVirtualStorage1, - idVolumeType, - tenantID, - networkID, - subnetID, - ipAddrPoolStart, - ipAddrPoolEnd, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, - storageTime, - storageTime) - -// GetResponse is mocked format of virtualstorages.Get -var GetResponse = fmt.Sprintf(` -{ - "virtual_storage": { - "id": "%s", - "volume_type_id": "%s", - "name": "%s", - "description": "%s", - "network_id": "%s", - "subnet_id": "%s", - "ip_addr_pool": { - "start": "%s", - "end": "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }], - "status": "available", - "created_at": "%s", - "updated_at" : "%s", - "error_message": "" - } -}`, idVirtualStorage1, - idVolumeType, - nameVirtualStorage1, - descriptionVirtualStorage1, - networkID, - subnetID, - ipAddrPoolStart, - ipAddrPoolEnd, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, - storageTime, - storageTime) - -// CreateRequest is mocked request for virtualstorages.Create -var CreateRequest = fmt.Sprintf(` -{ - "virtual_storage": { - "volume_type_id": "%s", - "name": "%s", - "description": "%s", - "network_id": "%s", - "subnet_id": "%s", - "ip_addr_pool": { - "start": "%s", - "end": "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }] - } -}`, idVolumeType, - nameVirtualStorage1, - descriptionVirtualStorage1, - networkID, - subnetID, - ipAddrPoolStart, - ipAddrPoolEnd, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, -) - -// CreateResponse is mocked response of virtualstorages.Create -var CreateResponse = fmt.Sprintf(` -{ - "virtual_storage": { - "id": "%s", - "volume_type_id": "%s", - "name": "%s", - "description": "%s", - "network_id": "%s", - "subnet_id": "%s", - "ip_addr_pool": { - "start": "%s", - "end": "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }], - "status": "creating", - "created_at": "null", - "error_message": "" - } -}`, idVirtualStorage1, - idVolumeType, - nameVirtualStorage1, - descriptionVirtualStorage1, - networkID, - subnetID, - ipAddrPoolStart, - ipAddrPoolEnd, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, -) - -// UpdateRequest is mocked request of virtualstorages.Update -var UpdateRequest = fmt.Sprintf(` -{ - "virtual_storage": { - "name": "%s", - "description": "%s", - "ip_addr_pool": { - "start": "%s", - "end": "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }] - } -}`, nameVirtualStorage1Update, - descriptionVirtualStorage1Update, - ipAddrPoolStartUpdate, - ipAddrPoolEndUpdate, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, - hostRoute3Destination, - hostRoute3Nexthop, -) - -// UpdateResponse is mocked response of virtualstorages.Update -var UpdateResponse = fmt.Sprintf(` -{ - "virtual_storage": { - "id": "%s", - "volume_type_id": "%s", - "name": "%s", - "description": "%s", - "network_id": "%s", - "subnet_id": "%s", - "ip_addr_pool": { - "start": "%s", - "end": "%s" - }, - "host_routes":[{ - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }, - { - "destination": "%s", - "nexthop": "%s" - }], - "status": "available", - "created_at": "%s", - "updated_at" : "%s", - "error_message": "" - } -}`, idVirtualStorage1, - idVolumeType, - nameVirtualStorage1Update, - descriptionVirtualStorage1Update, - networkID, - subnetID, - ipAddrPoolStartUpdate, - ipAddrPoolEndUpdate, - hostRoute1Destination, - hostRoute1Nexthop, - hostRoute2Destination, - hostRoute2Nexthop, - hostRoute3Destination, - hostRoute3Nexthop, - storageTime, - storageTime) - -func getExpectedVirtualStoragesSlice() []virtualstorages.VirtualStorage { - storageParsedTime, _ := time.Parse(eclcloud.ISO8601, storageTime) - - var virtualStorage1 = virtualstorages.VirtualStorage{ - ID: idVirtualStorage1, - VolumeTypeID: idVolumeType, - Name: nameVirtualStorage1, - Description: descriptionVirtualStorage1, - NetworkID: networkID, - SubnetID: subnetID, - CreatedAt: storageParsedTime, - UpdatedAt: storageParsedTime, - IPAddrPool: getIPAddrPool(false), - HostRoutes: getHostRoutes(false), - Status: "available", - } - - var virtualStorage2 = virtualstorages.VirtualStorage{ - ID: idVirtualStorage1, - VolumeTypeID: idVolumeType, - Name: "virtual_storage_name_2", - Description: "virtual_storage_description_2", - NetworkID: networkID, - SubnetID: subnetID, - CreatedAt: storageParsedTime, - UpdatedAt: storageParsedTime, - IPAddrPool: getIPAddrPool(false), - HostRoutes: getHostRoutes(false), - Status: "available", - } - - // ExpectedVirtualStoragesSlice is expected assertion target - ExpectedVirtualStoragesSlice := []virtualstorages.VirtualStorage{ - virtualStorage1, - virtualStorage2, - } - - return ExpectedVirtualStoragesSlice -} - -func getHostRoutes(isUpdate bool) []virtualstorages.HostRoute { - hostRoutes := []virtualstorages.HostRoute{ - { - Destination: hostRoute1Destination, - Nexthop: hostRoute1Nexthop, - }, - { - Destination: hostRoute2Destination, - Nexthop: hostRoute2Nexthop, - }, - } - - if isUpdate { - hostRoutes = append( - hostRoutes, - virtualstorages.HostRoute{ - Destination: hostRoute3Destination, - Nexthop: hostRoute3Nexthop, - }, - ) - } - - return hostRoutes -} - -func getIPAddrPool(isUpdate bool) virtualstorages.IPAddressPool { - var ipAddrPool virtualstorages.IPAddressPool - - if isUpdate { - ipAddrPool = virtualstorages.IPAddressPool{ - Start: ipAddrPoolStartUpdate, - End: ipAddrPoolEndUpdate, - } - return ipAddrPool - } - - ipAddrPool = virtualstorages.IPAddressPool{ - Start: ipAddrPoolStart, - End: ipAddrPoolEnd, - } - return ipAddrPool -} - -func getExpectedCreateVirtualStorage() virtualstorages.VirtualStorage { - - result := virtualstorages.VirtualStorage{ - ID: idVirtualStorage1, - VolumeTypeID: idVolumeType, - Name: nameVirtualStorage1, - Description: descriptionVirtualStorage1, - NetworkID: networkID, - SubnetID: subnetID, - IPAddrPool: getIPAddrPool(false), - HostRoutes: getHostRoutes(false), - Status: "creating", - ErrorMessage: "", - } - return result -} diff --git a/v3/ecl/storage/v1/virtualstorages/testing/requests_test.go b/v3/ecl/storage/v1/virtualstorages/testing/requests_test.go deleted file mode 100644 index ec66cda..0000000 --- a/v3/ecl/storage/v1/virtualstorages/testing/requests_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/virtualstorages" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListVirtualStorage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/virtual_storages/detail", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fakeclient.ServiceClient() - count := 0 - - virtualstorages.List(client, virtualstorages.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := virtualstorages.ExtractVirtualStorages(page) - if err != nil { - t.Errorf("Failed to extract virtual storages: %v", err) - return false, err - } - - th.CheckDeepEquals(t, getExpectedVirtualStoragesSlice(), actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } - -} - -func TestGetVirtualStorage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/virtual_storages/%s", idVirtualStorage1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - vsActual, err := virtualstorages.Get( - fakeclient.ServiceClient(), idVirtualStorage1).Extract() - th.AssertNoErr(t, err) - vsExpected := getExpectedVirtualStoragesSlice()[0] - th.CheckDeepEquals(t, &vsExpected, vsActual) -} - -func TestCreate(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/virtual_storages", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) // 202 - - fmt.Fprintf(w, CreateResponse) - }) - - createOpts := virtualstorages.CreateOpts{ - VolumeTypeID: idVolumeType, - Name: nameVirtualStorage1, - Description: descriptionVirtualStorage1, - NetworkID: networkID, - SubnetID: subnetID, - IPAddrPool: getIPAddrPool(false), - HostRoutes: getHostRoutes(false), - } - vsActual, err := virtualstorages.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, vsActual.Status, "creating") - - vsExpected := getExpectedCreateVirtualStorage() - th.AssertDeepEquals(t, &vsExpected, vsActual) -} - -func TestUpdateVirtualStorage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/virtual_storages/%s", idVirtualStorage1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, UpdateResponse) - }) - - name := nameVirtualStorage1Update - description := descriptionVirtualStorage1Update - ipAddrPool := getIPAddrPool(true) - hostRoutes := getHostRoutes(true) - - updateOpts := virtualstorages.UpdateOpts{ - Name: &name, - Description: &description, - IPAddrPool: &ipAddrPool, - HostRoutes: &hostRoutes, - } - vsActual, err := virtualstorages.Update( - fakeclient.ServiceClient(), idVirtualStorage1, updateOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, vsActual.Name, nameVirtualStorage1Update) - th.AssertEquals(t, vsActual.Description, descriptionVirtualStorage1Update) - th.AssertEquals(t, vsActual.ID, idVirtualStorage1) - - th.AssertEquals(t, vsActual.IPAddrPool.Start, ipAddrPoolStartUpdate) - th.AssertEquals(t, vsActual.IPAddrPool.End, ipAddrPoolEndUpdate) - - th.AssertEquals(t, vsActual.HostRoutes[2].Destination, hostRoute3Destination) - th.AssertEquals(t, vsActual.HostRoutes[2].Nexthop, hostRoute3Nexthop) -} - -func TestDeleteVirtualStorage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/virtual_storages/%s", idVirtualStorage1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - w.WriteHeader(http.StatusOK) - }) - - res := virtualstorages.Delete(fakeclient.ServiceClient(), idVirtualStorage1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/storage/v1/virtualstorages/urls.go b/v3/ecl/storage/v1/virtualstorages/urls.go deleted file mode 100644 index de09fa9..0000000 --- a/v3/ecl/storage/v1/virtualstorages/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package virtualstorages - -import "github.com/nttcom/eclcloud/v3" - -func createURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("virtual_storages") -} - -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("virtual_storages", "detail") -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("virtual_storages", id) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} diff --git a/v3/ecl/storage/v1/virtualstorages/util.go b/v3/ecl/storage/v1/virtualstorages/util.go deleted file mode 100644 index b65d9e5..0000000 --- a/v3/ecl/storage/v1/virtualstorages/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package virtualstorages - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// WaitForStatus will continually poll the resource, checking for a particular -// status. It will do this for the amount of seconds defined. -func WaitForStatus(c *eclcloud.ServiceClient, id, status string, secs int) error { - return eclcloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/v3/ecl/storage/v1/volumes/doc.go b/v3/ecl/storage/v1/volumes/doc.go deleted file mode 100644 index e75c49c..0000000 --- a/v3/ecl/storage/v1/volumes/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package volume provides information and interaction with volume in the -// Storage service. A volume is a detachable block storage device. -package volumes diff --git a/v3/ecl/storage/v1/volumes/requests.go b/v3/ecl/storage/v1/volumes/requests.go deleted file mode 100644 index 2d40d3f..0000000 --- a/v3/ecl/storage/v1/volumes/requests.go +++ /dev/null @@ -1,187 +0,0 @@ -package volumes - -import ( - "github.com/nttcom/eclcloud/v3" - // "github.com/nttcom/eclcloud/v3/ecl/storage/v1/virtualstorages" - // "github.com/nttcom/eclcloud/v3/ecl/storage/v1/volumetypes" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToVolumeCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains options for creating a Volume. This object is passed to -// the Volumes.Create function. For more information about these parameters, -// see the Volume object. -type CreateOpts struct { - // The volume name - Name string `json:"name" required:"true"` - // The volume description - Description string `json:"description,omitempty"` - // The volume size - Size int `json:"size" required:"true"` - // The volume IOPS as IOPS/GB - IOPSPerGB string `json:"iops_per_gb,omitempty"` - // The volume Throughput - Throughput string `json:"throughput,omitempty"` - // The initiator_iqns for volume (in case ISCSI) - InitiatorIQNs []string `json:"initiator_iqns,omitempty"` - // The availability zone of volume - AvailabilityZone string `json:"availability_zone,omitempty"` - // The parent virtual storage ID to connect volume - VirtualStorageID string `json:"virtual_storage_id" required:"true"` -} - -// ToVolumeCreateMap assembles a request body based on the contents of a -// CreateOpts. -func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "volume") -} - -// Create will create a new Volume based on the values in CreateOpts. -// To extract the Volume object from the response, call the Extract method on the -// CreateResult. -func Create(client *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToVolumeCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// Delete will delete the existing Volume with the provided ID. -func Delete(client *eclcloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete( - deleteURL(client, id), - &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get retrieves the Volume with the provided ID. -// To extract the Volume object from the response, -// call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToVolumeListQuery() (string, error) -} - -// ListOpts holds options for listing Volumes. -// It is passed to the Volumes.List function. -type ListOpts struct { - // Now there are no definitions as query params in API specification - // But do not remove this struct in future specification change. -} - -// ToVolumeListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVolumeListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns Volume optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToVolumeListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VolumePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToVolumeUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contain options for updating an existing Volume. -// This object is passed to the volume.Update function. -// For more information about the parameters, see the Volume object. -type UpdateOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - InitiatorIQNs *[]string `json:"initiator_iqns,omitempty"` -} - -// ToVolumeUpdateMap assembles a request body based on the contents of an -// UpdateOpts. -// Volume of Storage SDP only allows to send "initiator_iqns" when -// the service type is "File Storage" type -// So in "ToVolumeUpdateMap" function, check volume type of virtual storage -// related to volume first -// And if service type is "File Storage's one", add initiator_iqns as request parameter -func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "volume") -} - -// Update will update the Volume with provided information. -// To extract the updated Volume from the response, -// call the Extract method on the UpdateResult. -func Update(client *eclcloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToVolumeUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{202}, - }) - return -} - -// IDFromName is a convenience function that returns a server's ID given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - // Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractVolumes(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "volume"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"} - } -} diff --git a/v3/ecl/storage/v1/volumes/results.go b/v3/ecl/storage/v1/volumes/results.go deleted file mode 100644 index 19344ea..0000000 --- a/v3/ecl/storage/v1/volumes/results.go +++ /dev/null @@ -1,130 +0,0 @@ -package volumes - -import ( - "encoding/json" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Volume contains all the information associated with a Volume. -type Volume struct { - // API error in volume creation. - APIErrorMessage string `json:"api_error_message"` - // Unique identifier for the volume. - ID string `json:"id"` - // Current status of the volume. - Status string `json:"status"` - // Human-readable display name for the volume. - Name string `json:"name"` - // Human-readable description for the volume. - Description string `json:"description"` - // The volume size - Size int `json:"size"` - // The volume IOPS GB - IOPSPerGB string `json:"iops_per_gb"` - // The volume Throughput - Throughput string `json:"throughput"` - // The initiator_iqns for volume (in case ISCSI) - InitiatorIQNs []string `json:"initiator_iqns"` - // Relevant snapshot's IDs of this volume - SnapshotIDs []string `json:"snapshot_ids"` - // IP Addresses to connect this volume as target device. - TargetIPs []string `json:"target_ips"` - // The metadata of volume - Metadata map[string]string `json:"metadata"` - // The parent virtual storage ID to connect volume - VirtualStorageID string `json:"virtual_storage_id"` - // The availability zone of volume - AvailabilityZone string `json:"availability_zone"` - // The date when this volume was created. - CreatedAt time.Time `json:"-"` - // The date when this volume was last updated - UpdatedAt time.Time `json:"-"` - // Export rule of the volum - ExportRules []string `json:"export_rules"` - // Reservation parcentage about snapshot reservation capacity of the volume - PercentSnapshotReserveUsed int `json:"percent_snapshot_reserve_used"` - // Error in volume creation. - ErrorMessage string `json:"error_message"` -} - -// UnmarshalJSON creates JSON format of volume -func (r *Volume) UnmarshalJSON(b []byte) error { - type tmp Volume - var s struct { - tmp - CreatedAt eclcloud.JSONISO8601 `json:"created_at"` - UpdatedAt eclcloud.JSONISO8601 `json:"updated_at"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Volume(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.UpdatedAt = time.Time(s.UpdatedAt) - - return err -} - -// VolumePage is a pagination.pager that is returned from a call to the List function. -type VolumePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a ListResult contains no Volumes. -func (r VolumePage) IsEmpty() (bool, error) { - vss, err := ExtractVolumes(r) - return len(vss) == 0, err -} - -// ExtractVolumes extracts and returns Volumes. -// It is used while iterating over a Volumes.List call. -func ExtractVolumes(r pagination.Page) ([]Volume, error) { - var s []Volume - err := ExtractVolumesInto(r, &s) - return s, err -} - -type commonResult struct { - eclcloud.Result -} - -// Extract will get the Volume object out of the commonResult object. -func (r commonResult) Extract() (*Volume, error) { - var s Volume - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "volume") -} - -// ExtractVolumesInto is information expander for volume -func ExtractVolumesInto(r pagination.Page, v interface{}) error { - return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes") -} - -// CreateResult contains the response body and error from a Create request. -type CreateResult struct { - commonResult -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} - -// UpdateResult contains the response body and error from an Update request. -type UpdateResult struct { - commonResult -} - -// DeleteResult contains the response body and error from a Delete request. -type DeleteResult struct { - eclcloud.ErrResult -} diff --git a/v3/ecl/storage/v1/volumes/testing/doc.go b/v3/ecl/storage/v1/volumes/testing/doc.go deleted file mode 100644 index d083d20..0000000 --- a/v3/ecl/storage/v1/volumes/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains volume unit tests -package testing diff --git a/v3/ecl/storage/v1/volumes/testing/fixtures.go b/v3/ecl/storage/v1/volumes/testing/fixtures.go deleted file mode 100644 index 792cc24..0000000 --- a/v3/ecl/storage/v1/volumes/testing/fixtures.go +++ /dev/null @@ -1,371 +0,0 @@ -package testing - -import ( - "fmt" - "time" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/volumes" -) - -// Define parameters which are used in assertion. -// Additionally, kind of IDs are defined here. -const idVolume1 = "fb3efc23-ca8c-4eb5-b7f6-6fc66ff24f9c" -const idVolume2 = "3535de20-192d-4f5a-a74a-cd1a9c1bf747" - -const idVirtualStorage = "4f4971a5-899d-42b4-8442-24f17eac9683" - -const nameVolume1 = "virtual_storage_name_1" -const descriptionVolume1 = "virtual_storage_description_1" - -const nameVolume1Update = "virtual_storage_name_1-update" -const descriptionVolume1Update = "virtual_storage_description_1-update" - -const storageTime = "2015-05-17T18:14:34+0000" - -const idVolumeType = "3f4971a5-899d-42b4-8442-24f17eac9684" - -const IQN1 = "iqn.1986-03.com.nttcom:iscsihost.0" -const IQN2 = "iqn.1986-03.com.nttcom:iscsihost.1" - -// ListResponse is mocked response of volumes.List -var ListResponse = fmt.Sprintf(` -{ - "volumes": [ - { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s" - ], - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "%s", - "updated_at": "%s", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "available" - }, - { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "virtual_storage_name_2", - "description": "virtual_storage_description_2", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s" - ], - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "%s", - "updated_at": "%s", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "available" - } - ] -}`, - // for volume 1 - idVolume1, - idVirtualStorage, - nameVolume1, - descriptionVolume1, - IQN1, - storageTime, - storageTime, - // for volume 2 - idVolume2, - idVirtualStorage, - IQN1, - storageTime, - storageTime, -) - -// GetResponse is mocked format of volumes.Get -var GetResponse = fmt.Sprintf(` -{ - "volume": { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s" - ], - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "%s", - "updated_at": "%s", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "available" - } -}`, idVolume1, - idVirtualStorage, - nameVolume1, - descriptionVolume1, - IQN1, - storageTime, - storageTime, -) - -// CreateRequestBlock is mocked request for volumes.Create -var CreateRequestBlock = fmt.Sprintf(` -{ - "volume": { - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s" - ], - "availability_zone": "zone1_groupa" - } -}`, idVirtualStorage, - nameVolume1, - descriptionVolume1, - IQN1, -) - -// CreateResponseBlock is mocked response of volumes.Create -var CreateResponseBlock = fmt.Sprintf(` -{ - "volume": { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s" - ], - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "null", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "creating" - } -}`, idVolume1, - idVirtualStorage, - nameVolume1, - descriptionVolume1, - IQN1, -) - -// CreateRequestFile is mocked request for volumes.Create -var CreateRequestFile = fmt.Sprintf(` -{ - "volume": { - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 256, - "throughput": "50", - "availability_zone": "zone1_groupa" - } -}`, idVirtualStorage, - nameVolume1, - descriptionVolume1, -) - -// CreateResponseFile is mocked response of volumes.Create -var CreateResponseFile = fmt.Sprintf(` -{ - "volume": { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 256, - "throughput": "50", - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "null", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "creating" - } -}`, idVolume1, - idVirtualStorage, - nameVolume1, - descriptionVolume1, -) - -// UpdateRequest is mocked request of volumes.Update -var UpdateRequest = fmt.Sprintf(` -{ - "volume": { - "name": "%s", - "description": "%s", - "initiator_iqns": [ - "%s", - "%s" - ] - } -}`, nameVolume1Update, - descriptionVolume1Update, - IQN1, - IQN2, -) - -// UpdateResponse is mocked response of volumes.Update -var UpdateResponse = fmt.Sprintf(` -{ - "volume": { - "id" : "%s", - "virtual_storage_id": "%s", - "name" : "%s", - "description": "%s", - "size": 100, - "iops_per_gb": "2", - "initiator_iqns": [ - "%s", - "%s" - ], - "snapshot_ids": [], - "availability_zone": "zone1_groupa", - "created_at": "%s", - "updated_at": "%s", - "links": [ - { - "href": "http://storage.sdp.url:port/v1.0/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/13fea5a0-a36f-43e8-92ef-1cf472725dbe", - "rel": "self" - } - ], - "metadata": {"lun_id": "1"}, - "error_message": "", - "status": "updating" - } -}`, idVolume1, - idVirtualStorage, - nameVolume1Update, - descriptionVolume1Update, - IQN1, - IQN2, - storageTime, - storageTime, -) - -func getExpectedVolumesSlice() []volumes.Volume { - storageParsedTime, _ := time.Parse(eclcloud.ISO8601, storageTime) - - var volume1 = volumes.Volume{ - ID: idVolume1, - VirtualStorageID: idVirtualStorage, - Name: nameVolume1, - Description: descriptionVolume1, - Size: 100, - IOPSPerGB: "2", - InitiatorIQNs: []string{IQN1}, - SnapshotIDs: []string{}, - Metadata: map[string]string{"lun_id": "1"}, - CreatedAt: storageParsedTime, - UpdatedAt: storageParsedTime, - AvailabilityZone: "zone1_groupa", - Status: "available", - ErrorMessage: "", - } - - var volume2 = volumes.Volume{ - ID: idVolume2, - VirtualStorageID: idVirtualStorage, - Name: "virtual_storage_name_2", - Description: "virtual_storage_description_2", - Size: 100, - IOPSPerGB: "2", - InitiatorIQNs: []string{IQN1}, - SnapshotIDs: []string{}, - Metadata: map[string]string{"lun_id": "1"}, - CreatedAt: storageParsedTime, - UpdatedAt: storageParsedTime, - AvailabilityZone: "zone1_groupa", - Status: "available", - ErrorMessage: "", - } - - // ExpectedVolumesSlice is expected assertion target - ExpectedVolumesSlice := []volumes.Volume{ - volume1, - volume2, - } - - return ExpectedVolumesSlice -} - -func getExpectedCreateBlockStorageTypeVolume() volumes.Volume { - - result := volumes.Volume{ - ID: idVolume1, - VirtualStorageID: idVirtualStorage, - Name: nameVolume1, - Description: descriptionVolume1, - Size: 100, - IOPSPerGB: "2", - InitiatorIQNs: []string{IQN1}, - AvailabilityZone: "zone1_groupa", - SnapshotIDs: []string{}, - Metadata: map[string]string{"lun_id": "1"}, - Status: "creating", - ErrorMessage: "", - } - return result -} - -func getExpectedCreateFileStorageTypeVolume() volumes.Volume { - - result := volumes.Volume{ - ID: idVolume1, - VirtualStorageID: idVirtualStorage, - Name: nameVolume1, - Description: descriptionVolume1, - Size: 256, - Throughput: "50", - AvailabilityZone: "zone1_groupa", - SnapshotIDs: []string{}, - Metadata: map[string]string{"lun_id": "1"}, - Status: "creating", - ErrorMessage: "", - } - return result -} diff --git a/v3/ecl/storage/v1/volumes/testing/requests_test.go b/v3/ecl/storage/v1/volumes/testing/requests_test.go deleted file mode 100644 index 5e514da..0000000 --- a/v3/ecl/storage/v1/volumes/testing/requests_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/volumes" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/volumes/detail", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fakeclient.ServiceClient() - count := 0 - - volumes.List(client, volumes.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := volumes.ExtractVolumes(page) - if err != nil { - t.Errorf("Failed to extract volumes: %v", err) - return false, err - } - - th.CheckDeepEquals(t, getExpectedVolumesSlice(), actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } - -} - -func TestGetVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s", idVolume1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - volActual, err := volumes.Get( - fakeclient.ServiceClient(), idVolume1).Extract() - th.AssertNoErr(t, err) - volExpected := getExpectedVolumesSlice()[0] - th.CheckDeepEquals(t, &volExpected, volActual) -} - -func TestCreateBlockStorageTypeVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/volumes", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequestBlock) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) // 202 - - fmt.Fprintf(w, CreateResponseBlock) - }) - - createOpts := volumes.CreateOpts{ - VirtualStorageID: idVirtualStorage, - Name: nameVolume1, - Description: descriptionVolume1, - Size: 100, - IOPSPerGB: "2", - InitiatorIQNs: []string{IQN1}, - AvailabilityZone: "zone1_groupa", - } - volActual, err := volumes.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, volActual.Status, "creating") - - volExpected := getExpectedCreateBlockStorageTypeVolume() - th.AssertDeepEquals(t, &volExpected, volActual) -} - -func TestCreateFileStorageTypeVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/volumes", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, CreateRequestFile) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) // 202 - - fmt.Fprintf(w, CreateResponseFile) - }) - - createOpts := volumes.CreateOpts{ - VirtualStorageID: idVirtualStorage, - Name: nameVolume1, - Description: descriptionVolume1, - Size: 256, - Throughput: "50", - AvailabilityZone: "zone1_groupa", - } - volActual, err := volumes.Create(fakeclient.ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, volActual.Status, "creating") - - volExpected := getExpectedCreateFileStorageTypeVolume() - th.AssertDeepEquals(t, &volExpected, volActual) -} - -// TestUpdateBlockStorageTypeVolume covers file storage type's codes -// So, contrary to creation tests, tests for file storage type updating is not implemented -func TestUpdateBlockStorageTypeVolume(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc(fmt.Sprintf("/volumes/%s", idVolume1), - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PUT") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, UpdateRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusAccepted) - - fmt.Fprintf(w, UpdateResponse) - }) - - name := nameVolume1Update - description := descriptionVolume1Update - initiatorIQNs := []string{IQN1, IQN2} - - updateOpts := volumes.UpdateOpts{ - Name: &name, - Description: &description, - InitiatorIQNs: &initiatorIQNs, - } - - volActual, err := volumes.Update( - fakeclient.ServiceClient(), idVolume1, updateOpts).Extract() - - th.AssertNoErr(t, err) - - th.AssertEquals(t, volActual.Name, nameVolume1Update) - th.AssertEquals(t, volActual.Description, descriptionVolume1Update) - - th.AssertEquals(t, volActual.InitiatorIQNs[0], IQN1) - th.AssertEquals(t, volActual.InitiatorIQNs[1], IQN2) -} - -func TestDeleteVirtualStorage(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volumes/%s", idVolume1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - w.WriteHeader(http.StatusOK) - }) - - res := volumes.Delete(fakeclient.ServiceClient(), idVolume1) - th.AssertNoErr(t, res.Err) -} diff --git a/v3/ecl/storage/v1/volumes/urls.go b/v3/ecl/storage/v1/volumes/urls.go deleted file mode 100644 index 4865b34..0000000 --- a/v3/ecl/storage/v1/volumes/urls.go +++ /dev/null @@ -1,23 +0,0 @@ -package volumes - -import "github.com/nttcom/eclcloud/v3" - -func createURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("volumes") -} - -func listURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("volumes", "detail") -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("volumes", id) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return deleteURL(c, id) -} diff --git a/v3/ecl/storage/v1/volumes/util.go b/v3/ecl/storage/v1/volumes/util.go deleted file mode 100644 index 548329c..0000000 --- a/v3/ecl/storage/v1/volumes/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package volumes - -import ( - "github.com/nttcom/eclcloud/v3" -) - -// WaitForStatus will continually poll the resource, checking for a particular -// status. It will do this for the amount of seconds defined. -func WaitForStatus(c *eclcloud.ServiceClient, id, status string, secs int) error { - return eclcloud.WaitFor(secs, func() (bool, error) { - current, err := Get(c, id).Extract() - if err != nil { - return false, err - } - - if current.Status == status { - return true, nil - } - - return false, nil - }) -} diff --git a/v3/ecl/storage/v1/volumetypes/doc.go b/v3/ecl/storage/v1/volumetypes/doc.go deleted file mode 100644 index ad96f88..0000000 --- a/v3/ecl/storage/v1/volumetypes/doc.go +++ /dev/null @@ -1 +0,0 @@ -package volumetypes diff --git a/v3/ecl/storage/v1/volumetypes/requests.go b/v3/ecl/storage/v1/volumetypes/requests.go deleted file mode 100644 index 5461fbe..0000000 --- a/v3/ecl/storage/v1/volumetypes/requests.go +++ /dev/null @@ -1,85 +0,0 @@ -package volumetypes - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// Get retrieves the VolumeType with the provided ID. -// To extract the VolumeType object from the response, -// call the Extract method on the GetResult. -func Get(client *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// ListOptsBuilder allows extensions to add additional parameters to the List -// request. -type ListOptsBuilder interface { - ToVolumeTypeListQuery() (string, error) -} - -// ListOpts holds options for listing ToVolumeTypes. -// It is passed to the volumetypes.List function. -type ListOpts struct { - // Now there are no definiton as query params in API specification - // But do not remove this struct in future specification change. -} - -// ToVolumeTypeListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVolumeTypeListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns VolumeType optionally limited by the conditions provided in ListOpts. -func List(client *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(client) - if opts != nil { - query, err := opts.ToVolumeTypeListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return VolumeTypePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// IDFromName is a convienience function that returns a server's ID given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - // Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractVolumeTypes(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "volume_type"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "virtual_storage"} - } -} diff --git a/v3/ecl/storage/v1/volumetypes/results.go b/v3/ecl/storage/v1/volumetypes/results.go deleted file mode 100644 index bad2d23..0000000 --- a/v3/ecl/storage/v1/volumetypes/results.go +++ /dev/null @@ -1,71 +0,0 @@ -package volumetypes - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ExtraSpec is struct which corresponds to extra_specs object. -type ExtraSpec struct { - AvailableVolumeSize []int `json:"available_volume_size"` - AvailableVolumeThroughput []string `json:"available_volume_throughput"` - AvailableIOPSPerGB []string `json:"available_iops_per_gb"` -} - -// VolumeType contains all the information associated with a Virtual Storage. -type VolumeType struct { - // API error in virtual storage creation. - APIErrorMessage string `json:"api_error_message"` - // Unique identifier for the volume type. - ID string `json:"id"` - // Human-readable display name for the volume type. - Name string `json:"name"` - // Extra specification of volume type. - // This includes available_volume_size, and available_iops_per_gb, - // or available_throughput depending on storage service type. - ExtraSpecs ExtraSpec `json:"extra_specs"` -} - -// VolumeTypePage is a pagination.pager that is returned from a call to the List function. -type VolumeTypePage struct { - pagination.LinkedPageBase -} - -// IsEmpty returns true if a ListResult contains no VirtualStorages. -func (r VolumeTypePage) IsEmpty() (bool, error) { - vtypes, err := ExtractVolumeTypes(r) - return len(vtypes) == 0, err -} - -// ExtractVolumeTypes extracts and returns VolumeTypes. -// It is used while iterating over a volumetypes.List call. -func ExtractVolumeTypes(r pagination.Page) ([]VolumeType, error) { - var s []VolumeType - err := ExtractVolumeTypesInto(r, &s) - return s, err -} - -type commonResult struct { - eclcloud.Result -} - -// Extract will get the VolumeType object out of the commonResult object. -func (r commonResult) Extract() (*VolumeType, error) { - var s VolumeType - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "volume_type") -} - -// ExtractVolumeTypesInto is information expander for volume types -func ExtractVolumeTypesInto(r pagination.Page, v interface{}) error { - return r.(VolumeTypePage).Result.ExtractIntoSlicePtr(v, "volume_types") -} - -// GetResult contains the response body and error from a Get request. -type GetResult struct { - commonResult -} diff --git a/v3/ecl/storage/v1/volumetypes/testing/doc.go b/v3/ecl/storage/v1/volumetypes/testing/doc.go deleted file mode 100644 index fc6042c..0000000 --- a/v3/ecl/storage/v1/volumetypes/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains volume type unit tests -package testing diff --git a/v3/ecl/storage/v1/volumetypes/testing/fixtures.go b/v3/ecl/storage/v1/volumetypes/testing/fixtures.go deleted file mode 100644 index a7235b1..0000000 --- a/v3/ecl/storage/v1/volumetypes/testing/fixtures.go +++ /dev/null @@ -1,170 +0,0 @@ -package testing - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/volumetypes" -) - -// Define parameters which are used in assertion. -// Additionally, kind of IDs are defined here. -const idVolumeType1 = "6328d234-7939-4d61-9216-736de66d15f9" -const idVolumeType2 = "bf33db2a-d13e-11e5-8949-005056ab5d30" -const idVolumeType3 = "704db6e5-8a93-41a5-850d-405913600341" - -// ListResponse is mocked response of volumetypes.List -var ListResponse = fmt.Sprintf(` -{ - "volume_types": [ - { - "extra_specs": { - "available_volume_size": [ - 100, - 250, - 500, - 1000, - 2000, - 4000, - 8000, - 12000 - ], - "available_iops_per_gb": [ - "2", - "4" - ] - }, - "id": "%s", - "name": "piops_iscsi_na" - }, - { - "extra_specs": { - "available_volume_size": [ - 256, - 512 - ], - "available_volume_throughput": [ - "50", - "100", - "250", - "400" - ] - }, - "id": "%s", - "name": "pre_nfs_na" - }, - { - "extra_specs": { - "available_volume_size": [ - 1024, - 2048, - 3072, - 4096, - 5120, - 10240, - 15360, - 20480, - 25600, - 30720, - 35840, - 40960, - 46080, - 51200, - 56320, - 61440, - 66560, - 71680, - 76800, - 81920, - 87040, - 92160, - 97280, - 102400 - ] - }, - "id": "%s", - "name": "standard_nfs_na" - } - ] -}`, - idVolumeType1, - idVolumeType2, - idVolumeType3, -) - -// GetResponse is mocked format of volumetypes.Get -var GetResponse = fmt.Sprintf(` -{ - "volume_type": { - "extra_specs": { - "available_volume_size": [ - 100, - 250, - 500, - 1000, - 2000, - 4000, - 8000, - 12000 - ], - "available_iops_per_gb": [ - "2", - "4" - ] - }, - "id": "%s", - "name": "piops_iscsi_na" - } -}`, idVolumeType1, -) - -func getExpectedVolumeTypesSlice() []volumetypes.VolumeType { - - // For Block Storage Type - var volumetype1 = volumetypes.VolumeType{ - ID: idVolumeType1, - Name: "piops_iscsi_na", - ExtraSpecs: volumetypes.ExtraSpec{ - AvailableVolumeSize: []int{ - 100, 250, 500, 1000, 2000, 4000, 8000, 12000, - }, - AvailableIOPSPerGB: []string{"2", "4"}, - }, - } - - // For File Storage(Premium) Type - var volumetype2 = volumetypes.VolumeType{ - ID: idVolumeType2, - Name: "pre_nfs_na", - ExtraSpecs: volumetypes.ExtraSpec{ - AvailableVolumeSize: []int{ - 256, 512, - }, - AvailableVolumeThroughput: []string{ - "50", "100", "250", "400", - }, - }, - } - - // For File Storage(Standard) Type - var volumetype3 = volumetypes.VolumeType{ - ID: idVolumeType3, - Name: "standard_nfs_na", - ExtraSpecs: volumetypes.ExtraSpec{ - AvailableVolumeSize: []int{ - 1024, 2048, 3072, 4096, 5120, 10240, - 15360, 20480, 25600, 30720, 35840, 40960, - 46080, 51200, 56320, 61440, 66560, 71680, - 76800, 81920, 87040, 92160, 97280, 102400, - }, - }, - } - - // ExpectedVolumeTypesSlice is expected assertion target - ExpectedVolumeTypesSlice := []volumetypes.VolumeType{ - volumetype1, - volumetype2, - volumetype3, - } - - return ExpectedVolumeTypesSlice -} diff --git a/v3/ecl/storage/v1/volumetypes/testing/requests_test.go b/v3/ecl/storage/v1/volumetypes/testing/requests_test.go deleted file mode 100644 index ce8135b..0000000 --- a/v3/ecl/storage/v1/volumetypes/testing/requests_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/ecl/storage/v1/volumetypes" - "github.com/nttcom/eclcloud/v3/pagination" - - th "github.com/nttcom/eclcloud/v3/testhelper" - fakeclient "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestListVolumeType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/volume_types/detail", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := fakeclient.ServiceClient() - count := 0 - - volumetypes.List(client, volumetypes.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := volumetypes.ExtractVolumeTypes(page) - if err != nil { - t.Errorf("Failed to extract volume types: %v", err) - return false, err - } - - th.CheckDeepEquals(t, getExpectedVolumeTypesSlice(), actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } - -} - -func TestGetVolumeType(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/volume_types/%s", idVolumeType1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - vtActual, err := volumetypes.Get( - fakeclient.ServiceClient(), idVolumeType1).Extract() - th.AssertNoErr(t, err) - vtExpected := getExpectedVolumeTypesSlice()[0] - th.CheckDeepEquals(t, &vtExpected, vtActual) -} diff --git a/v3/ecl/storage/v1/volumetypes/urls.go b/v3/ecl/storage/v1/volumetypes/urls.go deleted file mode 100644 index 93967c3..0000000 --- a/v3/ecl/storage/v1/volumetypes/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package volumetypes - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func getURL(client *eclcloud.ServiceClient, id string) string { - return client.ServiceURL("volume_types", id) -} - -func listURL(client *eclcloud.ServiceClient) string { - return client.ServiceURL("volume_types", "detail") -} diff --git a/v3/ecl/utils/base_endpoint.go b/v3/ecl/utils/base_endpoint.go deleted file mode 100644 index 40080f7..0000000 --- a/v3/ecl/utils/base_endpoint.go +++ /dev/null @@ -1,28 +0,0 @@ -package utils - -import ( - "net/url" - "regexp" - "strings" -) - -// BaseEndpoint will return a URL without the /vX.Y -// portion of the URL. -func BaseEndpoint(endpoint string) (string, error) { - u, err := url.Parse(endpoint) - if err != nil { - return "", err - } - - u.RawQuery, u.Fragment = "", "" - - path := u.Path - versionRe := regexp.MustCompile("v[0-9.]+/?") - - if version := versionRe.FindString(path); version != "" { - versionIndex := strings.Index(path, version) - u.Path = path[:versionIndex] - } - - return u.String(), nil -} diff --git a/v3/ecl/utils/choose_version.go b/v3/ecl/utils/choose_version.go deleted file mode 100644 index 09b9524..0000000 --- a/v3/ecl/utils/choose_version.go +++ /dev/null @@ -1,111 +0,0 @@ -package utils - -import ( - "fmt" - "strings" - - "github.com/nttcom/eclcloud/v3" -) - -// Version is a supported API version, corresponding to a vN package within the appropriate service. -type Version struct { - ID string - Suffix string - Priority int -} - -var goodStatus = map[string]bool{ - "current": true, - "supported": true, - "stable": true, -} - -// ChooseVersion queries the base endpoint of an API to choose the most recent non-experimental alternative from a service's -// published versions. -// It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint. -func ChooseVersion(client *eclcloud.ProviderClient, recognized []*Version) (*Version, string, error) { - type linkResp struct { - Href string `json:"href"` - Rel string `json:"rel"` - } - - type valueResp struct { - ID string `json:"id"` - Status string `json:"status"` - Links []linkResp `json:"links"` - } - - type versionsResp struct { - Values []valueResp `json:"values"` - } - - type response struct { - Versions versionsResp `json:"versions"` - } - - normalize := func(endpoint string) string { - if !strings.HasSuffix(endpoint, "/") { - return endpoint + "/" - } - return endpoint - } - identityEndpoint := normalize(client.IdentityEndpoint) - - // If a full endpoint is specified, check version suffixes for a match first. - for _, v := range recognized { - if strings.HasSuffix(identityEndpoint, v.Suffix) { - return v, identityEndpoint, nil - } - } - - var resp response - _, err := client.Request("GET", client.IdentityBase, &eclcloud.RequestOpts{ - JSONResponse: &resp, - OkCodes: []int{200, 300}, - }) - - if err != nil { - return nil, "", err - } - - var highest *Version - var endpoint string - - for _, value := range resp.Versions.Values { - href := "" - for _, link := range value.Links { - if link.Rel == "self" { - href = normalize(link.Href) - } - } - - for _, version := range recognized { - if strings.Contains(value.ID, version.ID) { - // Prefer a version that exactly matches the provided endpoint. - if href == identityEndpoint { - if href == "" { - return nil, "", fmt.Errorf("endpoint missing in version %s response from %s", value.ID, client.IdentityBase) - } - return version, href, nil - } - - // Otherwise, find the highest-priority version with a whitelisted status. - if goodStatus[strings.ToLower(value.Status)] { - if highest == nil || version.Priority > highest.Priority { - highest = version - endpoint = href - } - } - } - } - } - - if highest == nil { - return nil, "", fmt.Errorf("no supported version available from endpoint %s", client.IdentityBase) - } - if endpoint == "" { - return nil, "", fmt.Errorf("endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) - } - - return highest, endpoint, nil -} diff --git a/v3/ecl/vna/v1/appliance_plans/doc.go b/v3/ecl/vna/v1/appliance_plans/doc.go deleted file mode 100644 index 2b9d5dd..0000000 --- a/v3/ecl/vna/v1/appliance_plans/doc.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Package appliance_plans contains functionality for working with -ECL Virtual Network Appliance Plan resources. - -Example to List Virtual Network Appliance Plans - - listOpts := appliance_plans.ListOpts{ - Description: "general", - } - - allPages, err := appliance_plans.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allVirtualNetworkAppliancePlans, err := appliance_plans.ExtractVirtualNetworkAppliancePlans(allPages) - if err != nil { - panic(err) - } - - for _, virtualNetworkAppliancePlan := range allVirtualNetworkAppliancePlans { - fmt.Printf("%+v\n", virtualNetworkAppliancePlan) - } - -Example to Show Virtual Network Appliance Plan - - virtualNetworkAppliancePlanID := "37556569-87f2-4699-b5ff-bf38e7cbf8a7" - - virtualNetworkAppliancePlan, err := appliance_plans.Get(networkClient, virtualNetworkAppliancePlanID, nil).Extract() - if err != nil { - panic(err) - } - - fmt.Printf("%+v\n", virtualNetworkAppliancePlan) - -*/ -package appliance_plans diff --git a/v3/ecl/vna/v1/appliance_plans/requests.go b/v3/ecl/vna/v1/appliance_plans/requests.go deleted file mode 100644 index 50411e6..0000000 --- a/v3/ecl/vna/v1/appliance_plans/requests.go +++ /dev/null @@ -1,111 +0,0 @@ -package appliance_plans - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the Virtual Network Appliance Plan attributes you want to see returned. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - Description string `q:"description"` - ApplianceType string `q:"appliance_type"` - Version string `q:"version"` - Flavor string `q:"flavor"` - NumberOfInterfaces int `q:"number_of_interfaces"` - Enabled bool `q:"enabled"` - MaxNumberOfAap int `q:"max_number_of_aap"` - Details bool `q:"details"` - AvailabilityZone string `q:"availability_zone"` - AvailabilityZoneAvailable bool `q:"availability_zone.available"` -} - -// ToVirtualNetworkAppliancePlanListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVirtualNetworkAppliancePlanListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// Virtual Network Appliance Plans. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *eclcloud.ServiceClient, opts ListOpts) pagination.Pager { - url := listURL(c) - query, err := opts.ToVirtualNetworkAppliancePlanListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return VirtualNetworkAppliancePlanPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// GetOptsBuilder allows extensions to add additional parameters to -// the Virtual Network Appliance Plan API request -type GetOptsBuilder interface { - ToProcessQuery() (string, error) -} - -// GetOpts represents result of Virtual Network Appliance Plan API response. -type GetOpts struct { - VirtualNetworkAppliancePlanId string `q:"virtual_network_appliance_plan_id"` - Details bool `q:"details"` -} - -// ToProcessQuery formats a GetOpts into a query string. -func (opts GetOpts) ToProcessQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// Get retrieves a specific Virtual Network Appliance Plan based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string, opts GetOptsBuilder) (r GetResult) { - url := getURL(c, id) - if opts != nil { - query, _ := opts.ToProcessQuery() - url += query - } - _, r.Err = c.Get(url, &r.Body, nil) - return -} - -// IDFromName is a convenience function that returns a Virtual Network Appliance Plan's ID, -// given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractVirtualNetworkAppliancePlans(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "virtual_network_appliance_plan"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "virtual_network_appliance_plan"} - } -} diff --git a/v3/ecl/vna/v1/appliance_plans/results.go b/v3/ecl/vna/v1/appliance_plans/results.go deleted file mode 100644 index 06a8853..0000000 --- a/v3/ecl/vna/v1/appliance_plans/results.go +++ /dev/null @@ -1,98 +0,0 @@ -package appliance_plans - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result and extracts a Virtual Network Appliance Plan resource. -func (r commonResult) Extract() (*VirtualNetworkAppliancePlan, error) { - var s struct { - VirtualNetworkAppliancePlan *VirtualNetworkAppliancePlan `json:"virtual_network_appliance_plan"` - } - err := r.ExtractInto(&s) - return s.VirtualNetworkAppliancePlan, err -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Virtual Network Appliance Plan. -type GetResult struct { - commonResult -} - -// License of Virtual Network Appliance -type License struct { - LicenseType string `json:"license_type"` -} - -// Availability Zone of Virtual Network Appliance -type AvailabilityZone struct { - AvailabilityZone string `json:"availability_zone"` - Available bool `json:"available"` - Rank int `json:"rank"` -} - -// VirtualNetworkAppliancePlan represents a Virtual Network Appliance Plan. -// See package documentation for a top-level description of what this is. -type VirtualNetworkAppliancePlan struct { - - // UUID representing the Virtual Network Appliance Plan. - ID string `json:"id"` - - // Name of the Virtual Network Appliance Plan. - Name string `json:"name"` - - // Description is description - Description string `json:"description"` - - // Type of appliance - ApplianceType string `json:"appliance_type"` - - // Version name - Version string `json:"version"` - - // Nova flavor - Flavor string `json:"flavor"` - - // Number of Interfaces - NumberOfInterfaces int `json:"number_of_interfaces"` - - // Is user allowed to create new firewalls with this plan. - Enabled bool `json:"enabled"` - - // Max Number of allowed_address_pairs - MaxNumberOfAap int `json:"max_number_of_aap"` - - // Licenses - Licenses []License `json:"licenses"` - - // AvailabilityZones - AvailabilityZones []AvailabilityZone `json:"availability_zones"` -} - -// VirtualNetworkAppliancePlanPage is the page returned by a pager when traversing over a collection -// of virtual network appliance plans. -type VirtualNetworkAppliancePlanPage struct { - pagination.LinkedPageBase -} - -// IsEmpty checks whether a VirtualNetworkAppliancePlanPage struct is empty. -func (r VirtualNetworkAppliancePlanPage) IsEmpty() (bool, error) { - is, err := ExtractVirtualNetworkAppliancePlans(r) - return len(is) == 0, err -} - -// ExtractVirtualNetworkAppliancePlans accepts a Page struct, specifically a VirtualNetworkAppliancePlanPage struct, -// and extracts the elements into a slice of Virtual Network Appliance Plan structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractVirtualNetworkAppliancePlans(r pagination.Page) ([]VirtualNetworkAppliancePlan, error) { - var s struct { - VirtualNetworkAppliancePlans []VirtualNetworkAppliancePlan `json:"virtual_network_appliance_plans"` - } - err := (r.(VirtualNetworkAppliancePlanPage)).ExtractInto(&s) - return s.VirtualNetworkAppliancePlans, err -} diff --git a/v3/ecl/vna/v1/appliance_plans/testing/doc.go b/v3/ecl/vna/v1/appliance_plans/testing/doc.go deleted file mode 100644 index d17d407..0000000 --- a/v3/ecl/vna/v1/appliance_plans/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Virtual Network Appliance Plans unit tests -package testing diff --git a/v3/ecl/vna/v1/appliance_plans/testing/fixtures.go b/v3/ecl/vna/v1/appliance_plans/testing/fixtures.go deleted file mode 100644 index 046de18..0000000 --- a/v3/ecl/vna/v1/appliance_plans/testing/fixtures.go +++ /dev/null @@ -1,195 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3/ecl/vna/v1/appliance_plans" -) - -const ListResponse = ` -{ - "virtual_network_appliance_plans": [ - { - "id": "37556569-87f2-4699-b5ff-bf38e7cbf8a7", - "name": "appliance_plans_name", - "description": "appliance_plans_description", - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "version": "", - "flavor": "2CPU-8GB", - "number_of_interfaces": 8, - "enabled": true, - "max_number_of_aap": 1, - "licenses": [ - { - "license_type": "STD" - } - ], - "availability_zones": [ - { - "availability_zone": "zone1_groupa", - "available": true, - "rank": 1 - }, - { - "availability_zone": "zone1_groupb", - "available": false, - "rank": 2 - } - ] - } - ] -} -` -const GetResponse = ` -{ - "virtual_network_appliance_plan": { - "id": "6589b37a-cf82-4918-96fe-255683f78e76", - "name": "vSRX_15.1X49-D100_2CPU_4GB_8IF_STD", - "description": "vSRX_15.1X49-D100_2CPU_4GB_8IF_STD", - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "version": "15.1X49-D100", - "flavor": "VSRX-2CPU-4GB", - "number_of_interfaces": 8, - "enabled": true, - "max_number_of_aap": 1, - "licenses": [ - { - "license_type": "STD" - } - ], - "availability_zones": [ - { - "availability_zone": "zone1_groupa", - "available": true, - "rank": 1 - }, - { - "availability_zone": "zone1_groupb", - "available": false, - "rank": 2 - } - ] - } -} -` - -var VirtualNetworkAppliancePlan1 = appliance_plans.VirtualNetworkAppliancePlan{ - ID: "37556569-87f2-4699-b5ff-bf38e7cbf8a7", - Name: "appliance_plans_name", - Description: "appliance_plans_description", - ApplianceType: "ECL::VirtualNetworkAppliance::VSRX", - Version: "", - Flavor: "2CPU-8GB", - NumberOfInterfaces: 8, - Enabled: true, - MaxNumberOfAap: 1, - Licenses: []appliance_plans.License{ - { - LicenseType: "STD", - }, - }, - AvailabilityZones: []appliance_plans.AvailabilityZone{ - { - AvailabilityZone: "zone1_groupa", - Available: true, - Rank: 1, - }, - { - AvailabilityZone: "zone1_groupb", - Available: false, - Rank: 2, - }, - }, -} - -var VirtualNetworkApplianceDetail = appliance_plans.VirtualNetworkAppliancePlan{ - ID: "6589b37a-cf82-4918-96fe-255683f78e76", - Name: "vSRX_15.1X49-D100_2CPU_4GB_8IF_STD", - Description: "vSRX_15.1X49-D100_2CPU_4GB_8IF_STD", - ApplianceType: "ECL::VirtualNetworkAppliance::VSRX", - Version: "15.1X49-D100", - Flavor: "VSRX-2CPU-4GB", - NumberOfInterfaces: 8, - Enabled: true, - MaxNumberOfAap: 1, - Licenses: []appliance_plans.License{ - { - LicenseType: "STD", - }, - }, - AvailabilityZones: []appliance_plans.AvailabilityZone{ - { - AvailabilityZone: "zone1_groupa", - Available: true, - Rank: 1, - }, - { - AvailabilityZone: "zone1_groupb", - Available: false, - Rank: 2, - }, - }, -} - -var ExpectedVirtualNetworkAppliancePlanSlice = []appliance_plans.VirtualNetworkAppliancePlan{VirtualNetworkAppliancePlan1} - -const ListResponseDuplicatedNames = ` -{ - "virtual_network_appliance_plans": [ - { - "id": "37556569-87f2-4699-b5ff-bf38e7cbf8a7", - "name": "appliance_plans_name", - "description": "appliance_plans_description", - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "version": "", - "flavor": "2CPU-8GB", - "number_of_interfaces": 8, - "enabled": true, - "max_number_of_aap": 1, - "licenses": [ - { - "license_type": "STD" - } - ], - "availability_zones": [ - { - "availability_zone": "zone1_groupa", - "available": true, - "rank": 1 - }, - { - "availability_zone": "zone1_groupb", - "available": false, - "rank": 2 - } - ] - }, - { - "id": "6589b37a-cf82-4918-96fe-255683f78e76", - "name": "appliance_plans_name", - "description": "appliance_plans_description", - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "version": "", - "flavor": "2CPU-8GB", - "number_of_interfaces": 8, - "enabled": true, - "max_number_of_aap": 1, - "licenses": [ - { - "license_type": "STD" - } - ], - "availability_zones": [ - { - "availability_zone": "zone1_groupa", - "available": true, - "rank": 1 - }, - { - "availability_zone": "zone1_groupb", - "available": false, - "rank": 2 - } - ] - } - ] -} -` diff --git a/v3/ecl/vna/v1/appliance_plans/testing/request_test.go b/v3/ecl/vna/v1/appliance_plans/testing/request_test.go deleted file mode 100644 index b9340da..0000000 --- a/v3/ecl/vna/v1/appliance_plans/testing/request_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/vna/v1/appliance_plans" - "github.com/nttcom/eclcloud/v3/pagination" - th "github.com/nttcom/eclcloud/v3/testhelper" - cli "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -const TokenID = cli.TokenID - -func ServiceClient() *eclcloud.ServiceClient { - sc := cli.ServiceClient() - sc.ResourceBase = sc.Endpoint + "v1.0/" - return sc -} - -func TestListAppliancePlans(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/v1.0/virtual_network_appliance_plans", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, ListResponse) - }) - - client := ServiceClient() - count := 0 - - appliance_plans.List(client, appliance_plans.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := appliance_plans.ExtractVirtualNetworkAppliancePlans(page) - if err != nil { - t.Errorf("Failed to extract Virtual Network Appliance Plans: %v", err) - return false, nil - } - - th.CheckDeepEquals(t, ExpectedVirtualNetworkAppliancePlanSlice, actual) - - return true, nil - }) - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetAppliancePlan(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1.0/virtual_network_appliance_plans/6589b37a-cf82-4918-96fe-255683f78e76", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, GetResponse) - }) - - s, err := appliance_plans.Get(ServiceClient(), "6589b37a-cf82-4918-96fe-255683f78e76", appliance_plans.GetOpts{}).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &VirtualNetworkApplianceDetail, s) -} - -func TestIDFromName(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1.0/virtual_network_appliance_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := ServiceClient() - - expectedID := "37556569-87f2-4699-b5ff-bf38e7cbf8a7" - actualID, err := appliance_plans.IDFromName(client, "appliance_plans_name") - - th.AssertNoErr(t, err) - th.AssertEquals(t, expectedID, actualID) -} - -func TestIDFromNameNoResult(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1.0/virtual_network_appliance_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponse) - }) - - client := ServiceClient() - - _, err := appliance_plans.IDFromName(client, "appliance_plans_nameX") - - if err == nil { - t.Fatalf("Expected error, got none") - } - -} - -func TestIDFromNameDuplicated(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1.0/virtual_network_appliance_plans", func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprintf(w, ListResponseDuplicatedNames) - }) - - client := ServiceClient() - - _, err := appliance_plans.IDFromName(client, "appliance_plans_name") - - if err == nil { - t.Fatalf("Expected error, got none") - } -} diff --git a/v3/ecl/vna/v1/appliance_plans/urls.go b/v3/ecl/vna/v1/appliance_plans/urls.go deleted file mode 100644 index 5e430b8..0000000 --- a/v3/ecl/vna/v1/appliance_plans/urls.go +++ /dev/null @@ -1,19 +0,0 @@ -package appliance_plans - -import "github.com/nttcom/eclcloud/v3" - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("virtual_network_appliance_plans", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("virtual_network_appliance_plans") -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/ecl/vna/v1/appliances/doc.go b/v3/ecl/vna/v1/appliances/doc.go deleted file mode 100644 index dca0884..0000000 --- a/v3/ecl/vna/v1/appliances/doc.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Package appliances contains functionality for working with -ECL Commnon Function Gateway resources. - -Example to List VirtualNetworkAppliances - - listOpts := virtual_network_appliances.ListOpts{ - TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", - } - - allPages, err := virtual_network_appliances.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allVirtualNetworkAppliances, err := virtual_network_appliances.ExtractVirtualNetworkAppliances(allPages) - if err != nil { - panic(err) - } - - for _, virtual_network_appliances := range allVirtualNetworkAppliances { - fmt.Printf("%+v", virtual_network_appliances) - } - -Example to Create a virtual_network_appliances - - createOpts := virtual_network_appliances.CreateOpts{ - Name: "network_1", - } - - virtual_network_appliances, err := virtual_network_appliances.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a virtual_network_appliances - - virtualNetworkApplianceID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - - updateOpts := virtual_network_appliances.UpdateOpts{ - Name: "new_name", - } - - virtual_network_appliances, err := virtual_network_appliances.Update(networkClient, virtualNetworkApplianceID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a virtual_network_appliances - - virtualNetworkApplianceID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - err := virtual_network_appliances.Delete(networkClient, virtualNetworkApplianceID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package appliances diff --git a/v3/ecl/vna/v1/appliances/requests.go b/v3/ecl/vna/v1/appliances/requests.go deleted file mode 100644 index 65debde..0000000 --- a/v3/ecl/vna/v1/appliances/requests.go +++ /dev/null @@ -1,326 +0,0 @@ -package appliances - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToVirtualNetworkApplianceListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the virtual network appliance attributes you want to see returned. -type ListOpts struct { - Name string `q:"name"` - ID string `q:"id"` - ApplianceType string `q:"appliance_type"` - Description string `q:"description"` - AvailabilityZone string `q:"availability_zone"` - OSMonitoringStatus string `q:"os_monitoring_status"` - OSLoginStatus string `q:"os_login_status"` - VMStatus string `q:"vm_status"` - OperationStatus string `q:"operation_status"` - VirtualNetworkAppliancePlanID string `q:"virtual_network_appliance_plan_id"` - TenantID string `q:"tenant_id"` -} - -// ToVirtualNetworkApplianceListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToVirtualNetworkApplianceListQuery() (string, error) { - q, err := eclcloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// virtual network appliances. -// It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *eclcloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToVirtualNetworkApplianceListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return AppliancePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific virtual network appliance based on its unique ID. -func Get(c *eclcloud.ServiceClient, id string) (r GetResult) { - _, r.Err = c.Get(getURL(c, id), &r.Body, nil) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToApplianceCreateMap() (map[string]interface{}, error) -} - -/* -Parameters for Create -*/ - -// CreateOptsFixedIP represents fixed ip information in virtual network appliance creation. -type CreateOptsFixedIP struct { - IPAddress string `json:"ip_address" required:"true"` -} - -// CreateOptsInterface represents each parameters in virtual network appliance creation. -type CreateOptsInterface struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - NetworkID string `json:"network_id" required:"true"` - Tags map[string]string `json:"tags,omitempty"` - FixedIPs *[]CreateOptsFixedIP `json:"fixed_ips,omitempty"` -} - -// CreateOptsInterfaces represents 1st interface in virtual network appliance creation. -type CreateOptsInterfaces struct { - Interface1 *CreateOptsInterface `json:"interface_1,omitempty"` - Interface2 *CreateOptsInterface `json:"interface_2,omitempty"` - Interface3 *CreateOptsInterface `json:"interface_3,omitempty"` - Interface4 *CreateOptsInterface `json:"interface_4,omitempty"` - Interface5 *CreateOptsInterface `json:"interface_5,omitempty"` - Interface6 *CreateOptsInterface `json:"interface_6,omitempty"` - Interface7 *CreateOptsInterface `json:"interface_7,omitempty"` - Interface8 *CreateOptsInterface `json:"interface_8,omitempty"` -} - -// CreateOpts represents options used to create a virtual network appliance. -type CreateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - DefaultGateway string `json:"default_gateway,omitempty"` - AvailabilityZone string `json:"availability_zone,omitempty"` - VirtualNetworkAppliancePlanID string `json:"virtual_network_appliance_plan_id" required:"true"` - TenantID string `json:"tenant_id,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - Interfaces *CreateOptsInterfaces `json:"interfaces,omitempty"` -} - -// ToApplianceCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToApplianceCreateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_network_appliance") -} - -// Create accepts a CreateOpts struct and creates a new virtual network appliance -// using the values provided. -// This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -func Create(c *eclcloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToApplianceCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Post(createURL(c), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToApplianceUpdateMap() (map[string]interface{}, error) -} - -/* -Update for Allowed Address Pairs -*/ - -// UpdateAllowedAddressPairAddressInfo represents options used to -// update virtual network appliance allowed address pairs. -type UpdateAllowedAddressPairAddressInfo struct { - IPAddress string `json:"ip_address" required:"true"` - MACAddress *string `json:"mac_address" required:"true"` - Type *string `json:"type" required:"true"` - VRID *interface{} `json:"vrid" required:"true"` -} - -// UpdateAllowedAddressPairInterface represents -// allowed address pairs list in update options used to -// update virtual network appliance allowed address pairs. -type UpdateAllowedAddressPairInterface struct { - AllowedAddressPairs *[]UpdateAllowedAddressPairAddressInfo `json:"allowed_address_pairs,omitempty"` -} - -// UpdateAllowedAddressPairInterfaces represents -// interface list of update options used to -// update virtual network appliance allowed address pairs. -type UpdateAllowedAddressPairInterfaces struct { - Interface1 *UpdateAllowedAddressPairInterface `json:"interface_1,omitempty"` - Interface2 *UpdateAllowedAddressPairInterface `json:"interface_2,omitempty"` - Interface3 *UpdateAllowedAddressPairInterface `json:"interface_3,omitempty"` - Interface4 *UpdateAllowedAddressPairInterface `json:"interface_4,omitempty"` - Interface5 *UpdateAllowedAddressPairInterface `json:"interface_5,omitempty"` - Interface6 *UpdateAllowedAddressPairInterface `json:"interface_6,omitempty"` - Interface7 *UpdateAllowedAddressPairInterface `json:"interface_7,omitempty"` - Interface8 *UpdateAllowedAddressPairInterface `json:"interface_8,omitempty"` -} - -// UpdateAllowedAddressPairOpts represents -// parent element of interfaces in update options used to -// update virtual network appliance allowed address pairs. -type UpdateAllowedAddressPairOpts struct { - Interfaces *UpdateAllowedAddressPairInterfaces `json:"interfaces,omitempty"` -} - -// ToApplianceUpdateMap builds a request body from UpdateAllowedAddressPairOpts. -func (opts UpdateAllowedAddressPairOpts) ToApplianceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_network_appliance") -} - -/* -Update for FixedIP (includes network_id) -*/ - -// UpdateFixedIPAddressInfo represents ip address part -// of virtual network appliance update. -type UpdateFixedIPAddressInfo struct { - IPAddress string `json:"ip_address" required:"true"` -} - -// UpdateFixedIPInterface represents each interface information -// in updating network connection and fixed ip address -// of virtual network appliance. -type UpdateFixedIPInterface struct { - NetworkID *string `json:"network_id,omitempty"` - FixedIPs *[]UpdateFixedIPAddressInfo `json:"fixed_ips,omitempty"` -} - -// UpdateFixedIPInterfaces represents -// interface list of update options used to -// update virtual network appliance network connection and fixed ips. -type UpdateFixedIPInterfaces struct { - Interface1 *UpdateFixedIPInterface `json:"interface_1,omitempty"` - Interface2 *UpdateFixedIPInterface `json:"interface_2,omitempty"` - Interface3 *UpdateFixedIPInterface `json:"interface_3,omitempty"` - Interface4 *UpdateFixedIPInterface `json:"interface_4,omitempty"` - Interface5 *UpdateFixedIPInterface `json:"interface_5,omitempty"` - Interface6 *UpdateFixedIPInterface `json:"interface_6,omitempty"` - Interface7 *UpdateFixedIPInterface `json:"interface_7,omitempty"` - Interface8 *UpdateFixedIPInterface `json:"interface_8,omitempty"` -} - -// UpdateFixedIPOpts represents -// parent element of interfaces in update options used to -// update virtual network appliance network connection and fixed ips. -type UpdateFixedIPOpts struct { - Interfaces *UpdateFixedIPInterfaces `json:"interfaces,omitempty"` -} - -// ToApplianceUpdateMap builds a request body from UpdateFixedIPOpts. -func (opts UpdateFixedIPOpts) ToApplianceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_network_appliance") -} - -/* -Update for Metadata -*/ - -// UpdateMetadataInterface represents options used to -// update virtual network appliance metadata of interface. -type UpdateMetadataInterface struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` -} - -// UpdateMetadataInterfaces represents -// list of interfaces for updating virtual network appliance metadata. -type UpdateMetadataInterfaces struct { - Interface1 *UpdateMetadataInterface `json:"interface_1,omitempty"` - Interface2 *UpdateMetadataInterface `json:"interface_2,omitempty"` - Interface3 *UpdateMetadataInterface `json:"interface_3,omitempty"` - Interface4 *UpdateMetadataInterface `json:"interface_4,omitempty"` - Interface5 *UpdateMetadataInterface `json:"interface_5,omitempty"` - Interface6 *UpdateMetadataInterface `json:"interface_6,omitempty"` - Interface7 *UpdateMetadataInterface `json:"interface_7,omitempty"` - Interface8 *UpdateMetadataInterface `json:"interface_8,omitempty"` -} - -// UpdateMetadataOpts represents -// metadata of virtual network appliance itself and -// pararent element for list of interfaces -// which are used by virtual network appliance metadata update. -type UpdateMetadataOpts struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Tags *map[string]string `json:"tags,omitempty"` - Interfaces *UpdateMetadataInterfaces `json:"interfaces,omitempty"` -} - -// ToApplianceUpdateMap builds a request body from UpdateOpts. -func (opts UpdateMetadataOpts) ToApplianceUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "virtual_network_appliance") -} - -/* -Update Common -*/ - -// Update accepts a UpdateOpts struct and updates an existing virtual network appliance -// using the values provided. For more information, see the Create function. -func Update(c *eclcloud.ServiceClient, virtualNetworkApplianceID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToApplianceUpdateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = c.Patch(updateURL(c, virtualNetworkApplianceID), b, &r.Body, &eclcloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Delete accepts a unique ID and deletes the virtual network appliance associated with it. -func Delete(c *eclcloud.ServiceClient, virtualNetworkApplianceID string) (r DeleteResult) { - _, r.Err = c.Delete(deleteURL(c, virtualNetworkApplianceID), nil) - return -} - -// IDFromName is a convenience function that returns a virtual network appliance's -// ID, given its name. -func IDFromName(client *eclcloud.ServiceClient, name string) (string, error) { - count := 0 - id := "" - - listOpts := ListOpts{ - Name: name, - } - - pages, err := List(client, listOpts).AllPages() - if err != nil { - return "", err - } - - all, err := ExtractAppliances(pages) - if err != nil { - return "", err - } - - for _, s := range all { - if s.Name == name { - count++ - id = s.ID - } - } - - switch count { - case 0: - return "", eclcloud.ErrResourceNotFound{Name: name, ResourceType: "virtual_network_appliance"} - case 1: - return id, nil - default: - return "", eclcloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "virtual_network_appliance"} - } -} diff --git a/v3/ecl/vna/v1/appliances/results.go b/v3/ecl/vna/v1/appliances/results.go deleted file mode 100644 index 05def8a..0000000 --- a/v3/ecl/vna/v1/appliances/results.go +++ /dev/null @@ -1,150 +0,0 @@ -package appliances - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/pagination" -) - -type commonResult struct { - eclcloud.Result -} - -// Extract is a function that accepts a result -// and extracts a virtual network appliance resource. -func (r commonResult) Extract() (*Appliance, error) { - var vna Appliance - err := r.ExtractInto(&vna) - return &vna, err -} - -// Extract interprets any commonResult as a Virtual Network Appliance, if possible. -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "virtual_network_appliance") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Virtual Network Appliance. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Virtual Network Appliance. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Virtual Network Appliance. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - eclcloud.ErrResult -} - -// FixedIPInResponse represents each element of fixed ips -// of virtual network appliance. -type FixedIPInResponse struct { - IPAddress string `json:"ip_address"` - SubnetID string `json:"subnet_id"` -} - -// AllowedAddressPairInResponse represents each element of -// allowed address pair of virtual network appliance. -type AllowedAddressPairInResponse struct { - IPAddress string `json:"ip_address"` - MACAddress string `json:"mac_address"` - Type string `json:"type"` - VRID interface{} `json:"vrid"` -} - -// InterfaceInResponse works as parent element of -// each interface of virtual network appliance. -type InterfaceInResponse struct { - Name string `json:"name"` - Description string `json:"description"` - NetworkID string `json:"network_id"` - Updatable bool `json:"updatable"` - Tags map[string]string `json:"tags"` - FixedIPs []FixedIPInResponse `json:"fixed_ips"` - AllowedAddressPairs []AllowedAddressPairInResponse `json:"allowed_address_pairs"` -} - -// InterfacesInResponse works as list of interfaces -// of virtual network appliance. -type InterfacesInResponse struct { - Interface1 InterfaceInResponse `json:"interface_1"` - Interface2 InterfaceInResponse `json:"interface_2"` - Interface3 InterfaceInResponse `json:"interface_3"` - Interface4 InterfaceInResponse `json:"interface_4"` - Interface5 InterfaceInResponse `json:"interface_5"` - Interface6 InterfaceInResponse `json:"interface_6"` - Interface7 InterfaceInResponse `json:"interface_7"` - Interface8 InterfaceInResponse `json:"interface_8"` -} - -// Appliance represents, well, a virtual network appliance. -type Appliance struct { - Name string `json:"name"` - ID string `json:"id"` - ApplianceType string `json:"appliance_type"` - Description string `json:"description"` - DefaultGateway string `json:"default_gateway"` - AvailabilityZone string `json:"availability_zone"` - OSMonitoringStatus string `json:"os_monitoring_status"` - OSLoginStatus string `json:"os_login_status"` - VMStatus string `json:"vm_status"` - OperationStatus string `json:"operation_status"` - AppliancePlanID string `json:"virtual_network_appliance_plan_id"` - TenantID string `json:"tenant_id"` - Username string `json:"username"` - Password string `json:"password"` - Tags map[string]string `json:"tags"` - Interfaces InterfacesInResponse `json:"interfaces"` -} - -// AppliancePage is the page returned by a pager -// when traversing over a collection of virtual network appliance. -type AppliancePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of virtual network appliance -// has reached the end of a page and the pager seeks to traverse over a new one. -// In order to do this, it needs to construct the next page's URL. -func (r AppliancePage) NextPageURL() (string, error) { - var s struct { - Links []eclcloud.Link `json:"appliances_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return eclcloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a AppliancePage struct is empty. -func (r AppliancePage) IsEmpty() (bool, error) { - is, err := ExtractAppliances(r) - return len(is) == 0, err -} - -// ExtractAppliances accepts a Page struct, -// specifically a NetworkPage struct, and extracts the elements -// into a slice of Virtual Network Appliance structs. -// In other words, a generic collection is mapped into a relevant slice. -func ExtractAppliances(r pagination.Page) ([]Appliance, error) { - var s []Appliance - err := ExtractAppliancesInto(r, &s) - return s, err -} - -// ExtractAppliancesInto interprets the results of a single page from a List() call, -// producing a slice of Server entities. -func ExtractAppliancesInto(r pagination.Page, v interface{}) error { - return r.(AppliancePage).Result.ExtractIntoSlicePtr(v, "virtual_network_appliances") -} diff --git a/v3/ecl/vna/v1/appliances/testing/doc.go b/v3/ecl/vna/v1/appliances/testing/doc.go deleted file mode 100644 index f740d23..0000000 --- a/v3/ecl/vna/v1/appliances/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains virtual network appliance unit tests -package testing diff --git a/v3/ecl/vna/v1/appliances/testing/fixtures.go b/v3/ecl/vna/v1/appliances/testing/fixtures.go deleted file mode 100644 index 65ada27..0000000 --- a/v3/ecl/vna/v1/appliances/testing/fixtures.go +++ /dev/null @@ -1,1061 +0,0 @@ -package testing - -import ( - "fmt" - - "github.com/nttcom/eclcloud/v3/ecl/vna/v1/appliances" -) - -const applianceType = "ECL::VirtualNetworkAppliance::VSRX" -const idAppliance1 = "45db3e66-31af-45a6-8ad2-d01521726141" -const idAppliance2 = "45db3e66-31af-45a6-8ad2-d01521726142" -const idAppliance3 = "45db3e66-31af-45a6-8ad2-d01521726143" - -const idVirtualNetworkAppliancePlan = "6589b37a-cf82-4918-96fe-255683f78e76" - -var listResponse = fmt.Sprintf(` -{ - "virtual_network_appliances": [ - { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_1_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.51", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": {}, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_1", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "tags": { - "k1": "v1" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - }, - { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_2_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "2.2.2.2", - "mac_address": "aa:bb:cc:dd:ee:f2", - "type": "", - "vrid": null - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.52", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": {}, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_2", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "tags": { - "k1": "v1" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } - ] -}`, - // for appliance1 - idAppliance1, - idVirtualNetworkAppliancePlan, - // for appliance2 - idAppliance2, - idVirtualNetworkAppliancePlan, -) - -var defaultInterface = appliances.InterfaceInResponse{ - Name: "", - Description: "", - NetworkID: "", - Updatable: true, - Tags: map[string]string{}, - FixedIPs: []appliances.FixedIPInResponse{}, - AllowedAddressPairs: []appliances.AllowedAddressPairInResponse{}, -} - -var appliance1 = appliances.Appliance{ - ID: idAppliance1, - Name: "appliance_1", - ApplianceType: applianceType, - Description: "appliance_1_description", - DefaultGateway: "192.168.1.1", - AvailabilityZone: "zone1-groupb", - OSMonitoringStatus: "ACTIVE", - OSLoginStatus: "ACTIVE", - VMStatus: "ACTIVE", - OperationStatus: "COMPLETE", - AppliancePlanID: idVirtualNetworkAppliancePlan, - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Tags: map[string]string{"k1": "v1"}, - Interfaces: appliances.InterfacesInResponse{ - Interface1: appliances.InterfaceInResponse{ - Name: "interface_1", - Description: "interface_1_description", - NetworkID: "dummyNetworkID", - Tags: map[string]string{}, - Updatable: true, - FixedIPs: []appliances.FixedIPInResponse{ - { - IPAddress: "192.168.1.51", - SubnetID: "dummySubnetID", - }, - }, - AllowedAddressPairs: []appliances.AllowedAddressPairInResponse{ - { - IPAddress: "1.1.1.1", - MACAddress: "aa:bb:cc:dd:ee:f1", - Type: "vrrp", - VRID: float64(123), - }, - }, - }, - Interface2: defaultInterface, - Interface3: defaultInterface, - Interface4: defaultInterface, - Interface5: defaultInterface, - Interface6: defaultInterface, - Interface7: defaultInterface, - Interface8: defaultInterface, - }, -} - -var appliance2 = appliances.Appliance{ - ID: idAppliance2, - Name: "appliance_2", - ApplianceType: applianceType, - Description: "appliance_2_description", - DefaultGateway: "192.168.1.1", - AvailabilityZone: "zone1-groupb", - OSMonitoringStatus: "ACTIVE", - OSLoginStatus: "ACTIVE", - VMStatus: "ACTIVE", - OperationStatus: "COMPLETE", - AppliancePlanID: idVirtualNetworkAppliancePlan, - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Tags: map[string]string{"k1": "v1"}, - Interfaces: appliances.InterfacesInResponse{ - Interface1: appliances.InterfaceInResponse{ - Name: "interface_1", - Description: "interface_1_description", - NetworkID: "dummyNetworkID", - Tags: map[string]string{}, - Updatable: true, - FixedIPs: []appliances.FixedIPInResponse{ - { - IPAddress: "192.168.1.52", - SubnetID: "dummySubnetID", - }, - }, - AllowedAddressPairs: []appliances.AllowedAddressPairInResponse{ - { - IPAddress: "2.2.2.2", - MACAddress: "aa:bb:cc:dd:ee:f2", - Type: "", - VRID: interface{}(nil), - }, - }, - }, - Interface2: defaultInterface, - Interface3: defaultInterface, - Interface4: defaultInterface, - Interface5: defaultInterface, - Interface6: defaultInterface, - Interface7: defaultInterface, - Interface8: defaultInterface, - }, -} - -var appliance3 = appliances.Appliance{ - ID: idAppliance3, - Name: "appliance_3", - ApplianceType: applianceType, - Description: "appliance_3_description", - DefaultGateway: "192.168.1.1", - AvailabilityZone: "zone1-groupb", - OSMonitoringStatus: "ACTIVE", - OSLoginStatus: "ACTIVE", - VMStatus: "ACTIVE", - OperationStatus: "COMPLETE", - AppliancePlanID: idVirtualNetworkAppliancePlan, - TenantID: "9ee80f2a926c49f88f166af47df4e9f5", - Username: "root", - Password: "Passw0rd", - Tags: map[string]string{"k1": "v1"}, - Interfaces: appliances.InterfacesInResponse{ - Interface1: appliances.InterfaceInResponse{ - Name: "interface_1", - Description: "interface_1_description", - NetworkID: "dummyNetworkID", - Tags: map[string]string{}, - Updatable: true, - FixedIPs: []appliances.FixedIPInResponse{ - { - IPAddress: "192.168.1.53", - SubnetID: "dummySubnetID", - }, - }, - AllowedAddressPairs: []appliances.AllowedAddressPairInResponse{ - { - IPAddress: "3.3.3.3", - MACAddress: "aa:bb:cc:dd:ee:f3", - Type: "vrrp", - VRID: float64(123), - }, - }, - }, - Interface2: defaultInterface, - Interface3: defaultInterface, - Interface4: defaultInterface, - Interface5: defaultInterface, - Interface6: defaultInterface, - Interface7: defaultInterface, - Interface8: defaultInterface, - }, -} - -var expectedAppliancesSlice = []appliances.Appliance{ - appliance1, - appliance2, -} - -var getResponse = fmt.Sprintf(` -{ - "virtual_network_appliance": { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_1_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.51", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": {}, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_1", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "tags": { - "k1": "v1" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } -}`, - idAppliance1, - idVirtualNetworkAppliancePlan, -) - -var createRequest = fmt.Sprintf(` - { - "virtual_network_appliance": { - "name": "appliance_1", - "description": "appliance_1_description", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "interfaces": { - "interface_1": { - "name": "interface_1", - "description": "interface_1_description", - "fixed_ips": [{ - "ip_address": "192.168.1.51" - }], - "network_id": "dummyNetworkID" - } - }, - "tags": { - "k1": "v1" - }, - "virtual_network_appliance_plan_id": "%s" - } - } -`, - idVirtualNetworkAppliancePlan, -) - -var createResponse = fmt.Sprintf(` -{ - "virtual_network_appliance": { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_3_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "3.3.3.3", - "mac_address": "aa:bb:cc:dd:ee:f3", - "type": "vrrp", - "vrid": 123 - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.53", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": {}, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_3", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "password": "Passw0rd", - "tags": { - "k1": "v1" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "username": "root", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } -}`, - idAppliance3, - idVirtualNetworkAppliancePlan, -) - -var updateMetadataRequest = fmt.Sprintf(` - { - "virtual_network_appliance": { - "name": "appliance_1-update", - "description": "appliance_1_description-update", - "tags": { - "k1": "v1", - "k2": "v2" - }, - "interfaces": { - "interface_1": { - "name": "interface_1", - "description": "interface_1_description", - "tags": { - "k1": "v1", - "k2": "v2" - } - } - } - } - }`, -) - -var updateMetadataResponse = fmt.Sprintf(` -{ - "virtual_network_appliance": { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_1_description-update", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.51", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": { - "k1": "v1", - "k2": "v2" - }, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_1-update", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "password": "Passw0rd", - "tags": { - "k1": "v1", - "k2": "v2" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "username": "root", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } -}`, - idAppliance1, - idVirtualNetworkAppliancePlan, -) - -var updateNetworkIDAndFixedIPRequest = fmt.Sprintf(` - { - "virtual_network_appliance": { - "interfaces": { - "interface_1": { - "network_id": "dummyNetworkID2", - "fixed_ips": [ - { - "ip_address": "192.168.1.51" - }, - { - "ip_address": "192.168.1.52" - } - ] - } - } - } - }`, -) - -var updateNetworkIDAndFixedIPResponse = fmt.Sprintf(` -{ - "virtual_network_appliance": { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_1_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.51", - "subnet_id": "dummySubnetID" - }, - { - "ip_address": "192.168.1.52", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID2", - "tags": { - "k1": "v1" - }, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_1", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "password": "Passw0rd", - "tags": { - "k1": "v1", - "k2": "v2" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "username": "root", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } -}`, - idAppliance1, - idVirtualNetworkAppliancePlan, -) - -var updateAllowedAddressPairsRequest = fmt.Sprintf(` - { - "virtual_network_appliance": { - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - }, - { - "ip_address": "2.2.2.2", - "mac_address": "aa:bb:cc:dd:ee:f2", - "type": "", - "vrid": null - } - ] - } - } - } - }`, -) - -var updateAllowedAddressPairsResponse = fmt.Sprintf(` -{ - "virtual_network_appliance": { - "appliance_type": "ECL::VirtualNetworkAppliance::VSRX", - "availability_zone": "zone1-groupb", - "default_gateway": "192.168.1.1", - "description": "appliance_1_description", - "id": "%s", - "interfaces": { - "interface_1": { - "allowed_address_pairs": [ - { - "ip_address": "1.1.1.1", - "mac_address": "aa:bb:cc:dd:ee:f1", - "type": "vrrp", - "vrid": 123 - }, - { - "ip_address": "2.2.2.2", - "mac_address": "aa:bb:cc:dd:ee:f2", - "type": "", - "vrid": null - } - ], - "description": "interface_1_description", - "fixed_ips": [ - { - "ip_address": "192.168.1.51", - "subnet_id": "dummySubnetID" - } - ], - "name": "interface_1", - "network_id": "dummyNetworkID", - "tags": { - "k1": "v1" - }, - "updatable": true - }, - "interface_2": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_3": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_4": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_5": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_6": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_7": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - }, - "interface_8": { - "allowed_address_pairs": [], - "description": "", - "fixed_ips": [], - "name": "", - "network_id": "", - "tags": {}, - "updatable": true - } - }, - "name": "appliance_1", - "operation_status": "COMPLETE", - "os_login_status": "ACTIVE", - "os_monitoring_status": "ACTIVE", - "password": "Passw0rd", - "tags": { - "k1": "v1", - "k2": "v2" - }, - "tenant_id": "9ee80f2a926c49f88f166af47df4e9f5", - "username": "root", - "virtual_network_appliance_plan_id": "%s", - "vm_status": "ACTIVE" - } -}`, - idAppliance1, - idVirtualNetworkAppliancePlan, -) diff --git a/v3/ecl/vna/v1/appliances/testing/requests_test.go b/v3/ecl/vna/v1/appliances/testing/requests_test.go deleted file mode 100644 index 19adfae..0000000 --- a/v3/ecl/vna/v1/appliances/testing/requests_test.go +++ /dev/null @@ -1,313 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/ecl/vna/v1/appliances" - "github.com/nttcom/eclcloud/v3/pagination" - "github.com/nttcom/eclcloud/v3/testhelper/client" - - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -const TokenID = client.TokenID - -func ServiceClient() *eclcloud.ServiceClient { - sc := client.ServiceClient() - sc.ResourceBase = sc.Endpoint + "v1.0/" - return sc -} - -func TestListAppliances(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc( - "/v1.0/virtual_network_appliances", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, listResponse) - }) - - cli := ServiceClient() - count := 0 - - err := appliances.List(cli, appliances.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - count++ - actual, err := appliances.ExtractAppliances(page) - if err != nil { - t.Errorf("Failed to extract virtual network appliances: %v", err) - return false, err - } - - th.CheckDeepEquals(t, expectedAppliancesSlice, actual) - - return true, nil - }) - - if err != nil { - t.Errorf("Failed to get virtual network appliance list: %v", err) - } - - if count != 1 { - t.Errorf("Expected 1 page, got %d", count) - } -} - -func TestGetAppliance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v1.0/virtual_network_appliances/%s", idAppliance1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "GET") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, getResponse) - }) - - ap, err := appliances.Get(ServiceClient(), idAppliance1).Extract() - th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &appliance1, ap) -} - -func TestCreateAppliance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/v1.0/virtual_network_appliances", - func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "POST") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, createRequest) - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, createResponse) - }) - - createOpts := appliances.CreateOpts{ - Name: "appliance_1", - Description: "appliance_1_description", - DefaultGateway: "192.168.1.1", - AvailabilityZone: "zone1-groupb", - VirtualNetworkAppliancePlanID: idVirtualNetworkAppliancePlan, - Tags: map[string]string{"k1": "v1"}, - Interfaces: &appliances.CreateOptsInterfaces{ - Interface1: &appliances.CreateOptsInterface{ - Name: "interface_1", - Description: "interface_1_description", - NetworkID: "dummyNetworkID", - Tags: map[string]string{}, - FixedIPs: &[]appliances.CreateOptsFixedIP{ - { - IPAddress: "192.168.1.51", - }, - }, - }, - }, - } - ap, err := appliances.Create(ServiceClient(), createOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ap.OperationStatus, "COMPLETE") - th.AssertDeepEquals(t, &appliance3, ap) -} - -func TestDeleteAppliance(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v1.0/virtual_network_appliances/%s", idAppliance1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "DELETE") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - w.WriteHeader(http.StatusNoContent) - }) - - res := appliances.Delete(ServiceClient(), idAppliance1) - th.AssertNoErr(t, res.Err) -} - -func TestUpdateApplianceMetadata(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v1.0/virtual_network_appliances/%s", idAppliance1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, updateMetadataRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, updateMetadataResponse) - }) - - name := "appliance_1-update" - description := "appliance_1_description-update" - tags := map[string]string{"k1": "v1", "k2": "v2"} - - interface1Name := "interface_1" - interface1Description := "interface_1_description" - interface1Tags := map[string]string{"k1": "v1", "k2": "v2"} - - updateOptsInterface1 := appliances.UpdateMetadataInterface{ - Name: &interface1Name, - Description: &interface1Description, - Tags: &interface1Tags, - } - updateOpts := appliances.UpdateMetadataOpts{ - Name: &name, - Description: &description, - Tags: &tags, - Interfaces: &appliances.UpdateMetadataInterfaces{ - Interface1: &updateOptsInterface1, - }, - } - ap, err := appliances.Update( - ServiceClient(), idAppliance1, updateOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ap.Name, "appliance_1-update") - th.AssertEquals(t, ap.Description, "appliance_1_description-update") - th.AssertEquals(t, ap.ID, idAppliance1) -} - -func TestUpdateApplianceNetworkIDAndFixedIP(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v1.0/virtual_network_appliances/%s", idAppliance1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, updateNetworkIDAndFixedIPRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, updateNetworkIDAndFixedIPResponse) - }) - - networkID := "dummyNetworkID2" - - updateAddressInfo1 := appliances.UpdateFixedIPAddressInfo{ - IPAddress: "192.168.1.51", - } - - updateAddressInfo2 := appliances.UpdateFixedIPAddressInfo{ - IPAddress: "192.168.1.52", - } - updateFixedIPs := []appliances.UpdateFixedIPAddressInfo{ - updateAddressInfo1, - updateAddressInfo2, - } - - updateOptsInterface1 := appliances.UpdateFixedIPInterface{ - NetworkID: &networkID, - FixedIPs: &updateFixedIPs, - } - updateOpts := appliances.UpdateFixedIPOpts{ - Interfaces: &appliances.UpdateFixedIPInterfaces{ - Interface1: &updateOptsInterface1, - }, - } - ap, err := appliances.Update( - ServiceClient(), idAppliance1, updateOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ap.Interfaces.Interface1.NetworkID, "dummyNetworkID2") - th.AssertEquals(t, ap.Interfaces.Interface1.FixedIPs[0].IPAddress, "192.168.1.51") - th.AssertEquals(t, ap.Interfaces.Interface1.FixedIPs[1].IPAddress, "192.168.1.52") - th.AssertEquals(t, ap.ID, idAppliance1) -} -func TestUpdateApplianceAllowedAddressPairs(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - - url := fmt.Sprintf("/v1.0/virtual_network_appliances/%s", idAppliance1) - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, "PATCH") - th.TestHeader(t, r, "X-Auth-Token", TokenID) - th.TestHeader(t, r, "Content-Type", "application/json") - th.TestHeader(t, r, "Accept", "application/json") - th.TestJSONRequest(t, r, updateAllowedAddressPairsRequest) - - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - fmt.Fprint(w, updateAllowedAddressPairsResponse) - }) - - mac1 := "aa:bb:cc:dd:ee:f1" - type1 := "vrrp" - - var vrid1 interface{} = 123 - - UpdateAllowedAddressPairAddressInfo1 := appliances.UpdateAllowedAddressPairAddressInfo{ - IPAddress: "1.1.1.1", - MACAddress: &mac1, - Type: &type1, - VRID: &vrid1, - } - - mac2 := "aa:bb:cc:dd:ee:f2" - type2 := "" - - var vrid2 interface{} = nil - - UpdateAllowedAddressPairAddressInfo2 := appliances.UpdateAllowedAddressPairAddressInfo{ - IPAddress: "2.2.2.2", - MACAddress: &mac2, - Type: &type2, - VRID: &vrid2, - } - - updateAllowedAddressPairs := []appliances.UpdateAllowedAddressPairAddressInfo{ - UpdateAllowedAddressPairAddressInfo1, - UpdateAllowedAddressPairAddressInfo2, - } - - updateOptsInterface1 := appliances.UpdateAllowedAddressPairInterface{ - AllowedAddressPairs: &updateAllowedAddressPairs, - } - - updateOpts := appliances.UpdateAllowedAddressPairOpts{ - Interfaces: &appliances.UpdateAllowedAddressPairInterfaces{ - Interface1: &updateOptsInterface1, - }, - } - ap, err := appliances.Update( - ServiceClient(), idAppliance1, updateOpts).Extract() - th.AssertNoErr(t, err) - - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[0].IPAddress, "1.1.1.1") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[0].MACAddress, "aa:bb:cc:dd:ee:f1") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[0].Type, "vrrp") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[0].VRID, float64(123)) - - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[1].IPAddress, "2.2.2.2") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[1].MACAddress, "aa:bb:cc:dd:ee:f2") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[1].Type, "") - th.AssertEquals(t, ap.Interfaces.Interface1.AllowedAddressPairs[1].VRID, interface{}(nil)) - - th.AssertEquals(t, ap.ID, idAppliance1) -} diff --git a/v3/ecl/vna/v1/appliances/urls.go b/v3/ecl/vna/v1/appliances/urls.go deleted file mode 100644 index 2dd749d..0000000 --- a/v3/ecl/vna/v1/appliances/urls.go +++ /dev/null @@ -1,33 +0,0 @@ -package appliances - -import ( - "github.com/nttcom/eclcloud/v3" -) - -func resourceURL(c *eclcloud.ServiceClient, id string) string { - return c.ServiceURL("virtual_network_appliances", id) -} - -func rootURL(c *eclcloud.ServiceClient) string { - return c.ServiceURL("virtual_network_appliances") -} - -func getURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *eclcloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *eclcloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/v3/endpoint_search.go b/v3/endpoint_search.go deleted file mode 100644 index a106f6a..0000000 --- a/v3/endpoint_search.go +++ /dev/null @@ -1,74 +0,0 @@ -package eclcloud - -// Availability indicates to whom a specific service endpoint is accessible: -// the internet at large, internal networks only, or only to administrators. -// Different identity services use different terminology for these. Identity v2 -// lists them as different kinds of URLs within the service catalog ("adminURL", -// "internalURL", and "publicURL"), while v3 lists them as "Interfaces" in an -// endpoint's response. -type Availability string - -const ( - // AvailabilityAdmin indicates that an endpoint is only available to - // administrators. - // AvailabilityAdmin Availability = "admin" - - // AvailabilityPublic indicates that an endpoint is available to everyone on - // the internet. - AvailabilityPublic Availability = "public" - - // AvailabilityInternal indicates that an endpoint is only available within - // the cluster's internal network. - // AvailabilityInternal Availability = "internal" -) - -// EndpointOpts specifies search criteria used by queries against an -// Enterprise Cloud service catalog. The options must contain enough information to -// unambiguously identify one, and only one, endpoint within the catalog. -// -// Usually, these are passed to service client factory functions in a provider -// package, like "ecl.NewComputeV2()". -type EndpointOpts struct { - // Type [required] is the service type for the client (e.g., "compute", - // "object-store"). Generally, this will be supplied by the service client - // function, but a user-given value will be honored if provided. - Type string - - // Name [optional] is the service name for the client (e.g., "nova") as it - // appears in the service catalog. Services can have the same Type but a - // different Name, which is why both Type and Name are sometimes needed. - Name string - - // Region [required] is the geographic region in which the endpoint resides, - // generally specifying which datacenter should house your resources. - // Required only for services that span multiple regions. - Region string - - // Availability [optional] is the visibility of the endpoint to be returned. - // Valid types include the constants AvailabilityPublic, AvailabilityInternal, - // or AvailabilityAdmin from this package. - // - // Availability is not required, and defaults to AvailabilityPublic. Not all - // providers or services offer all Availability options. - Availability Availability -} - -/* -EndpointLocator is an internal function to be used by provider implementations. - -It provides an implementation that locates a single endpoint from a service -catalog for a specific ProviderClient based on user-provided EndpointOpts. The -provider then uses it to discover related ServiceClients. -*/ -type EndpointLocator func(EndpointOpts) (string, error) - -// ApplyDefaults is an internal method to be used by provider implementations. -// -// It sets EndpointOpts fields if not already set, including a default type. -// Currently, EndpointOpts.Availability defaults to the public endpoint. -func (eo *EndpointOpts) ApplyDefaults(t string) { - if eo.Type == "" { - eo.Type = t - } - eo.Availability = AvailabilityPublic -} diff --git a/v3/errors.go b/v3/errors.go deleted file mode 100644 index d4edadf..0000000 --- a/v3/errors.go +++ /dev/null @@ -1,474 +0,0 @@ -package eclcloud - -import ( - "fmt" - "strings" -) - -// BaseError is an error type that all other error types embed. -type BaseError struct { - DefaultErrString string - Info string -} - -func (e BaseError) Error() string { - e.DefaultErrString = "An error occurred while executing a Eclcloud request." - return e.choseErrString() -} - -func (e BaseError) choseErrString() string { - if e.Info != "" { - return e.Info - } - return e.DefaultErrString -} - -// ErrMissingInput is the error when input is required in a particular -// situation but not provided by the user -type ErrMissingInput struct { - BaseError - Argument string -} - -func (e ErrMissingInput) Error() string { - e.DefaultErrString = fmt.Sprintf("Missing input for argument [%s]", e.Argument) - return e.choseErrString() -} - -// ErrInvalidInput is an error type used for most non-HTTP Eclcloud errors. -type ErrInvalidInput struct { - ErrMissingInput - Value interface{} -} - -func (e ErrInvalidInput) Error() string { - e.DefaultErrString = fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value) - return e.choseErrString() -} - -// ErrMissingEnvironmentVariable is the error when environment variable is required -// in a particular situation but not provided by the user -type ErrMissingEnvironmentVariable struct { - BaseError - EnvironmentVariable string -} - -func (e ErrMissingEnvironmentVariable) Error() string { - e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable) - return e.choseErrString() -} - -// ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables -// is required in a particular situation but not provided by the user -type ErrMissingAnyoneOfEnvironmentVariables struct { - BaseError - EnvironmentVariables []string -} - -func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Missing one of the following environment variables [%s]", - strings.Join(e.EnvironmentVariables, ", "), - ) - return e.choseErrString() -} - -// ErrUnexpectedResponseCode is returned by the Request method when a response code other than -// those listed in OkCodes is encountered. -type ErrUnexpectedResponseCode struct { - BaseError - URL string - Method string - Expected []int - Actual int - Body []byte -} - -func (e ErrUnexpectedResponseCode) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s", - e.Expected, e.Method, e.URL, e.Actual, e.Body, - ) - return e.choseErrString() -} - -// ErrDefault400 is the default error type returned on a 400 HTTP response code. -type ErrDefault400 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault401 is the default error type returned on a 401 HTTP response code. -type ErrDefault401 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault403 is the default error type returned on a 403 HTTP response code. -type ErrDefault403 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault404 is the default error type returned on a 404 HTTP response code. -type ErrDefault404 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault405 is the default error type returned on a 405 HTTP response code. -type ErrDefault405 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault408 is the default error type returned on a 408 HTTP response code. -type ErrDefault408 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault409 is the default error type returned on a 409 HTTP response code. -type ErrDefault409 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault429 is the default error type returned on a 429 HTTP response code. -type ErrDefault429 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault500 is the default error type returned on a 500 HTTP response code. -type ErrDefault500 struct { - ErrUnexpectedResponseCode -} - -// ErrDefault503 is the default error type returned on a 503 HTTP response code. -type ErrDefault503 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault400) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Bad request with: [%s %s], error message: %s", - e.Method, e.URL, e.Body, - ) - return e.choseErrString() -} -func (e ErrDefault401) Error() string { - return "Authentication failed" -} -func (e ErrDefault403) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Request forbidden: [%s %s], error message: %s", - e.Method, e.URL, e.Body, - ) - return e.choseErrString() -} -func (e ErrDefault404) Error() string { - return "Resource not found" -} -func (e ErrDefault405) Error() string { - return "Method not allowed" -} -func (e ErrDefault408) Error() string { - return "The server timed out waiting for the request" -} -func (e ErrDefault409) Error() string { - return "Request conflicted" -} -func (e ErrDefault429) Error() string { - return "Too many requests have been sent in a given amount of time. Pause" + - " requests, wait up to one minute, and try again." -} -func (e ErrDefault500) Error() string { - return "Internal Server Error" -} -func (e ErrDefault503) Error() string { - return "The service is currently unable to handle the request due to a temporary" + - " overloading or maintenance. This is a temporary condition. Try again later." -} - -// Err400er is the interface resource error types implement to override the error message -// from a 400 error. -type Err400er interface { - Error400(ErrUnexpectedResponseCode) error -} - -// Err401er is the interface resource error types implement to override the error message -// from a 401 error. -type Err401er interface { - Error401(ErrUnexpectedResponseCode) error -} - -// Err403er is the interface resource error types implement to override the error message -// from a 403 error. -type Err403er interface { - Error403(ErrUnexpectedResponseCode) error -} - -// Err404er is the interface resource error types implement to override the error message -// from a 404 error. -type Err404er interface { - Error404(ErrUnexpectedResponseCode) error -} - -// Err405er is the interface resource error types implement to override the error message -// from a 405 error. -type Err405er interface { - Error405(ErrUnexpectedResponseCode) error -} - -// Err408er is the interface resource error types implement to override the error message -// from a 408 error. -type Err408er interface { - Error408(ErrUnexpectedResponseCode) error -} - -// Err409er is the interface resource error types implement to override the error message -// from a 409 error. -type Err409er interface { - Error409(ErrUnexpectedResponseCode) error -} - -// Err429er is the interface resource error types implement to override the error message -// from a 429 error. -type Err429er interface { - Error429(ErrUnexpectedResponseCode) error -} - -// Err500er is the interface resource error types implement to override the error message -// from a 500 error. -type Err500er interface { - Error500(ErrUnexpectedResponseCode) error -} - -// Err503er is the interface resource error types implement to override the error message -// from a 503 error. -type Err503er interface { - Error503(ErrUnexpectedResponseCode) error -} - -// ErrTimeOut is the error type returned when an operations times out. -type ErrTimeOut struct { - BaseError -} - -func (e ErrTimeOut) Error() string { - e.DefaultErrString = "A time out occurred" - return e.choseErrString() -} - -// ErrUnableToReauthenticate is the error type returned when reauthentication fails. -type ErrUnableToReauthenticate struct { - BaseError - ErrOriginal error -} - -func (e ErrUnableToReauthenticate) Error() string { - e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s", e.ErrOriginal) - return e.choseErrString() -} - -// ErrErrorAfterReauthentication is the error type returned when reauthentication -// succeeds, but an error occurs afterword (usually an HTTP error). -type ErrErrorAfterReauthentication struct { - BaseError - ErrOriginal error -} - -func (e ErrErrorAfterReauthentication) Error() string { - e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal) - return e.choseErrString() -} - -// ErrServiceNotFound is returned when no service in a service catalog matches -// the provided EndpointOpts. This is generally returned by provider service -// factory methods like "NewComputeV2()" and can mean that a service is not -// enabled for your account. -type ErrServiceNotFound struct { - BaseError -} - -func (e ErrServiceNotFound) Error() string { - e.DefaultErrString = "No suitable service could be found in the service catalog." - return e.choseErrString() -} - -// ErrEndpointNotFound is returned when no available endpoints match the -// provided EndpointOpts. This is also generally returned by provider service -// factory methods, and usually indicates that a region was specified -// incorrectly. -type ErrEndpointNotFound struct { - BaseError -} - -func (e ErrEndpointNotFound) Error() string { - e.DefaultErrString = "No suitable endpoint could be found in the service catalog." - return e.choseErrString() -} - -// ErrResourceNotFound is the error when trying to retrieve a resource's -// ID by name and the resource doesn't exist. -type ErrResourceNotFound struct { - BaseError - Name string - ResourceType string -} - -func (e ErrResourceNotFound) Error() string { - e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name) - return e.choseErrString() -} - -// ErrMultipleResourcesFound is the error when trying to retrieve a resource's -// ID by name and multiple resources have the user-provided name. -type ErrMultipleResourcesFound struct { - BaseError - Name string - Count int - ResourceType string -} - -func (e ErrMultipleResourcesFound) Error() string { - e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name) - return e.choseErrString() -} - -// ErrUnexpectedType is the error when an unexpected type is encountered -type ErrUnexpectedType struct { - BaseError - Expected string - Actual string -} - -func (e ErrUnexpectedType) Error() string { - e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual) - return e.choseErrString() -} - -func unacceptedAttributeErr(attribute string) string { - return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute) -} - -func redundantWithTokenErr(attribute string) string { - return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute) -} - -func redundantWithUserID(attribute string) string { - return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute) -} - -// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used. -type ErrAPIKeyProvided struct{ BaseError } - -func (e ErrAPIKeyProvided) Error() string { - return unacceptedAttributeErr("APIKey") -} - -// ErrTenantIDProvided indicates that a TenantID was provided but can't be used. -type ErrTenantIDProvided struct{ BaseError } - -func (e ErrTenantIDProvided) Error() string { - return unacceptedAttributeErr("TenantID") -} - -// ErrTenantNameProvided indicates that a TenantName was provided but can't be used. -type ErrTenantNameProvided struct{ BaseError } - -func (e ErrTenantNameProvided) Error() string { - return unacceptedAttributeErr("TenantName") -} - -// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead. -type ErrUsernameWithToken struct{ BaseError } - -func (e ErrUsernameWithToken) Error() string { - return redundantWithTokenErr("Username") -} - -// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead. -type ErrUserIDWithToken struct{ BaseError } - -func (e ErrUserIDWithToken) Error() string { - return redundantWithTokenErr("UserID") -} - -// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead. -type ErrDomainIDWithToken struct{ BaseError } - -func (e ErrDomainIDWithToken) Error() string { - return redundantWithTokenErr("DomainID") -} - -// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s -type ErrDomainNameWithToken struct{ BaseError } - -func (e ErrDomainNameWithToken) Error() string { - return redundantWithTokenErr("DomainName") -} - -// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once. -type ErrUsernameOrUserID struct{ BaseError } - -func (e ErrUsernameOrUserID) Error() string { - return "Exactly one of Username and UserID must be provided for password authentication" -} - -// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used. -type ErrDomainIDWithUserID struct{ BaseError } - -func (e ErrDomainIDWithUserID) Error() string { - return redundantWithUserID("DomainID") -} - -// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used. -type ErrDomainNameWithUserID struct{ BaseError } - -func (e ErrDomainNameWithUserID) Error() string { - return redundantWithUserID("DomainName") -} - -// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it. -// It may also indicate that both a DomainID and a DomainName were provided at once. -type ErrDomainIDOrDomainName struct{ BaseError } - -func (e ErrDomainIDOrDomainName) Error() string { - return "You must provide exactly one of DomainID or DomainName to authenticate by Username" -} - -// ErrMissingPassword indicates that no password was provided and no token is available. -type ErrMissingPassword struct{ BaseError } - -func (e ErrMissingPassword) Error() string { - return "You must provide a password to authenticate" -} - -// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present. -type ErrScopeDomainIDOrDomainName struct{ BaseError } - -func (e ErrScopeDomainIDOrDomainName) Error() string { - return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName" -} - -// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope. -type ErrScopeProjectIDOrProjectName struct{ BaseError } - -func (e ErrScopeProjectIDOrProjectName) Error() string { - return "You must provide at most one of ProjectID or ProjectName in a Scope" -} - -// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope. -type ErrScopeProjectIDAlone struct{ BaseError } - -func (e ErrScopeProjectIDAlone) Error() string { - return "ProjectID must be supplied alone in a Scope" -} - -// ErrScopeEmpty indicates that no credentials were provided in a Scope. -type ErrScopeEmpty struct{ BaseError } - -func (e ErrScopeEmpty) Error() string { - return "You must provide either a Project or Domain in a Scope" -} - -// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name -type ErrAppCredMissingSecret struct{ BaseError } - -func (e ErrAppCredMissingSecret) Error() string { - return "You must provide an Application Credential Secret" -} diff --git a/v3/go.mod b/v3/go.mod deleted file mode 100644 index 63b9bf7..0000000 --- a/v3/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/nttcom/eclcloud/v3 - -go 1.13 diff --git a/v3/internal/pkg.go b/v3/internal/pkg.go deleted file mode 100644 index 5bf0569..0000000 --- a/v3/internal/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package internal diff --git a/v3/internal/testing/pkg.go b/v3/internal/testing/pkg.go deleted file mode 100644 index 7603f83..0000000 --- a/v3/internal/testing/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package testing diff --git a/v3/internal/testing/util_test.go b/v3/internal/testing/util_test.go deleted file mode 100644 index b26b32b..0000000 --- a/v3/internal/testing/util_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package testing - -import ( - "reflect" - "testing" - - "github.com/nttcom/eclcloud/v3/internal" -) - -func TestRemainingKeys(t *testing.T) { - type User struct { - UserID string `json:"user_id"` - Username string `json:"username"` - Location string `json:"-"` - CreatedAt string `json:"-"` - Status string - IsAdmin bool - } - - userResponse := map[string]interface{}{ - "user_id": "abcd1234", - "username": "jdoe", - "location": "Hawaii", - "created_at": "2017-06-08T02:49:03.000000", - "status": "active", - "is_admin": "true", - "custom_field": "foo", - } - - expected := map[string]interface{}{ - "created_at": "2017-06-08T02:49:03.000000", - "is_admin": "true", - "custom_field": "foo", - } - - actual := internal.RemainingKeys(User{}, userResponse) - - isEqual := reflect.DeepEqual(expected, actual) - if !isEqual { - t.Fatalf("expected %s but got %s", expected, actual) - } -} diff --git a/v3/internal/util.go b/v3/internal/util.go deleted file mode 100644 index 8efb283..0000000 --- a/v3/internal/util.go +++ /dev/null @@ -1,34 +0,0 @@ -package internal - -import ( - "reflect" - "strings" -) - -// RemainingKeys will inspect a struct and compare it to a map. Any struct -// field that does not have a JSON tag that matches a key in the map or -// a matching lower-case field in the map will be returned as an extra. -// -// This is useful for determining the extra fields returned in response bodies -// for resources that can contain an arbitrary or dynamic number of fields. -func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) { - extras = make(map[string]interface{}) - for k, v := range m { - extras[k] = v - } - - valueOf := reflect.ValueOf(s) - typeOf := reflect.TypeOf(s) - for i := 0; i < valueOf.NumField(); i++ { - field := typeOf.Field(i) - - lowerField := strings.ToLower(field.Name) - delete(extras, lowerField) - - if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" { - delete(extras, tagValue) - } - } - - return -} diff --git a/v3/pagination/http.go b/v3/pagination/http.go deleted file mode 100644 index 56cc6fb..0000000 --- a/v3/pagination/http.go +++ /dev/null @@ -1,59 +0,0 @@ -package pagination - -import ( - "encoding/json" - "github.com/nttcom/eclcloud/v3" - "io/ioutil" - "net/http" - "net/url" - "strings" -) - -// PageResult stores the HTTP response that returned the current page of results. -type PageResult struct { - eclcloud.Result - url.URL -} - -// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the -// results, interpreting it as JSON if the content type indicates. -func PageResultFrom(resp *http.Response) (PageResult, error) { - var parsedBody interface{} - - defer resp.Body.Close() - rawBody, err := ioutil.ReadAll(resp.Body) - if err != nil { - return PageResult{}, err - } - - if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { - err = json.Unmarshal(rawBody, &parsedBody) - if err != nil { - return PageResult{}, err - } - } else { - parsedBody = rawBody - } - - return PageResultFromParsed(resp, parsedBody), err -} - -// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its -// body parsed as JSON (and closed). -func PageResultFromParsed(resp *http.Response, body interface{}) PageResult { - return PageResult{ - Result: eclcloud.Result{ - Body: body, - Header: resp.Header, - }, - URL: *resp.Request.URL, - } -} - -// Request performs an HTTP request and extracts the http.Response from the result. -func Request(client *eclcloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) { - return client.Get(url, nil, &eclcloud.RequestOpts{ - MoreHeaders: headers, - OkCodes: []int{200, 204, 300}, - }) -} diff --git a/v3/pagination/linked.go b/v3/pagination/linked.go deleted file mode 100644 index 201006f..0000000 --- a/v3/pagination/linked.go +++ /dev/null @@ -1,92 +0,0 @@ -package pagination - -import ( - "fmt" - "reflect" - - "github.com/nttcom/eclcloud/v3" -) - -// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result. -type LinkedPageBase struct { - PageResult - - // LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer. - // If any link along the path is missing, an empty URL will be returned. - // If any link results in an unexpected value type, an error will be returned. - // When left as "nil", []string{"links", "next"} will be used as a default. - LinkPath []string -} - -// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present. -// It assumes that the links are available in a "links" element of the top-level response object. -// If this is not the case, override NextPageURL on your result type. -func (current LinkedPageBase) NextPageURL() (string, error) { - var path []string - var key string - - if current.LinkPath == nil { - path = []string{"links", "next"} - } else { - path = current.LinkPath - } - - submap, ok := current.Body.(map[string]interface{}) - if !ok { - err := eclcloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return "", err - } - - for { - key, path = path[0], path[1:] - - value, ok := submap[key] - if !ok { - return "", nil - } - - if len(path) > 0 { - submap, ok = value.(map[string]interface{}) - if !ok { - err := eclcloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - return "", err - } - } else { - if value == nil { - // Actual null element. - return "", nil - } - - url, ok := value.(string) - if !ok { - err := eclcloud.ErrUnexpectedType{} - err.Expected = "string" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - return "", err - } - - return url, nil - } - } -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current LinkedPageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := eclcloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the linked page's body. This method is needed to satisfy the -// Page interface. -func (current LinkedPageBase) GetBody() interface{} { - return current.Body -} diff --git a/v3/pagination/marker.go b/v3/pagination/marker.go deleted file mode 100644 index 7721cf0..0000000 --- a/v3/pagination/marker.go +++ /dev/null @@ -1,57 +0,0 @@ -package pagination - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3" - "reflect" -) - -// MarkerPage is a stricter Page interface that describes additional functionality required for use with NewMarkerPager. -// For convenience, embed the MarkedPageBase struct. -type MarkerPage interface { - Page - - // LastMarker returns the last "marker" value on this page. - LastMarker() (string, error) -} - -// MarkerPageBase is a page in a collection that's paginated by "limit" and "marker" query parameters. -type MarkerPageBase struct { - PageResult - - // Owner is a reference to the embedding struct. - Owner MarkerPage -} - -// NextPageURL generates the URL for the page of results after this one. -func (current MarkerPageBase) NextPageURL() (string, error) { - currentURL := current.URL - - mark, err := current.Owner.LastMarker() - if err != nil { - return "", err - } - - q := currentURL.Query() - q.Set("marker", mark) - currentURL.RawQuery = q.Encode() - - return currentURL.String(), nil -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current MarkerPageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := eclcloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the linked page's body. This method is needed to satisfy the -// Page interface. -func (current MarkerPageBase) GetBody() interface{} { - return current.Body -} diff --git a/v3/pagination/pager.go b/v3/pagination/pager.go deleted file mode 100644 index 71f9599..0000000 --- a/v3/pagination/pager.go +++ /dev/null @@ -1,250 +0,0 @@ -package pagination - -import ( - "errors" - "fmt" - "github.com/nttcom/eclcloud/v3" - "net/http" - "reflect" - "strings" -) - -var ( - // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. - ErrPageNotAvailable = errors.New("the requested page does not exist") -) - -// Page must be satisfied by the result type of any resource collection. -// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. -// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, -// instead. -// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type -// will need to implement. -type Page interface { - // NextPageURL generates the URL for the page of data that follows this collection. - // Return "" if no such page exists. - NextPageURL() (string, error) - - // IsEmpty returns true if this Page has no items in it. - IsEmpty() (bool, error) - - // GetBody returns the Page Body. This is used in the `AllPages` method. - GetBody() interface{} -} - -// Pager knows how to advance through a specific resource collection, one page at a time. -type Pager struct { - client *eclcloud.ServiceClient - - initialURL string - - createPage func(r PageResult) Page - - firstPage Page - - Err error - - // Headers supplies additional HTTP headers to populate on each paged request. - Headers map[string]string -} - -// NewPager constructs a manually-configured pager. -// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. -func NewPager(client *eclcloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { - return Pager{ - client: client, - initialURL: initialURL, - createPage: createPage, - } -} - -// WithPageCreator returns a new Pager that substitutes a different page creation function. This is -// useful for overriding List functions in delegation. -func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { - return Pager{ - client: p.client, - initialURL: p.initialURL, - createPage: createPage, - } -} - -func (p Pager) fetchNextPage(url string) (Page, error) { - resp, err := Request(p.client, p.Headers, url) - if err != nil { - return nil, err - } - - remembered, err := PageResultFrom(resp) - if err != nil { - return nil, err - } - - return p.createPage(remembered), nil -} - -// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. -// Return "false" from the handler to prematurely stop iterating. -func (p Pager) EachPage(handler func(Page) (bool, error)) error { - if p.Err != nil { - return p.Err - } - currentURL := p.initialURL - for { - var currentPage Page - - // if first page has already been fetched, no need to fetch it again - if p.firstPage != nil { - currentPage = p.firstPage - p.firstPage = nil - } else { - var err error - currentPage, err = p.fetchNextPage(currentURL) - if err != nil { - return err - } - } - - empty, err := currentPage.IsEmpty() - if err != nil { - return err - } - if empty { - return nil - } - - ok, err := handler(currentPage) - if err != nil { - return err - } - if !ok { - return nil - } - - currentURL, err = currentPage.NextPageURL() - if err != nil { - return err - } - if currentURL == "" { - return nil - } - } -} - -// AllPages returns all the pages from a `List` operation in a single page, -// allowing the user to retrieve all the pages at once. -func (p Pager) AllPages() (Page, error) { - // pagesSlice holds all the pages until they get converted into as Page Body. - var pagesSlice []interface{} - // body will contain the final concatenated Page body. - var body reflect.Value - - // Grab a first page to ascertain the page body type. - firstPage, err := p.fetchNextPage(p.initialURL) - if err != nil { - return nil, err - } - // Store the page type so we can use reflection to create a new mega-page of - // that type. - pageType := reflect.TypeOf(firstPage) - - // if it's a single page, just return the firstPage (first page) - if _, found := pageType.FieldByName("SinglePageBase"); found { - return firstPage, nil - } - - // store the first page to avoid getting it twice - p.firstPage = firstPage - - // Switch on the page body type. Recognized types are `map[string]interface{}`, - // `[]byte`, and `[]interface{}`. - switch pb := firstPage.GetBody().(type) { - case map[string]interface{}: - // key is the map key for the page body if the body type is `map[string]interface{}`. - var key string - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().(map[string]interface{}) - for k, v := range b { - // If it's a linked page, we don't want the `links`, we want the other one. - if !strings.HasSuffix(k, "links") { - // check the field's type. we only want []interface{} (which is really []map[string]interface{}) - switch vt := v.(type) { - case []interface{}: - key = k - pagesSlice = append(pagesSlice, vt...) - } - } - } - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `map[string]interface{}` - body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice))) - body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice)) - case []byte: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]byte) - pagesSlice = append(pagesSlice, b) - // seperate pages with a comma - pagesSlice = append(pagesSlice, []byte{10}) - return true, nil - }) - if err != nil { - return nil, err - } - if len(pagesSlice) > 0 { - // Remove the trailing comma. - pagesSlice = pagesSlice[:len(pagesSlice)-1] - } - var b []byte - // Combine the slice of slices in to a single slice. - for _, slice := range pagesSlice { - b = append(b, slice.([]byte)...) - } - // Set body to value of type `bytes`. - body = reflect.New(reflect.TypeOf(b)).Elem() - body.SetBytes(b) - case []interface{}: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]interface{}) - pagesSlice = append(pagesSlice, b...) - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `[]interface{}` - body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice)) - for i, s := range pagesSlice { - body.Index(i).Set(reflect.ValueOf(s)) - } - default: - err := eclcloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}/[]byte/[]interface{}" - err.Actual = fmt.Sprintf("%T", pb) - return nil, err - } - - // Each `Extract*` function is expecting a specific type of page coming back, - // otherwise the type assertion in those functions will fail. pageType is needed - // to create a type in this method that has the same type that the `Extract*` - // function is expecting and set the Body of that object to the concatenated - // pages. - page := reflect.New(pageType) - // Set the page body to be the concatenated pages. - page.Elem().FieldByName("Body").Set(body) - // Set any additional headers that were pass along. The `objectstorage` pacakge, - // for example, passes a Content-Type header. - h := make(http.Header) - for k, v := range p.Headers { - h.Add(k, v) - } - page.Elem().FieldByName("Header").Set(reflect.ValueOf(h)) - // Type assert the page to a Page interface so that the type assertion in the - // `Extract*` methods will work. - return page.Elem().Interface().(Page), err -} diff --git a/v3/pagination/pkg.go b/v3/pagination/pkg.go deleted file mode 100644 index 90cb4b2..0000000 --- a/v3/pagination/pkg.go +++ /dev/null @@ -1,5 +0,0 @@ -/* -Package pagination contains utilities and convenience structs -that implement common pagination idioms within Enterprise Cloud APIs. -*/ -package pagination diff --git a/v3/pagination/single.go b/v3/pagination/single.go deleted file mode 100644 index e016a49..0000000 --- a/v3/pagination/single.go +++ /dev/null @@ -1,32 +0,0 @@ -package pagination - -import ( - "fmt" - "github.com/nttcom/eclcloud/v3" - "reflect" -) - -// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once. -type SinglePageBase PageResult - -// NextPageURL always returns "" to indicate that there are no more pages to return. -func (current SinglePageBase) NextPageURL() (string, error) { - return "", nil -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current SinglePageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := eclcloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the single page's body. This method is needed to satisfy the -// Page interface. -func (current SinglePageBase) GetBody() interface{} { - return current.Body -} diff --git a/v3/pagination/testing/doc.go b/v3/pagination/testing/doc.go deleted file mode 100644 index 0bc1eb3..0000000 --- a/v3/pagination/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// pagination -package testing diff --git a/v3/pagination/testing/linked_test.go b/v3/pagination/testing/linked_test.go deleted file mode 100644 index ae5c4c4..0000000 --- a/v3/pagination/testing/linked_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "reflect" - "testing" - - "github.com/nttcom/eclcloud/v3/pagination" - "github.com/nttcom/eclcloud/v3/testhelper" -) - -// LinkedPager sample and test cases. - -type LinkedPageResult struct { - pagination.LinkedPageBase -} - -func (r LinkedPageResult) IsEmpty() (bool, error) { - is, err := ExtractLinkedInts(r) - return len(is) == 0, err -} - -func ExtractLinkedInts(r pagination.Page) ([]int, error) { - var s struct { - Ints []int `json:"ints"` - } - err := (r.(LinkedPageResult)).ExtractInto(&s) - return s.Ints, err -} - -func createLinked(t *testing.T) pagination.Pager { - testhelper.SetupHTTP() - - testhelper.Mux.HandleFunc("/page1", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3], "links": { "next": "%s/page2" } }`, testhelper.Server.URL) - }) - - testhelper.Mux.HandleFunc("/page2", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [4, 5, 6], "links": { "next": "%s/page3" } }`, testhelper.Server.URL) - }) - - testhelper.Mux.HandleFunc("/page3", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [7, 8, 9], "links": { "next": null } }`) - }) - - client := createClient() - - createPage := func(r pagination.PageResult) pagination.Page { - return LinkedPageResult{pagination.LinkedPageBase{PageResult: r}} - } - - return pagination.NewPager(client, testhelper.Server.URL+"/page1", createPage) -} - -func TestEnumerateLinked(t *testing.T) { - pager := createLinked(t) - defer testhelper.TeardownHTTP() - - callCount := 0 - err := pager.EachPage(func(page pagination.Page) (bool, error) { - actual, err := ExtractLinkedInts(page) - if err != nil { - return false, err - } - - t.Logf("Handler invoked with %v", actual) - - var expected []int - switch callCount { - case 0: - expected = []int{1, 2, 3} - case 1: - expected = []int{4, 5, 6} - case 2: - expected = []int{7, 8, 9} - default: - t.Fatalf("Unexpected call count: %d", callCount) - return false, nil - } - - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Call %d: Expected %#v, but was %#v", callCount, expected, actual) - } - - callCount++ - return true, nil - }) - if err != nil { - t.Errorf("Unexpected error for page iteration: %v", err) - } - - if callCount != 3 { - t.Errorf("Expected 3 calls, but was %d", callCount) - } -} - -func TestAllPagesLinked(t *testing.T) { - pager := createLinked(t) - defer testhelper.TeardownHTTP() - - page, err := pager.AllPages() - testhelper.AssertNoErr(t, err) - - expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} - actual, err := ExtractLinkedInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) -} diff --git a/v3/pagination/testing/marker_test.go b/v3/pagination/testing/marker_test.go deleted file mode 100644 index a57f6cf..0000000 --- a/v3/pagination/testing/marker_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "strings" - "testing" - - "github.com/nttcom/eclcloud/v3/pagination" - "github.com/nttcom/eclcloud/v3/testhelper" -) - -// MarkerPager sample and test cases. - -type MarkerPageResult struct { - pagination.MarkerPageBase -} - -func (r MarkerPageResult) IsEmpty() (bool, error) { - results, err := ExtractMarkerStrings(r) - if err != nil { - return true, err - } - return len(results) == 0, err -} - -func (r MarkerPageResult) LastMarker() (string, error) { - results, err := ExtractMarkerStrings(r) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", nil - } - return results[len(results)-1], nil -} - -func createMarkerPaged(t *testing.T) pagination.Pager { - testhelper.SetupHTTP() - - testhelper.Mux.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) { - r.ParseForm() - ms := r.Form["marker"] - switch { - case len(ms) == 0: - fmt.Fprintf(w, "aaa\nbbb\nccc") - case len(ms) == 1 && ms[0] == "ccc": - fmt.Fprintf(w, "ddd\neee\nfff") - case len(ms) == 1 && ms[0] == "fff": - fmt.Fprintf(w, "ggg\nhhh\niii") - case len(ms) == 1 && ms[0] == "iii": - w.WriteHeader(http.StatusNoContent) - default: - t.Errorf("Request with unexpected marker: [%v]", ms) - } - }) - - client := createClient() - - createPage := func(r pagination.PageResult) pagination.Page { - p := MarkerPageResult{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p - return p - } - - return pagination.NewPager(client, testhelper.Server.URL+"/page", createPage) -} - -func ExtractMarkerStrings(page pagination.Page) ([]string, error) { - content := page.(MarkerPageResult).Body.([]uint8) - parts := strings.Split(string(content), "\n") - results := make([]string, 0, len(parts)) - for _, part := range parts { - if len(part) > 0 { - results = append(results, part) - } - } - return results, nil -} - -func TestEnumerateMarker(t *testing.T) { - pager := createMarkerPaged(t) - defer testhelper.TeardownHTTP() - - callCount := 0 - err := pager.EachPage(func(page pagination.Page) (bool, error) { - actual, err := ExtractMarkerStrings(page) - if err != nil { - return false, err - } - - t.Logf("Handler invoked with %v", actual) - - var expected []string - switch callCount { - case 0: - expected = []string{"aaa", "bbb", "ccc"} - case 1: - expected = []string{"ddd", "eee", "fff"} - case 2: - expected = []string{"ggg", "hhh", "iii"} - default: - t.Fatalf("Unexpected call count: %d", callCount) - return false, nil - } - - testhelper.CheckDeepEquals(t, expected, actual) - - callCount++ - return true, nil - }) - testhelper.AssertNoErr(t, err) - testhelper.AssertEquals(t, callCount, 3) -} - -func TestAllPagesMarker(t *testing.T) { - pager := createMarkerPaged(t) - defer testhelper.TeardownHTTP() - - page, err := pager.AllPages() - testhelper.AssertNoErr(t, err) - - expected := []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii"} - actual, err := ExtractMarkerStrings(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) -} diff --git a/v3/pagination/testing/pagination_test.go b/v3/pagination/testing/pagination_test.go deleted file mode 100644 index 15c9e93..0000000 --- a/v3/pagination/testing/pagination_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package testing - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/testhelper" -) - -func createClient() *eclcloud.ServiceClient { - return &eclcloud.ServiceClient{ - ProviderClient: &eclcloud.ProviderClient{TokenID: "abc123"}, - Endpoint: testhelper.Endpoint(), - } -} diff --git a/v3/pagination/testing/single_test.go b/v3/pagination/testing/single_test.go deleted file mode 100644 index b71a3a1..0000000 --- a/v3/pagination/testing/single_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3/pagination" - "github.com/nttcom/eclcloud/v3/testhelper" -) - -// SinglePage sample and test cases. - -type SinglePageResult struct { - pagination.SinglePageBase -} - -func (r SinglePageResult) IsEmpty() (bool, error) { - is, err := ExtractSingleInts(r) - if err != nil { - return true, err - } - return len(is) == 0, nil -} - -func ExtractSingleInts(r pagination.Page) ([]int, error) { - var s struct { - Ints []int `json:"ints"` - } - err := (r.(SinglePageResult)).ExtractInto(&s) - return s.Ints, err -} - -func setupSinglePaged() pagination.Pager { - testhelper.SetupHTTP() - client := createClient() - - testhelper.Mux.HandleFunc("/only", func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{ "ints": [1, 2, 3] }`) - }) - - createPage := func(r pagination.PageResult) pagination.Page { - return SinglePageResult{pagination.SinglePageBase(r)} - } - - return pagination.NewPager(client, testhelper.Server.URL+"/only", createPage) -} - -func TestEnumerateSinglePaged(t *testing.T) { - callCount := 0 - pager := setupSinglePaged() - defer testhelper.TeardownHTTP() - - err := pager.EachPage(func(page pagination.Page) (bool, error) { - callCount++ - - expected := []int{1, 2, 3} - actual, err := ExtractSingleInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) - return true, nil - }) - testhelper.CheckNoErr(t, err) - testhelper.CheckEquals(t, 1, callCount) -} - -func TestAllPagesSingle(t *testing.T) { - pager := setupSinglePaged() - defer testhelper.TeardownHTTP() - - page, err := pager.AllPages() - testhelper.AssertNoErr(t, err) - - expected := []int{1, 2, 3} - actual, err := ExtractSingleInts(page) - testhelper.AssertNoErr(t, err) - testhelper.CheckDeepEquals(t, expected, actual) -} diff --git a/v3/params.go b/v3/params.go deleted file mode 100644 index 88b06c3..0000000 --- a/v3/params.go +++ /dev/null @@ -1,488 +0,0 @@ -package eclcloud - -import ( - "encoding/json" - "fmt" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -/* -BuildRequestBody builds a map[string]interface from the given `struct`. If -parent is not an empty string, the final map[string]interface returned will -encapsulate the built one. For example: - - disk := 1 - createOpts := flavors.CreateOpts{ - ID: "1", - Name: "m1.tiny", - Disk: &disk, - RAM: 512, - VCPUs: 1, - RxTxFactor: 1.0, - } - - body, err := eclcloud.BuildRequestBody(createOpts, "flavor") - -The above example can be run as-is, however it is recommended to look at how -BuildRequestBody is used within eclcloud to more fully understand how it -fits within the request process as a whole rather than use it directly as shown -above. -*/ -func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]interface{}) - if optsValue.Kind() == reflect.Struct { - //fmt.Printf("optsValue.Kind() is a reflect.Struct: %+v\n", optsValue.Kind()) - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - - if f.Name != strings.Title(f.Name) { - //fmt.Printf("Skipping field: %s...\n", f.Name) - continue - } - - //fmt.Printf("Starting on field: %s...\n", f.Name) - - zero := isZero(v) - //fmt.Printf("v is zero?: %v\n", zero) - - // if the field has a required tag that's set to "true" - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - //fmt.Printf("Checking required field [%s]:\n\tv: %+v\n\tisZero:%v\n", f.Name, v.Interface(), zero) - // if the field's value is zero, return a missing-argument error - if zero { - // if the field has a 'required' tag, it can't have a zero-value - err := ErrMissingInput{} - err.Argument = f.Name - return nil, err - } - } - - if xorTag := f.Tag.Get("xor"); xorTag != "" { - //fmt.Printf("Checking `xor` tag for field [%s] with value %+v:\n\txorTag: %s\n", f.Name, v, xorTag) - xorField := optsValue.FieldByName(xorTag) - var xorFieldIsZero bool - if reflect.ValueOf(xorField.Interface()) == reflect.Zero(xorField.Type()) { - xorFieldIsZero = true - } else { - if xorField.Kind() == reflect.Ptr { - xorField = xorField.Elem() - } - xorFieldIsZero = isZero(xorField) - } - if !(zero != xorFieldIsZero) { - err := ErrMissingInput{} - err.Argument = fmt.Sprintf("%s/%s", f.Name, xorTag) - err.Info = fmt.Sprintf("Exactly one of %s and %s must be provided", f.Name, xorTag) - return nil, err - } - } - - if orTag := f.Tag.Get("or"); orTag != "" { - //fmt.Printf("Checking `or` tag for field with:\n\tname: %+v\n\torTag:%s\n", f.Name, orTag) - //fmt.Printf("field is zero?: %v\n", zero) - if zero { - orField := optsValue.FieldByName(orTag) - var orFieldIsZero bool - if reflect.ValueOf(orField.Interface()) == reflect.Zero(orField.Type()) { - orFieldIsZero = true - } else { - if orField.Kind() == reflect.Ptr { - orField = orField.Elem() - } - orFieldIsZero = isZero(orField) - } - if orFieldIsZero { - err := ErrMissingInput{} - err.Argument = fmt.Sprintf("%s/%s", f.Name, orTag) - err.Info = fmt.Sprintf("At least one of %s and %s must be provided", f.Name, orTag) - return nil, err - } - } - } - - jsonTag := f.Tag.Get("json") - if jsonTag == "-" { - continue - } - - if v.Kind() == reflect.Slice || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Slice) { - sliceValue := v - if sliceValue.Kind() == reflect.Ptr { - sliceValue = sliceValue.Elem() - } - - for i := 0; i < sliceValue.Len(); i++ { - element := sliceValue.Index(i) - if element.Kind() == reflect.Struct || (element.Kind() == reflect.Ptr && element.Elem().Kind() == reflect.Struct) { - _, err := BuildRequestBody(element.Interface(), "") - if err != nil { - return nil, err - } - } - } - } - if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { - if zero { - //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) - if jsonTag != "" { - jsonTagPieces := strings.Split(jsonTag, ",") - if len(jsonTagPieces) > 1 && jsonTagPieces[1] == "omitempty" { - if v.CanSet() { - if !v.IsNil() { - if v.Kind() == reflect.Ptr { - v.Set(reflect.Zero(v.Type())) - } - } - //fmt.Printf("value after change: %+v\n", optsValue.Field(i)) - } - } - } - continue - } - - //fmt.Printf("Calling BuildRequestBody with:\n\tv: %+v\n\tf.Name:%s\n", v.Interface(), f.Name) - _, err := BuildRequestBody(v.Interface(), f.Name) - if err != nil { - return nil, err - } - } - } - - //fmt.Printf("opts: %+v \n", opts) - - b, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - //fmt.Printf("string(b): %s\n", string(b)) - - err = json.Unmarshal(b, &optsMap) - if err != nil { - return nil, err - } - - //fmt.Printf("optsMap: %+v\n", optsMap) - - if parent != "" { - optsMap = map[string]interface{}{parent: optsMap} - } - //fmt.Printf("optsMap after parent added: %+v\n", optsMap) - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("options type is not a struct") -} - -// EnabledState is a convenience type, mostly used in Create and Update -// operations. Because the zero value of a bool is FALSE, we need to use a -// pointer instead to indicate zero-ness. -type EnabledState *bool - -// Convenience vars for EnabledState values. -var ( - iTrue = true - iFalse = false - - Enabled EnabledState = &iTrue - Disabled EnabledState = &iFalse -) - -// IPVersion is a type for the possible IP address versions. Valid instances -// are IPv4 and IPv6 -type IPVersion int - -const ( - // IPv4 is used for IP version 4 addresses - IPv4 IPVersion = 4 - // IPv6 is used for IP version 6 addresses - IPv6 IPVersion = 6 -) - -// IntToPointer is a function for converting integers into integer pointers. -// This is useful when passing in options to operations. -func IntToPointer(i int) *int { - return &i -} - -/* -MaybeString is an internal function to be used by request methods in individual -resource packages. - -It takes a string that might be a zero value and returns either a pointer to its -address or nil. This is useful for allowing users to conveniently omit values -from an options struct by leaving them zeroed, but still pass nil to the JSON -serializer so they'll be omitted from the request body. -*/ -func MaybeString(original string) *string { - if original != "" { - return &original - } - return nil -} - -/* -MaybeInt is an internal function to be used by request methods in individual -resource packages. - -Like MaybeString, it accepts an int that may or may not be a zero value, and -returns either a pointer to its address or nil. It's intended to hint that the -JSON serializer should omit its field. -*/ -func MaybeInt(original int) *int { - if original != 0 { - return &original - } - return nil -} - -/* -func isUnderlyingStructZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Ptr: - return isUnderlyingStructZero(v.Elem()) - default: - return isZero(v) - } -} -*/ - -var t time.Time - -func isZero(v reflect.Value) bool { - //fmt.Printf("\n\nchecking isZero for value: %+v\n", v) - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - return true - } - return false - case reflect.Func, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - z := true - for i := 0; i < v.Len(); i++ { - z = z && isZero(v.Index(i)) - } - return z - case reflect.Struct: - if v.Type() == reflect.TypeOf(t) { - return v.Interface().(time.Time).IsZero() - } - z := true - for i := 0; i < v.NumField(); i++ { - z = z && isZero(v.Field(i)) - } - return z - } - // Compare other types directly: - z := reflect.Zero(v.Type()) - //fmt.Printf("zero type for value: %+v\n\n\n", z) - return v.Interface() == z.Interface() -} - -/* -BuildQueryString is an internal function to be used by request methods in -individual resource packages. - -It accepts a tagged structure and expands it into a URL struct. Field names are -converted into query parameters based on a "q" tag. For example: - - type struct Something { - Bar string `q:"x_bar"` - Baz int `q:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into "?x_bar=AAA&lorem_ipsum=BBB". - -The struct's fields may be strings, integers, or boolean values. Fields left at -their type's zero value will be omitted from the query. -*/ -func BuildQueryString(opts interface{}) (*url.URL, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - params := url.Values{} - - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - qTag := f.Tag.Get("q") - - // if the field has a 'q' tag, it goes in the query string - if qTag != "" { - tags := strings.Split(qTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - loop: - switch v.Kind() { - case reflect.Ptr: - v = v.Elem() - goto loop - case reflect.String: - params.Add(tags[0], v.String()) - case reflect.Int: - params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) - case reflect.Bool: - params.Add(tags[0], strconv.FormatBool(v.Bool())) - case reflect.Slice: - switch v.Type().Elem() { - case reflect.TypeOf(0): - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10)) - } - default: - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], v.Index(i).String()) - } - } - case reflect.Map: - if v.Type().Key().Kind() == reflect.String && v.Type().Elem().Kind() == reflect.String { - var s []string - for _, k := range v.MapKeys() { - value := v.MapIndex(k).String() - s = append(s, fmt.Sprintf("'%s':'%s'", k.String(), value)) - } - params.Add(tags[0], fmt.Sprintf("{%s}", strings.Join(s, ", "))) - } - } - } else { - // if the field has a 'required' tag, it can't have a zero-value - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return &url.URL{}, fmt.Errorf("required query parameter [%s] not set", f.Name) - } - } - } - } - - return &url.URL{RawQuery: params.Encode()}, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("options type is not a struct") -} - -/* -BuildHeaders is an internal function to be used by request methods in -individual resource packages. - -It accepts an arbitrary tagged structure and produces a string map that's -suitable for use as the HTTP headers of an outgoing request. Field names are -mapped to header names based in "h" tags. - - type struct Something { - Bar string `h:"x_bar"` - Baz int `h:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into: - - map[string]string{ - "x_bar": "AAA", - "lorem_ipsum": "BBB", - } - -Untagged fields and fields left at their zero values are skipped. Integers, -booleans and string values are supported. -*/ -func BuildHeaders(opts interface{}) (map[string]string, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]string) - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - hTag := f.Tag.Get("h") - - // if the field has a 'h' tag, it goes in the header - if hTag != "" { - tags := strings.Split(hTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - switch v.Kind() { - case reflect.String: - optsMap[tags[0]] = v.String() - case reflect.Int: - optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) - case reflect.Bool: - optsMap[tags[0]] = strconv.FormatBool(v.Bool()) - } - } else { - // if the field has a 'required' tag, it can't have a zero-value - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return optsMap, fmt.Errorf("required header [%s] not set", f.Name) - } - } - } - - } - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return optsMap, fmt.Errorf("options type is not a struct") -} - -// IDSliceToQueryString takes a slice of elements and converts them into a query -// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the -// result would be `?name=20&name=40&name=60' -func IDSliceToQueryString(name string, ids []int) string { - str := "" - for k, v := range ids { - if k == 0 { - str += "?" - } else { - str += "&" - } - str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) - } - return str -} - -// IntWithinRange returns TRUE if an integer falls within a defined range, and -// FALSE if not. -func IntWithinRange(val, min, max int) bool { - return val > min && val < max -} diff --git a/v3/provider_client.go b/v3/provider_client.go deleted file mode 100644 index 5188c75..0000000 --- a/v3/provider_client.go +++ /dev/null @@ -1,402 +0,0 @@ -package eclcloud - -import ( - "bytes" - "encoding/json" - "io" - "io/ioutil" - "log" - "net/http" - "strings" - "sync" -) - -// DefaultUserAgent is the default User-Agent string set in the request header. -const DefaultUserAgent = "eclcloud/1.0.0" - -// UserAgent represents a User-Agent header. -type UserAgent struct { - // prepend is the slice of User-Agent strings to prepend to DefaultUserAgent. - // All the strings to prepend are accumulated and prepended in the Join method. - prepend []string -} - -// Prepend prepends a user-defined string to the default User-Agent string. Users -// may pass in one or more strings to prepend. -func (ua *UserAgent) Prepend(s ...string) { - ua.prepend = append(s, ua.prepend...) -} - -// Join concatenates all the user-defined User-Agend strings with the default -// Eclcloud User-Agent string. -func (ua *UserAgent) Join() string { - uaSlice := append(ua.prepend, DefaultUserAgent) - return strings.Join(uaSlice, " ") -} - -// ProviderClient stores details that are required to interact with any -// services within a specific provider's API. -// -// Generally, you acquire a ProviderClient by calling the NewClient method in -// the appropriate provider's child package, providing whatever authentication -// credentials are required. -type ProviderClient struct { - // IdentityBase is the base URL used for a particular provider's identity - // service - it will be used when issuing authenticatation requests. It - // should point to the root resource of the identity service, not a specific - // identity version. - IdentityBase string - - // IdentityEndpoint is the identity endpoint. This may be a specific version - // of the identity service. If this is the case, this endpoint is used rather - // than querying versions first. - IdentityEndpoint string - - // TokenID is the ID of the most recently issued valid token. - // NOTE: Aside from within a custom ReauthFunc, this field shouldn't be set by an application. - // To safely read or write this value, call `Token` or `SetToken`, respectively - TokenID string - - // EndpointLocator describes how this provider discovers the endpoints for - // its constituent services. - EndpointLocator EndpointLocator - - // HTTPClient allows users to interject arbitrary http, https, or other transit behaviors. - HTTPClient http.Client - - // UserAgent represents the User-Agent header in the HTTP request. - UserAgent UserAgent - - // ReauthFunc is the function used to re-authenticate the user if the request - // fails with a 401 HTTP response code. This a needed because there may be multiple - // authentication functions for different Identity service versions. - ReauthFunc func() error - - mut *sync.RWMutex - - reauthmut *reauthlock -} - -type reauthlock struct { - sync.RWMutex - reauthing bool -} - -// AuthenticatedHeaders returns a map of HTTP headers that are common for all -// authenticated service requests. -func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) { - if client.reauthmut != nil { - client.reauthmut.RLock() - if client.reauthmut.reauthing { - client.reauthmut.RUnlock() - return - } - client.reauthmut.RUnlock() - } - t := client.Token() - if t == "" { - return - } - return map[string]string{"X-Auth-Token": t} -} - -// UseTokenLock creates a mutex that is used to allow safe concurrent access to the auth token. -// If the application's ProviderClient is not used concurrently, this doesn't need to be called. -func (client *ProviderClient) UseTokenLock() { - client.mut = new(sync.RWMutex) - client.reauthmut = new(reauthlock) -} - -// Token safely reads the value of the auth token from the ProviderClient. Applications should -// call this method to access the token instead of the TokenID field -func (client *ProviderClient) Token() string { - if client.mut != nil { - client.mut.RLock() - defer client.mut.RUnlock() - } - return client.TokenID -} - -// SetToken safely sets the value of the auth token in the ProviderClient. Applications may -// use this method in a custom ReauthFunc -func (client *ProviderClient) SetToken(t string) { - if client.mut != nil { - client.mut.Lock() - defer client.mut.Unlock() - } - client.TokenID = t -} - -//Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is -//called because of a 401 response, the caller may pass the previous token. In -//this case, the reauthentication can be skipped if another thread has already -//reauthenticated in the meantime. If no previous token is known, an empty -//string should be passed instead to force unconditional reauthentication. -func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { - if client.ReauthFunc == nil { - return nil - } - - if client.mut == nil { - return client.ReauthFunc() - } - client.mut.Lock() - defer client.mut.Unlock() - - client.reauthmut.Lock() - client.reauthmut.reauthing = true - client.reauthmut.Unlock() - - if previousToken == "" || client.TokenID == previousToken { - err = client.ReauthFunc() - } - - client.reauthmut.Lock() - client.reauthmut.reauthing = false - client.reauthmut.Unlock() - return -} - -// RequestOpts customizes the behavior of the provider.Request() method. -type RequestOpts struct { - // JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The - // content type of the request will default to "application/json" unless overridden by MoreHeaders. - // It's an error to specify both a JSONBody and a RawBody. - JSONBody interface{} - // RawBody contains an io.Reader that will be consumed by the request directly. No content-type - // will be set unless one is provided explicitly by MoreHeaders. - RawBody io.Reader - // JSONResponse, if provided, will be populated with the contents of the response body parsed as - // JSON. - JSONResponse interface{} - // OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If - // the response has a different code, an error will be returned. - OkCodes []int - // MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is - // provided with a blank value (""), that header will be *omitted* instead: use this to suppress - // the default Accept header or an inferred Content-Type, for example. - MoreHeaders map[string]string - // ErrorContext specifies the resource error type to return if an error is encountered. - // This lets resources override default error messages based on the response status code. - ErrorContext error -} - -var applicationJSON = "application/json" - -// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication -// header will automatically be provided. -func (client *ProviderClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - var body io.Reader - var contentType *string - - log.Printf("[DEBUG] Request: %s %s", method, url) - - // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided - // io.ReadSeeker as-is. Default the content-type to application/json. - if options.JSONBody != nil { - if options.RawBody != nil { - panic("Please provide only one of JSONBody or RawBody to eclcloud.Request().") - } - - rendered, err := json.Marshal(options.JSONBody) - if err != nil { - return nil, err - } - - body = bytes.NewReader(rendered) - contentType = &applicationJSON - log.Printf("[DEBUG] Request body: %s", body) - - } - - if options.RawBody != nil { - body = options.RawBody - log.Printf("[DEBUG] Request body: %s", body) - } - - // Construct the http.Request. - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, err - } - - // Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to - // modify or omit any header. - if contentType != nil { - req.Header.Set("Content-Type", *contentType) - } - req.Header.Set("Accept", applicationJSON) - - // Set the User-Agent header - req.Header.Set("User-Agent", client.UserAgent.Join()) - - if options.MoreHeaders != nil { - for k, v := range options.MoreHeaders { - if v != "" { - req.Header.Set(k, v) - } else { - req.Header.Del(k) - } - } - } - - // get latest token from client - for k, v := range client.AuthenticatedHeaders() { - req.Header.Set(k, v) - } - - // Set connection parameter to close the connection immediately when we've got the response - req.Close = true - - prereqtok := req.Header.Get("X-Auth-Token") - - // Issue the request. - resp, err := client.HTTPClient.Do(req) - if err != nil { - return nil, err - } - - // Allow default OkCodes if none explicitly set - if options.OkCodes == nil { - options.OkCodes = defaultOkCodes(method) - } - - // Validate the HTTP response status. - var ok bool - for _, code := range options.OkCodes { - if resp.StatusCode == code { - ok = true - break - } - } - - if !ok { - body, _ := ioutil.ReadAll(resp.Body) - resp.Body.Close() - respErr := ErrUnexpectedResponseCode{ - URL: url, - Method: method, - Expected: options.OkCodes, - Actual: resp.StatusCode, - Body: body, - } - - errType := options.ErrorContext - switch resp.StatusCode { - case http.StatusBadRequest: - err = ErrDefault400{respErr} - if error400er, ok := errType.(Err400er); ok { - err = error400er.Error400(respErr) - } - case http.StatusUnauthorized: - if client.ReauthFunc != nil { - err = client.Reauthenticate(prereqtok) - if err != nil { - e := &ErrUnableToReauthenticate{} - e.ErrOriginal = respErr - return nil, e - } - if options.RawBody != nil { - if seeker, ok := options.RawBody.(io.Seeker); ok { - seeker.Seek(0, 0) - } - } - // make a new call to request with a nil reauth func in order to avoid infinite loop - reauthFunc := client.ReauthFunc - client.ReauthFunc = nil - resp, err = client.Request(method, url, options) - client.ReauthFunc = reauthFunc - if err != nil { - switch err.(type) { - case *ErrUnexpectedResponseCode: - e := &ErrErrorAfterReauthentication{} - e.ErrOriginal = err.(*ErrUnexpectedResponseCode) - return nil, e - default: - e := &ErrErrorAfterReauthentication{} - e.ErrOriginal = err - return nil, e - } - } - return resp, nil - } - err = ErrDefault401{respErr} - if error401er, ok := errType.(Err401er); ok { - err = error401er.Error401(respErr) - } - case http.StatusForbidden: - err = ErrDefault403{respErr} - if error403er, ok := errType.(Err403er); ok { - err = error403er.Error403(respErr) - } - case http.StatusNotFound: - err = ErrDefault404{respErr} - if error404er, ok := errType.(Err404er); ok { - err = error404er.Error404(respErr) - } - case http.StatusMethodNotAllowed: - err = ErrDefault405{respErr} - if error405er, ok := errType.(Err405er); ok { - err = error405er.Error405(respErr) - } - case http.StatusRequestTimeout: - err = ErrDefault408{respErr} - if error408er, ok := errType.(Err408er); ok { - err = error408er.Error408(respErr) - } - case http.StatusConflict: - err = ErrDefault409{respErr} - if error409er, ok := errType.(Err409er); ok { - err = error409er.Error409(respErr) - } - case 429: - err = ErrDefault429{respErr} - if error429er, ok := errType.(Err429er); ok { - err = error429er.Error429(respErr) - } - case http.StatusInternalServerError: - err = ErrDefault500{respErr} - if error500er, ok := errType.(Err500er); ok { - err = error500er.Error500(respErr) - } - case http.StatusServiceUnavailable: - err = ErrDefault503{respErr} - if error503er, ok := errType.(Err503er); ok { - err = error503er.Error503(respErr) - } - } - - if err == nil { - err = respErr - } - - return resp, err - } - - // Parse the response body as JSON, if requested to do so. - if options.JSONResponse != nil { - defer resp.Body.Close() - if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil { - return nil, err - } - } - - return resp, nil -} - -func defaultOkCodes(method string) []int { - switch { - case method == "GET": - return []int{200} - case method == "POST": - return []int{201, 202} - case method == "PUT": - return []int{201, 202} - case method == "PATCH": - return []int{200, 202, 204} - case method == "DELETE": - return []int{202, 204} - } - - return []int{} -} diff --git a/v3/results.go b/v3/results.go deleted file mode 100644 index 30e93ce..0000000 --- a/v3/results.go +++ /dev/null @@ -1,473 +0,0 @@ -package eclcloud - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - - // "log" - "log" - "net/http" - "reflect" - "strconv" - "time" -) - -/* -Result is an internal type to be used by individual resource packages, but its -methods will be available on a wide variety of user-facing embedding types. - -It acts as a base struct that other Result types, returned from request -functions, can embed for convenience. All Results capture basic information -from the HTTP transaction that was performed, including the response body, -HTTP headers, and any errors that happened. - -Generally, each Result type will have an Extract method that can be used to -further interpret the result's payload in a specific context. Extensions or -providers can then provide additional extraction functions to pull out -provider- or extension-specific information as well. -*/ -type Result struct { - // Body is the payload of the HTTP response from the server. In most cases, - // this will be the deserialized JSON structure. - Body interface{} - - // Header contains the HTTP header structure from the original response. - Header http.Header - - // Err is an error that occurred during the operation. It's deferred until - // extraction to make it easier to chain the Extract call. - Err error -} - -// ExtractInto allows users to provide an object into which `Extract` will extract -// the `Result.Body`. This would be useful for Enterprise Cloud providers that have -// different fields in the response object than Enterprise Cloud proper. -func (r Result) ExtractInto(to interface{}) error { - if r.Err != nil { - log.Printf("[DEBUG] Response body: %s", r.Err) - return r.Err - } - - if reader, ok := r.Body.(io.Reader); ok { - if readCloser, ok := reader.(io.Closer); ok { - defer readCloser.Close() - } - return json.NewDecoder(reader).Decode(to) - } - - b, err := json.Marshal(r.Body) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - log.Printf("[DEBUG] Response body: %s", b) - - return err -} - -func (r Result) extractIntoPtr(to interface{}, label string) error { - if label == "" { - return r.ExtractInto(&to) - } - - var m map[string]interface{} - err := r.ExtractInto(&m) - if err != nil { - return err - } - - b, err := json.Marshal(m[label]) - if err != nil { - return err - } - - toValue := reflect.ValueOf(to) - if toValue.Kind() == reflect.Ptr { - toValue = toValue.Elem() - } - - switch toValue.Kind() { - case reflect.Slice: - typeOfV := toValue.Type().Elem() - if typeOfV.Kind() == reflect.Struct { - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0) - - for _, v := range m[label].([]interface{}) { - // For each iteration of the slice, we create a new struct. - // This is to work around a bug where elements of a slice - // are reused and not overwritten when the same copy of the - // struct is used: - // - // https://github.com/golang/go/issues/21092 - // https://github.com/golang/go/issues/24155 - // https://play.golang.org/p/NHo3ywlPZli - newType := reflect.New(typeOfV).Elem() - - b, err := json.Marshal(v) - if err != nil { - return err - } - - // This is needed for structs with an UnmarshalJSON method. - // Technically this is just unmarshalling the response into - // a struct that is never used, but it's good enough to - // trigger the UnmarshalJSON method. - for i := 0; i < newType.NumField(); i++ { - s := newType.Field(i).Addr().Interface() - - // Unmarshal is used rather than NewDecoder to also work - // around the above-mentioned bug. - err = json.Unmarshal(b, s) - if err != nil { - return err - } - } - - newSlice = reflect.Append(newSlice, newType) - } - - // "to" should now be properly modeled to receive the - // JSON response body and unmarshal into all the correct - // fields of the struct or composed extension struct - // at the end of this method. - toValue.Set(newSlice) - } - } - case reflect.Struct: - typeOfV := toValue.Type() - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - for i := 0; i < toValue.NumField(); i++ { - toField := toValue.Field(i) - if toField.Kind() == reflect.Struct { - s := toField.Addr().Interface() - err = json.NewDecoder(bytes.NewReader(b)).Decode(s) - if err != nil { - return err - } - } - } - } - } - - err = json.Unmarshal(b, &to) - return err -} - -// ExtractIntoStructPtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying struct type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoStructPtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Struct: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("expected pointer to struct, got: %v", t) - } -} - -// ExtractIntoSlicePtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying slice type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoSlicePtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Slice: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("expected pointer to slice, got: %v", t) - } -} - -// PrettyPrintJSON creates a string containing the full response body as -// pretty-printed JSON. It's useful for capturing test fixtures and for -// debugging extraction bugs. If you include its output in an issue related to -// a buggy extraction function, we will all love you forever. -func (r Result) PrettyPrintJSON() string { - pretty, err := json.MarshalIndent(r.Body, "", " ") - if err != nil { - panic(err.Error()) - } - return string(pretty) -} - -// ErrResult is an internal type to be used by individual resource packages, but -// its methods will be available on a wide variety of user-facing embedding -// types. -// -// It represents results that only contain a potential error and -// nothing else. Usually, if the operation executed successfully, the Err field -// will be nil; otherwise it will be stocked with a relevant error. Use the -// ExtractErr method -// to cleanly pull it out. -type ErrResult struct { - Result -} - -// ExtractErr is a function that extracts error information, or nil, from a result. -func (r ErrResult) ExtractErr() error { - return r.Err -} - -/* -HeaderResult is an internal type to be used by individual resource packages, but -its methods will be available on a wide variety of user-facing embedding types. - -It represents a result that only contains an error (possibly nil) and an -http.Header. This is used, for example, by the objectstorage packages in -Enterprise Cloud, because most of the operations don't return response bodies, -but do have relevant information in headers. -*/ -type HeaderResult struct { - Result -} - -// ExtractInto allows users to provide an object into which `Extract` will -// extract the http.Header headers of the result. -func (r HeaderResult) ExtractInto(to interface{}) error { - if r.Err != nil { - return r.Err - } - - tmpHeaderMap := map[string]string{} - for k, v := range r.Header { - if len(v) > 0 { - tmpHeaderMap[k] = v[0] - } - } - - b, err := json.Marshal(tmpHeaderMap) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - return err -} - -// ISO8601 describes a common time format used by some API responses. -// Expecially in storage SDP of Enterprise Cloud 2.0 -const ISO8601 = "2006-01-02T15:04:05+0000" - -type JSONISO8601 time.Time - -func (jt *JSONISO8601) UnmarshalJSON(data []byte) error { - // log.Printf("[DEBUG] ISO8601::UnmarshalJSON") - b := bytes.NewBuffer(data) - dec := json.NewDecoder(b) - - var s string - if err := dec.Decode(&s); err != nil { - return err - } - - t, _ := time.Parse(ISO8601, s) - *jt = JSONISO8601(t) - return nil -} - -// RFC3339Milli describes a common time format used by some API responses. -const RFC3339Milli = "2006-01-02T15:04:05.999999Z" - -type JSONRFC3339Milli time.Time - -func (jt *JSONRFC3339Milli) UnmarshalJSON(data []byte) error { - b := bytes.NewBuffer(data) - dec := json.NewDecoder(b) - var s string - if err := dec.Decode(&s); err != nil { - return err - } - t, err := time.Parse(RFC3339Milli, s) - if err != nil { - return err - } - *jt = JSONRFC3339Milli(t) - return nil -} - -const RFC3339MilliNoZ = "2006-01-02T15:04:05.999999" - -type JSONRFC3339MilliNoZ time.Time - -func (jt *JSONRFC3339MilliNoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339MilliNoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339MilliNoZ(t) - return nil -} - -type JSONRFC1123 time.Time - -func (jt *JSONRFC1123) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(time.RFC1123, s) - if err != nil { - return err - } - *jt = JSONRFC1123(t) - return nil -} - -type JSONUnix time.Time - -func (jt *JSONUnix) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - unix, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return err - } - t = time.Unix(unix, 0) - *jt = JSONUnix(t) - return nil -} - -// RFC3339NoZ is the time format used in Heat (Orchestration). -const RFC3339NoZ = "2006-01-02T15:04:05" - -type JSONRFC3339NoZ time.Time - -func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339NoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339NoZ(t) - return nil -} - -// RFC3339ZNoT is the time format used in Zun (Containers Service). -const RFC3339ZNoT = "2006-01-02 15:04:05-07:00" - -type JSONRFC3339ZNoT time.Time - -func (jt *JSONRFC3339ZNoT) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339ZNoT, s) - if err != nil { - return err - } - *jt = JSONRFC3339ZNoT(t) - return nil -} - -// RFC3339ZNoTNoZ is another time format used in Zun (Containers Service). -const RFC3339ZNoTNoZ = "2006-01-02 15:04:05" - -type JSONRFC3339ZNoTNoZ time.Time - -func (jt *JSONRFC3339ZNoTNoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339ZNoTNoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339ZNoTNoZ(t) - return nil -} - -/* -Link is an internal type to be used in packages of collection resources that are -paginated in a certain way. - -It's a response substructure common to many paginated collection results that is -used to point to related pages. Usually, the one we care about is the one with -Rel field set to "next". -*/ -type Link struct { - Href string `json:"href"` - Rel string `json:"rel"` -} - -/* -ExtractNextURL is an internal function useful for packages of collection -resources that are paginated in a certain way. - -It attempts to extract the "next" URL from slice of Link structs, or -"" if no such URL is present. -*/ -func ExtractNextURL(links []Link) (string, error) { - var url string - - for _, l := range links { - if l.Rel == "next" { - url = l.Href - } - } - - if url == "" { - return "", nil - } - - return url, nil -} diff --git a/v3/service_client.go b/v3/service_client.go deleted file mode 100644 index 9cddab7..0000000 --- a/v3/service_client.go +++ /dev/null @@ -1,146 +0,0 @@ -package eclcloud - -import ( - "io" - "net/http" - "strings" -) - -// ServiceClient stores details required to interact with a specific service API implemented by a provider. -// Generally, you'll acquire these by calling the appropriate `New` method on a ProviderClient. -type ServiceClient struct { - // ProviderClient is a reference to the provider that implements this service. - *ProviderClient - - // Endpoint is the base URL of the service's API, acquired from a service catalog. - // It MUST end with a /. - Endpoint string - - // ResourceBase is the base URL shared by the resources within a service's API. It should include - // the API version and, like Endpoint, MUST end with a / if set. If not set, the Endpoint is used - // as-is, instead. - ResourceBase string - - // This is the service client type (e.g. compute, network). - Type string - - // The microversion of the service to use. Set this to use a particular microversion. - Microversion string - - // MoreHeaders allows users (or Eclcloud) to set service-wide headers on requests. Put another way, - // values set in this field will be set on all the HTTP requests the service client sends. - MoreHeaders map[string]string -} - -// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /. -func (client *ServiceClient) ResourceBaseURL() string { - if client.ResourceBase != "" { - return client.ResourceBase - } - return client.Endpoint -} - -// ServiceURL constructs a URL for a resource belonging to this provider. -func (client *ServiceClient) ServiceURL(parts ...string) string { - return client.ResourceBaseURL() + strings.Join(parts, "/") -} - -func (client *ServiceClient) initReqOpts(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) { - if v, ok := (JSONBody).(io.Reader); ok { - opts.RawBody = v - } else if JSONBody != nil { - opts.JSONBody = JSONBody - } - - if JSONResponse != nil { - opts.JSONResponse = JSONResponse - } - - if opts.MoreHeaders == nil { - opts.MoreHeaders = make(map[string]string) - } - - if client.Microversion != "" { - client.setMicroversionHeader(opts) - } -} - -// Get calls `Request` with the "GET" HTTP verb. -func (client *ServiceClient) Get(url string, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, JSONResponse, opts) - return client.Request("GET", url, opts) -} - -// Post calls `Request` with the "POST" HTTP verb. -func (client *ServiceClient) Post(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("POST", url, opts) -} - -// Put calls `Request` with the "PUT" HTTP verb. -func (client *ServiceClient) Put(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("PUT", url, opts) -} - -// Patch calls `Request` with the "PATCH" HTTP verb. -func (client *ServiceClient) Patch(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, JSONBody, JSONResponse, opts) - return client.Request("PATCH", url, opts) -} - -// Delete calls `Request` with the "DELETE" HTTP verb. -func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, nil, opts) - return client.Request("DELETE", url, opts) -} - -// Head calls `Request` with the "HEAD" HTTP verb. -func (client *ServiceClient) Head(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(url, nil, nil, opts) - return client.Request("HEAD", url, opts) -} - -func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { - switch client.Type { - case "compute": - opts.MoreHeaders["X-OpenStack-Nova-API-Version"] = client.Microversion - case "volume": - opts.MoreHeaders["X-OpenStack-Volume-API-Version"] = client.Microversion - } - - if client.Type != "" { - opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion - } -} - -// Request carries out the HTTP operation for the service client -func (client *ServiceClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - if len(client.MoreHeaders) > 0 { - if options == nil { - options = new(RequestOpts) - } - for k, v := range client.MoreHeaders { - options.MoreHeaders[k] = v - } - } - return client.ProviderClient.Request(method, url, options) -} diff --git a/v3/testhelper/client/fake.go b/v3/testhelper/client/fake.go deleted file mode 100644 index 1eee3ca..0000000 --- a/v3/testhelper/client/fake.go +++ /dev/null @@ -1,17 +0,0 @@ -package client - -import ( - "github.com/nttcom/eclcloud/v3" - "github.com/nttcom/eclcloud/v3/testhelper" -) - -// Fake token to use. -const TokenID = "cbc36478b0bd8e67e89469c7749d4127" - -// ServiceClient returns a generic service client for use in tests. -func ServiceClient() *eclcloud.ServiceClient { - return &eclcloud.ServiceClient{ - ProviderClient: &eclcloud.ProviderClient{TokenID: TokenID}, - Endpoint: testhelper.Endpoint(), - } -} diff --git a/v3/testhelper/convenience.go b/v3/testhelper/convenience.go deleted file mode 100644 index 25f6720..0000000 --- a/v3/testhelper/convenience.go +++ /dev/null @@ -1,348 +0,0 @@ -package testhelper - -import ( - "bytes" - "encoding/json" - "fmt" - "path/filepath" - "reflect" - "runtime" - "strings" - "testing" -) - -const ( - logBodyFmt = "\033[1;31m%s %s\033[0m" - greenCode = "\033[0m\033[1;32m" - yellowCode = "\033[0m\033[1;33m" - resetCode = "\033[0m\033[1;31m" -) - -func prefix(depth int) string { - _, file, line, _ := runtime.Caller(depth) - return fmt.Sprintf("Failure in %s, line %d:", filepath.Base(file), line) -} - -func green(str interface{}) string { - return fmt.Sprintf("%s%#v%s", greenCode, str, resetCode) -} - -func yellow(str interface{}) string { - return fmt.Sprintf("%s%#v%s", yellowCode, str, resetCode) -} - -func logFatal(t *testing.T, str string) { - t.Fatalf(logBodyFmt, prefix(3), str) -} - -func logError(t *testing.T, str string) { - t.Errorf(logBodyFmt, prefix(3), str) -} - -type diffLogger func([]string, interface{}, interface{}) - -type visit struct { - a1 uintptr - a2 uintptr - typ reflect.Type -} - -// Recursively visits the structures of "expected" and "actual". The diffLogger function will be -// invoked with each different value encountered, including the reference path that was followed -// to get there. -func deepDiffEqual(expected, actual reflect.Value, visited map[visit]bool, path []string, logDifference diffLogger) { - defer func() { - // Fall back to the regular reflect.DeepEquals function. - if r := recover(); r != nil { - var e, a interface{} - if expected.IsValid() { - e = expected.Interface() - } - if actual.IsValid() { - a = actual.Interface() - } - - if !reflect.DeepEqual(e, a) { - logDifference(path, e, a) - } - } - }() - - if !expected.IsValid() && actual.IsValid() { - logDifference(path, nil, actual.Interface()) - return - } - if expected.IsValid() && !actual.IsValid() { - logDifference(path, expected.Interface(), nil) - return - } - if !expected.IsValid() && !actual.IsValid() { - return - } - - hard := func(k reflect.Kind) bool { - switch k { - case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: - return true - } - return false - } - - if expected.CanAddr() && actual.CanAddr() && hard(expected.Kind()) { - addr1 := expected.UnsafeAddr() - addr2 := actual.UnsafeAddr() - - if addr1 > addr2 { - addr1, addr2 = addr2, addr1 - } - - if addr1 == addr2 { - // References are identical. We can short-circuit - return - } - - typ := expected.Type() - v := visit{addr1, addr2, typ} - if visited[v] { - // Already visited. - return - } - - // Remember this visit for later. - visited[v] = true - } - - switch expected.Kind() { - case reflect.Array: - for i := 0; i < expected.Len(); i++ { - hop := append(path, fmt.Sprintf("[%d]", i)) - deepDiffEqual(expected.Index(i), actual.Index(i), visited, hop, logDifference) - } - return - case reflect.Slice: - if expected.IsNil() != actual.IsNil() { - logDifference(path, expected.Interface(), actual.Interface()) - return - } - if expected.Len() == actual.Len() && expected.Pointer() == actual.Pointer() { - return - } - for i := 0; i < expected.Len(); i++ { - hop := append(path, fmt.Sprintf("[%d]", i)) - deepDiffEqual(expected.Index(i), actual.Index(i), visited, hop, logDifference) - } - return - case reflect.Interface: - if expected.IsNil() != actual.IsNil() { - logDifference(path, expected.Interface(), actual.Interface()) - return - } - deepDiffEqual(expected.Elem(), actual.Elem(), visited, path, logDifference) - return - case reflect.Ptr: - deepDiffEqual(expected.Elem(), actual.Elem(), visited, path, logDifference) - return - case reflect.Struct: - for i, n := 0, expected.NumField(); i < n; i++ { - field := expected.Type().Field(i) - hop := append(path, "."+field.Name) - deepDiffEqual(expected.Field(i), actual.Field(i), visited, hop, logDifference) - } - return - case reflect.Map: - if expected.IsNil() != actual.IsNil() { - logDifference(path, expected.Interface(), actual.Interface()) - return - } - if expected.Len() == actual.Len() && expected.Pointer() == actual.Pointer() { - return - } - - var keys []reflect.Value - if expected.Len() >= actual.Len() { - keys = expected.MapKeys() - } else { - keys = actual.MapKeys() - } - - for _, k := range keys { - expectedValue := expected.MapIndex(k) - actualValue := actual.MapIndex(k) - - if !expectedValue.IsValid() { - logDifference(path, nil, actual.Interface()) - return - } - if !actualValue.IsValid() { - logDifference(path, expected.Interface(), nil) - return - } - - hop := append(path, fmt.Sprintf("[%v]", k)) - deepDiffEqual(expectedValue, actualValue, visited, hop, logDifference) - } - return - case reflect.Func: - if expected.IsNil() != actual.IsNil() { - logDifference(path, expected.Interface(), actual.Interface()) - } - return - default: - if expected.Interface() != actual.Interface() { - logDifference(path, expected.Interface(), actual.Interface()) - } - } -} - -func deepDiff(expected, actual interface{}, logDifference diffLogger) { - if expected == nil || actual == nil { - logDifference([]string{}, expected, actual) - return - } - - expectedValue := reflect.ValueOf(expected) - actualValue := reflect.ValueOf(actual) - - if expectedValue.Type() != actualValue.Type() { - logDifference([]string{}, expected, actual) - return - } - deepDiffEqual(expectedValue, actualValue, map[visit]bool{}, []string{}, logDifference) -} - -// AssertEquals compares two arbitrary values and performs a comparison. If the -// comparison fails, a fatal error is raised that will fail the test -func AssertEquals(t *testing.T, expected, actual interface{}) { - if expected != actual { - logFatal(t, fmt.Sprintf("expected %s but got %s", green(expected), yellow(actual))) - } -} - -// CheckEquals is similar to AssertEquals, except with a non-fatal error -func CheckEquals(t *testing.T, expected, actual interface{}) { - if expected != actual { - logError(t, fmt.Sprintf("expected %s but got %s", green(expected), yellow(actual))) - } -} - -// AssertDeepEquals - like Equals - performs a comparison - but on more complex -// structures that requires deeper inspection -func AssertDeepEquals(t *testing.T, expected, actual interface{}) { - pre := prefix(2) - - differed := false - deepDiff(expected, actual, func(path []string, expected, actual interface{}) { - differed = true - t.Errorf("\033[1;31m%sat %s expected %s, but got %s\033[0m", - pre, - strings.Join(path, ""), - green(expected), - yellow(actual)) - }) - if differed { - logFatal(t, "The structures were different.") - } -} - -// CheckDeepEquals is similar to AssertDeepEquals, except with a non-fatal error -func CheckDeepEquals(t *testing.T, expected, actual interface{}) { - pre := prefix(2) - - deepDiff(expected, actual, func(path []string, expected, actual interface{}) { - t.Errorf("\033[1;31m%s at %s expected %s, but got %s\033[0m", - pre, - strings.Join(path, ""), - green(expected), - yellow(actual)) - }) -} - -func isByteArrayEquals(t *testing.T, expectedBytes []byte, actualBytes []byte) bool { - return bytes.Equal(expectedBytes, actualBytes) -} - -// AssertByteArrayEquals a convenience function for checking whether two byte arrays are equal -func AssertByteArrayEquals(t *testing.T, expectedBytes []byte, actualBytes []byte) { - if !isByteArrayEquals(t, expectedBytes, actualBytes) { - logFatal(t, "The bytes differed.") - } -} - -// CheckByteArrayEquals a convenience function for silent checking whether two byte arrays are equal -func CheckByteArrayEquals(t *testing.T, expectedBytes []byte, actualBytes []byte) { - if !isByteArrayEquals(t, expectedBytes, actualBytes) { - logError(t, "The bytes differed.") - } -} - -// isJSONEquals is a utility function that implements JSON comparison for AssertJSONEquals and -// CheckJSONEquals. -func isJSONEquals(t *testing.T, expectedJSON string, actual interface{}) bool { - var parsedExpected, parsedActual interface{} - err := json.Unmarshal([]byte(expectedJSON), &parsedExpected) - if err != nil { - t.Errorf("Unable to parse expected value as JSON: %v", err) - return false - } - - jsonActual, err := json.Marshal(actual) - AssertNoErr(t, err) - err = json.Unmarshal(jsonActual, &parsedActual) - AssertNoErr(t, err) - - if !reflect.DeepEqual(parsedExpected, parsedActual) { - prettyExpected, err := json.MarshalIndent(parsedExpected, "", " ") - if err != nil { - t.Logf("Unable to pretty-print expected JSON: %v\n%s", err, expectedJSON) - } else { - // We can't use green() here because %#v prints prettyExpected as a byte array literal, which - // is... unhelpful. Converting it to a string first leaves "\n" uninterpreted for some reason. - t.Logf("Expected JSON:\n%s%s%s", greenCode, prettyExpected, resetCode) - } - - prettyActual, err := json.MarshalIndent(actual, "", " ") - if err != nil { - t.Logf("Unable to pretty-print actual JSON: %v\n%#v", err, actual) - } else { - // We can't use yellow() for the same reason. - t.Logf("Actual JSON:\n%s%s%s", yellowCode, prettyActual, resetCode) - } - - return false - } - return true -} - -// AssertJSONEquals serializes a value as JSON, parses an expected string as JSON, and ensures that -// both are consistent. If they aren't, the expected and actual structures are pretty-printed and -// shown for comparison. -// -// This is useful for comparing structures that are built as nested map[string]interface{} values, -// which are a pain to construct as literals. -func AssertJSONEquals(t *testing.T, expectedJSON string, actual interface{}) { - if !isJSONEquals(t, expectedJSON, actual) { - logFatal(t, "The generated JSON structure differed.") - } -} - -// CheckJSONEquals is similar to AssertJSONEquals, but nonfatal. -func CheckJSONEquals(t *testing.T, expectedJSON string, actual interface{}) { - if !isJSONEquals(t, expectedJSON, actual) { - logError(t, "The generated JSON structure differed.") - } -} - -// AssertNoErr is a convenience function for checking whether an error value is -// an actual error -func AssertNoErr(t *testing.T, e error) { - if e != nil { - logFatal(t, fmt.Sprintf("unexpected error %s", yellow(e.Error()))) - } -} - -// CheckNoErr is similar to AssertNoErr, except with a non-fatal error -func CheckNoErr(t *testing.T, e error) { - if e != nil { - logError(t, fmt.Sprintf("unexpected error %s", yellow(e.Error()))) - } -} diff --git a/v3/testhelper/doc.go b/v3/testhelper/doc.go deleted file mode 100644 index 25b4dfe..0000000 --- a/v3/testhelper/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -/* -Package testhelper container methods that are useful for writing unit tests. -*/ -package testhelper diff --git a/v3/testhelper/fixture/helper.go b/v3/testhelper/fixture/helper.go deleted file mode 100644 index 5b9265d..0000000 --- a/v3/testhelper/fixture/helper.go +++ /dev/null @@ -1,31 +0,0 @@ -package fixture - -import ( - "fmt" - "net/http" - "testing" - - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func SetupHandler(t *testing.T, url, method, requestBody, responseBody string, status int) { - th.Mux.HandleFunc(url, func(w http.ResponseWriter, r *http.Request) { - th.TestMethod(t, r, method) - th.TestHeader(t, r, "X-Auth-Token", client.TokenID) - - if requestBody != "" { - th.TestJSONRequest(t, r, requestBody) - } - - if responseBody != "" { - w.Header().Add("Content-Type", "application/json") - } - - w.WriteHeader(status) - - if responseBody != "" { - fmt.Fprintf(w, responseBody) - } - }) -} diff --git a/v3/testhelper/http_responses.go b/v3/testhelper/http_responses.go deleted file mode 100644 index e1f1f9a..0000000 --- a/v3/testhelper/http_responses.go +++ /dev/null @@ -1,91 +0,0 @@ -package testhelper - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "net/http/httptest" - "net/url" - "reflect" - "testing" -) - -var ( - // Mux is a multiplexer that can be used to register handlers. - Mux *http.ServeMux - - // Server is an in-memory HTTP server for testing. - Server *httptest.Server -) - -// SetupHTTP prepares the Mux and Server. -func SetupHTTP() { - Mux = http.NewServeMux() - Server = httptest.NewServer(Mux) -} - -// TeardownHTTP releases HTTP-related resources. -func TeardownHTTP() { - Server.Close() -} - -// Endpoint returns a fake endpoint that will actually target the Mux. -func Endpoint() string { - return Server.URL + "/" -} - -// TestFormValues ensures that all the URL parameters given to the http.Request are the same as values. -func TestFormValues(t *testing.T, r *http.Request, values map[string]string) { - want := url.Values{} - for k, v := range values { - want.Add(k, v) - } - - r.ParseForm() - if !reflect.DeepEqual(want, r.Form) { - t.Errorf("Request parameters = %v, want %v", r.Form, want) - } -} - -// TestMethod checks that the Request has the expected method (e.g. GET, POST). -func TestMethod(t *testing.T, r *http.Request, expected string) { - if expected != r.Method { - t.Errorf("Request method = %v, expected %v", r.Method, expected) - } -} - -// TestHeader checks that the header on the http.Request matches the expected value. -func TestHeader(t *testing.T, r *http.Request, header string, expected string) { - if actual := r.Header.Get(header); expected != actual { - t.Errorf("Header %s = %s, expected %s", header, actual, expected) - } -} - -// TestBody verifies that the request body matches an expected body. -func TestBody(t *testing.T, r *http.Request, expected string) { - b, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Errorf("Unable to read body: %v", err) - } - str := string(b) - if expected != str { - t.Errorf("Body = %s, expected %s", str, expected) - } -} - -// TestJSONRequest verifies that the JSON payload of a request matches an expected structure, without asserting things about -// whitespace or ordering. -func TestJSONRequest(t *testing.T, r *http.Request, expected string) { - b, err := ioutil.ReadAll(r.Body) - if err != nil { - t.Errorf("Unable to read request body: %v", err) - } - - var actualJSON interface{} - err = json.Unmarshal(b, &actualJSON) - if err != nil { - t.Errorf("Unable to parse request body as JSON: %v", err) - } - - CheckJSONEquals(t, expected, actualJSON) -} diff --git a/v3/testing/doc.go b/v3/testing/doc.go deleted file mode 100644 index 6336d11..0000000 --- a/v3/testing/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package testing contains eclcloud tests. -package testing diff --git a/v3/testing/endpoint_search_test.go b/v3/testing/endpoint_search_test.go deleted file mode 100644 index f3d26a1..0000000 --- a/v3/testing/endpoint_search_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package testing - -import ( - "testing" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestApplyDefaultsToEndpointOpts(t *testing.T) { - eo := eclcloud.EndpointOpts{Availability: eclcloud.AvailabilityPublic} - eo.ApplyDefaults("compute") - expected := eclcloud.EndpointOpts{Availability: eclcloud.AvailabilityPublic, Type: "compute"} - th.CheckDeepEquals(t, expected, eo) - - eo = eclcloud.EndpointOpts{Type: "compute"} - eo.ApplyDefaults("object-store") - expected = eclcloud.EndpointOpts{Availability: eclcloud.AvailabilityPublic, Type: "compute"} - th.CheckDeepEquals(t, expected, eo) -} diff --git a/v3/testing/params_test.go b/v3/testing/params_test.go deleted file mode 100644 index f61389e..0000000 --- a/v3/testing/params_test.go +++ /dev/null @@ -1,276 +0,0 @@ -package testing - -import ( - "net/url" - "reflect" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestMaybeString(t *testing.T) { - testString := "" - var expected *string - actual := eclcloud.MaybeString(testString) - th.CheckDeepEquals(t, expected, actual) - - testString = "carol" - expected = &testString - actual = eclcloud.MaybeString(testString) - th.CheckDeepEquals(t, expected, actual) -} - -func TestMaybeInt(t *testing.T) { - testInt := 0 - var expected *int - actual := eclcloud.MaybeInt(testInt) - th.CheckDeepEquals(t, expected, actual) - - testInt = 4 - expected = &testInt - actual = eclcloud.MaybeInt(testInt) - th.CheckDeepEquals(t, expected, actual) -} - -func TestBuildQueryString(t *testing.T) { - type testVar string - iFalse := false - opts := struct { - J int `q:"j"` - R string `q:"r" required:"true"` - C bool `q:"c"` - S []string `q:"s"` - TS []testVar `q:"ts"` - TI []int `q:"ti"` - F *bool `q:"f"` - M map[string]string `q:"m"` - }{ - J: 2, - R: "red", - C: true, - S: []string{"one", "two", "three"}, - TS: []testVar{"a", "b"}, - TI: []int{1, 2}, - F: &iFalse, - M: map[string]string{"k1": "success1"}, - } - expected := &url.URL{RawQuery: "c=true&f=false&j=2&m=%7B%27k1%27%3A%27success1%27%7D&r=red&s=one&s=two&s=three&ti=1&ti=2&ts=a&ts=b"} - actual, err := eclcloud.BuildQueryString(&opts) - if err != nil { - t.Errorf("Error building query string: %v", err) - } - th.CheckDeepEquals(t, expected, actual) - - opts = struct { - J int `q:"j"` - R string `q:"r" required:"true"` - C bool `q:"c"` - S []string `q:"s"` - TS []testVar `q:"ts"` - TI []int `q:"ti"` - F *bool `q:"f"` - M map[string]string `q:"m"` - }{ - J: 2, - C: true, - } - _, err = eclcloud.BuildQueryString(&opts) - if err == nil { - t.Errorf("Expected error: 'Required field not set'") - } - th.CheckDeepEquals(t, expected, actual) - - _, err = eclcloud.BuildQueryString(map[string]interface{}{"Number": 4}) - if err == nil { - t.Errorf("Expected error: 'Options type is not a struct'") - } -} - -func TestBuildHeaders(t *testing.T) { - testStruct := struct { - Accept string `h:"Accept"` - Num int `h:"Number" required:"true"` - Style bool `h:"Style"` - }{ - Accept: "application/json", - Num: 4, - Style: true, - } - expected := map[string]string{"Accept": "application/json", "Number": "4", "Style": "true"} - actual, err := eclcloud.BuildHeaders(&testStruct) - th.CheckNoErr(t, err) - th.CheckDeepEquals(t, expected, actual) - - testStruct.Num = 0 - _, err = eclcloud.BuildHeaders(&testStruct) - if err == nil { - t.Errorf("Expected error: 'Required header not set'") - } - - _, err = eclcloud.BuildHeaders(map[string]interface{}{"Number": 4}) - if err == nil { - t.Errorf("Expected error: 'Options type is not a struct'") - } -} - -func TestQueriesAreEscaped(t *testing.T) { - type foo struct { - Name string `q:"something"` - Shape string `q:"else"` - } - - expected := &url.URL{RawQuery: "else=Triangl+e&something=blah%2B%3F%21%21foo"} - - actual, err := eclcloud.BuildQueryString(foo{Name: "blah+?!!foo", Shape: "Triangl e"}) - th.AssertNoErr(t, err) - - th.AssertDeepEquals(t, expected, actual) -} - -func TestBuildRequestBody(t *testing.T) { - type PasswordCredentials struct { - Username string `json:"username" required:"true"` - Password string `json:"password" required:"true"` - } - - type TokenCredentials struct { - ID string `json:"id,omitempty" required:"true"` - } - - type orFields struct { - Filler int `json:"filler,omitempty"` - F1 int `json:"f1,omitempty" or:"F2"` - F2 int `json:"f2,omitempty" or:"F1"` - } - - // AuthOptions wraps a eclcloud AuthOptions in order to adhere to the AuthOptionsBuilder - // interface. - type AuthOptions struct { - PasswordCredentials *PasswordCredentials `json:"passwordCredentials,omitempty" xor:"TokenCredentials"` - - // The TenantID and TenantName fields are optional for the Identity V2 API. - // Some providers allow you to specify a TenantName instead of the TenantId. - // Some require both. Your provider's authentication policies will determine - // how these fields influence authentication. - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - - // TokenCredentials allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenCredentials *TokenCredentials `json:"token,omitempty" xor:"PasswordCredentials"` - - OrFields *orFields `json:"or_fields,omitempty"` - } - - var successCases = []struct { - opts AuthOptions - expected map[string]interface{} - }{ - { - AuthOptions{ - PasswordCredentials: &PasswordCredentials{ - Username: "me", - Password: "swordfish", - }, - }, - map[string]interface{}{ - "auth": map[string]interface{}{ - "passwordCredentials": map[string]interface{}{ - "password": "swordfish", - "username": "me", - }, - }, - }, - }, - { - AuthOptions{ - TokenCredentials: &TokenCredentials{ - ID: "1234567", - }, - }, - map[string]interface{}{ - "auth": map[string]interface{}{ - "token": map[string]interface{}{ - "id": "1234567", - }, - }, - }, - }, - } - - for _, successCase := range successCases { - actual, err := eclcloud.BuildRequestBody(successCase.opts, "auth") - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, successCase.expected, actual) - } - - var failCases = []struct { - opts AuthOptions - expected error - }{ - { - AuthOptions{ - TenantID: "987654321", - TenantName: "me", - }, - eclcloud.ErrMissingInput{}, - }, - { - AuthOptions{ - TokenCredentials: &TokenCredentials{ - ID: "1234567", - }, - PasswordCredentials: &PasswordCredentials{ - Username: "me", - Password: "swordfish", - }, - }, - eclcloud.ErrMissingInput{}, - }, - { - AuthOptions{ - PasswordCredentials: &PasswordCredentials{ - Password: "swordfish", - }, - }, - eclcloud.ErrMissingInput{}, - }, - { - AuthOptions{ - PasswordCredentials: &PasswordCredentials{ - Username: "me", - Password: "swordfish", - }, - OrFields: &orFields{ - Filler: 2, - }, - }, - eclcloud.ErrMissingInput{}, - }, - } - - for _, failCase := range failCases { - _, err := eclcloud.BuildRequestBody(failCase.opts, "auth") - th.AssertDeepEquals(t, reflect.TypeOf(failCase.expected), reflect.TypeOf(err)) - } - - createdAt := time.Date(2018, 1, 4, 10, 00, 12, 0, time.UTC) - var complexFields = struct { - Username string `json:"username" required:"true"` - CreatedAt *time.Time `json:"-"` - }{ - Username: "jdoe", - CreatedAt: &createdAt, - } - - expectedComplexFields := map[string]interface{}{ - "username": "jdoe", - } - - actual, err := eclcloud.BuildRequestBody(complexFields, "") - th.AssertNoErr(t, err) - th.AssertDeepEquals(t, expectedComplexFields, actual) - -} diff --git a/v3/testing/provider_client_test.go b/v3/testing/provider_client_test.go deleted file mode 100644 index ec4ae05..0000000 --- a/v3/testing/provider_client_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package testing - -import ( - "fmt" - "io/ioutil" - "net/http" - "reflect" - "sync" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" - "github.com/nttcom/eclcloud/v3/testhelper/client" -) - -func TestAuthenticatedHeaders(t *testing.T) { - p := &eclcloud.ProviderClient{ - TokenID: "1234", - } - expected := map[string]string{"X-Auth-Token": "1234"} - actual := p.AuthenticatedHeaders() - th.CheckDeepEquals(t, expected, actual) -} - -func TestUserAgent(t *testing.T) { - p := &eclcloud.ProviderClient{} - - p.UserAgent.Prepend("custom-user-agent/2.4.0") - expected := "custom-user-agent/2.4.0 eclcloud/1.0.0" - actual := p.UserAgent.Join() - th.CheckEquals(t, expected, actual) - - p.UserAgent.Prepend("another-custom-user-agent/0.3.0", "a-third-ua/5.9.0") - expected = "another-custom-user-agent/0.3.0 a-third-ua/5.9.0 custom-user-agent/2.4.0 eclcloud/1.0.0" - actual = p.UserAgent.Join() - th.CheckEquals(t, expected, actual) - - p.UserAgent = eclcloud.UserAgent{} - expected = "eclcloud/1.0.0" - actual = p.UserAgent.Join() - th.CheckEquals(t, expected, actual) -} - -func TestConcurrentReauth(t *testing.T) { - var info = struct { - numreauths int - mut *sync.RWMutex - }{ - 0, - new(sync.RWMutex), - } - - numconc := 20 - - prereauthTok := client.TokenID - postreauthTok := "12345678" - - p := new(eclcloud.ProviderClient) - p.UseTokenLock() - p.SetToken(prereauthTok) - p.ReauthFunc = func() error { - time.Sleep(1 * time.Second) - p.AuthenticatedHeaders() - info.mut.Lock() - info.numreauths++ - info.mut.Unlock() - p.TokenID = postreauthTok - return nil - } - - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("X-Auth-Token") != postreauthTok { - w.WriteHeader(http.StatusUnauthorized) - return - } - info.mut.RLock() - hasReauthed := info.numreauths != 0 - info.mut.RUnlock() - - if hasReauthed { - th.CheckEquals(t, p.Token(), postreauthTok) - } - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintf(w, `{}`) - }) - - wg := new(sync.WaitGroup) - reqopts := new(eclcloud.RequestOpts) - reqopts.MoreHeaders = map[string]string{ - "X-Auth-Token": prereauthTok, - } - - for i := 0; i < numconc; i++ { - wg.Add(1) - go func() { - defer wg.Done() - resp, err := p.Request("GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts) - th.CheckNoErr(t, err) - if resp == nil { - t.Errorf("got a nil response") - return - } - if resp.Body == nil { - t.Errorf("response body was nil") - return - } - defer resp.Body.Close() - actual, err := ioutil.ReadAll(resp.Body) - if err != nil { - t.Errorf("error reading response body: %s", err) - return - } - th.CheckByteArrayEquals(t, []byte(`{}`), actual) - }() - } - - wg.Wait() - - th.AssertEquals(t, 1, info.numreauths) -} - -func TestReauthEndLoop(t *testing.T) { - - p := new(eclcloud.ProviderClient) - p.UseTokenLock() - p.SetToken(client.TokenID) - p.ReauthFunc = func() error { - // Reauth func is working and returns no error - return nil - } - - th.SetupHTTP() - defer th.TeardownHTTP() - - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { - // route always return 401 - w.WriteHeader(http.StatusUnauthorized) - }) - - reqopts := new(eclcloud.RequestOpts) - _, err := p.Request("GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts) - if err == nil { - t.Errorf("request ends with a nil error") - return - } - - if reflect.TypeOf(err) != reflect.TypeOf(&eclcloud.ErrErrorAfterReauthentication{}) { - t.Errorf("error is not an ErrErrorAfterReauthentication") - } -} diff --git a/v3/testing/results_test.go b/v3/testing/results_test.go deleted file mode 100644 index 7d4e2da..0000000 --- a/v3/testing/results_test.go +++ /dev/null @@ -1,208 +0,0 @@ -package testing - -import ( - "encoding/json" - "testing" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -var singleResponse = ` -{ - "person": { - "name": "Bill", - "email": "bill@example.com", - "location": "Canada" - } -} -` - -var multiResponse = ` -{ - "people": [ - { - "name": "Bill", - "email": "bill@example.com", - "location": "Canada" - }, - { - "name": "Ted", - "email": "ted@example.com", - "location": "Mexico" - } - ] -} -` - -type TestPerson struct { - Name string `json:"-"` - Email string `json:"email"` -} - -func (r *TestPerson) UnmarshalJSON(b []byte) error { - type tmp TestPerson - var s struct { - tmp - Name string `json:"name"` - } - - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - - *r = TestPerson(s.tmp) - r.Name = s.Name + " unmarshalled" - - return nil -} - -type TestPersonExt struct { - Location string `json:"-"` -} - -func (r *TestPersonExt) UnmarshalJSON(b []byte) error { - type tmp TestPersonExt - var s struct { - tmp - Location string `json:"location"` - } - - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - - *r = TestPersonExt(s.tmp) - r.Location = s.Location + " unmarshalled" - - return nil -} - -type TestPersonWithExtensions struct { - TestPerson - TestPersonExt -} - -type TestPersonWithExtensionsNamed struct { - TestPerson TestPerson - TestPersonExt TestPersonExt -} - -// TestUnmarshalAnonymousStruct tests if UnmarshalJSON is called on each -// of the anonymous structs contained in an overarching struct. -func TestUnmarshalAnonymousStructs(t *testing.T) { - var actual TestPersonWithExtensions - - var dejson interface{} - sejson := []byte(singleResponse) - err := json.Unmarshal(sejson, &dejson) - if err != nil { - t.Fatal(err) - } - - var singleResult = eclcloud.Result{ - Body: dejson, - } - - err = singleResult.ExtractIntoStructPtr(&actual, "person") - th.AssertNoErr(t, err) - - th.AssertEquals(t, "Bill unmarshalled", actual.Name) - th.AssertEquals(t, "Canada unmarshalled", actual.Location) -} - -// TestUnmarshalSliceofAnonymousStructs tests if UnmarshalJSON is called on each -// of the anonymous structs contained in an overarching struct slice. -func TestUnmarshalSliceOfAnonymousStructs(t *testing.T) { - var actual []TestPersonWithExtensions - - var dejson interface{} - sejson := []byte(multiResponse) - err := json.Unmarshal(sejson, &dejson) - if err != nil { - t.Fatal(err) - } - - var multiResult = eclcloud.Result{ - Body: dejson, - } - - err = multiResult.ExtractIntoSlicePtr(&actual, "people") - th.AssertNoErr(t, err) - - th.AssertEquals(t, "Bill unmarshalled", actual[0].Name) - th.AssertEquals(t, "Canada unmarshalled", actual[0].Location) - th.AssertEquals(t, "Ted unmarshalled", actual[1].Name) - th.AssertEquals(t, "Mexico unmarshalled", actual[1].Location) -} - -// TestUnmarshalSliceOfStruct tests if extracting results from a "normal" -// struct still works correctly. -func TestUnmarshalSliceofStruct(t *testing.T) { - var actual []TestPerson - - var dejson interface{} - sejson := []byte(multiResponse) - err := json.Unmarshal(sejson, &dejson) - if err != nil { - t.Fatal(err) - } - - var multiResult = eclcloud.Result{ - Body: dejson, - } - - err = multiResult.ExtractIntoSlicePtr(&actual, "people") - th.AssertNoErr(t, err) - - th.AssertEquals(t, "Bill unmarshalled", actual[0].Name) - th.AssertEquals(t, "Ted unmarshalled", actual[1].Name) -} - -// TestUnmarshalNamedStruct tests if the result is empty. -func TestUnmarshalNamedStructs(t *testing.T) { - var actual TestPersonWithExtensionsNamed - - var dejson interface{} - sejson := []byte(singleResponse) - err := json.Unmarshal(sejson, &dejson) - if err != nil { - t.Fatal(err) - } - - var singleResult = eclcloud.Result{ - Body: dejson, - } - - err = singleResult.ExtractIntoStructPtr(&actual, "person") - th.AssertNoErr(t, err) - - th.AssertEquals(t, "", actual.TestPerson.Name) - th.AssertEquals(t, "", actual.TestPersonExt.Location) -} - -// TestUnmarshalSliceofNamedStructs tests if the result is empty. -func TestUnmarshalSliceOfNamedStructs(t *testing.T) { - var actual []TestPersonWithExtensionsNamed - - var dejson interface{} - sejson := []byte(multiResponse) - err := json.Unmarshal(sejson, &dejson) - if err != nil { - t.Fatal(err) - } - - var multiResult = eclcloud.Result{ - Body: dejson, - } - - err = multiResult.ExtractIntoSlicePtr(&actual, "people") - th.AssertNoErr(t, err) - - th.AssertEquals(t, "", actual[0].TestPerson.Name) - th.AssertEquals(t, "", actual[0].TestPersonExt.Location) - th.AssertEquals(t, "", actual[1].TestPerson.Name) - th.AssertEquals(t, "", actual[1].TestPersonExt.Location) -} diff --git a/v3/testing/service_client_test.go b/v3/testing/service_client_test.go deleted file mode 100644 index b98f399..0000000 --- a/v3/testing/service_client_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package testing - -import ( - "fmt" - "net/http" - "testing" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestServiceURL(t *testing.T) { - c := &eclcloud.ServiceClient{Endpoint: "http://123.45.67.8/"} - expected := "http://123.45.67.8/more/parts/here" - actual := c.ServiceURL("more", "parts", "here") - th.CheckEquals(t, expected, actual) -} - -func TestMoreHeaders(t *testing.T) { - th.SetupHTTP() - defer th.TeardownHTTP() - th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - }) - - c := new(eclcloud.ServiceClient) - c.MoreHeaders = map[string]string{ - "custom": "header", - } - c.ProviderClient = new(eclcloud.ProviderClient) - resp, err := c.Get(fmt.Sprintf("%s/route", th.Endpoint()), nil, nil) - th.AssertNoErr(t, err) - th.AssertEquals(t, resp.Request.Header.Get("custom"), "header") -} diff --git a/v3/testing/util_test.go b/v3/testing/util_test.go deleted file mode 100644 index dfd08a7..0000000 --- a/v3/testing/util_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package testing - -import ( - "errors" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/nttcom/eclcloud/v3" - th "github.com/nttcom/eclcloud/v3/testhelper" -) - -func TestWaitFor(t *testing.T) { - err := eclcloud.WaitFor(2, func() (bool, error) { - return true, nil - }) - th.CheckNoErr(t, err) -} - -func TestWaitForTimeout(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - - err := eclcloud.WaitFor(1, func() (bool, error) { - return false, nil - }) - th.AssertEquals(t, "A timeout occurred", err.Error()) -} - -func TestWaitForError(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - - err := eclcloud.WaitFor(2, func() (bool, error) { - return false, errors.New("error has occurred") - }) - th.AssertEquals(t, "error has occurred", err.Error()) -} - -func TestWaitForPredicateExceed(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - - err := eclcloud.WaitFor(1, func() (bool, error) { - time.Sleep(4 * time.Second) - return false, errors.New("just wasting time") - }) - th.AssertEquals(t, "A timeout occurred", err.Error()) -} - -func TestNormalizeURL(t *testing.T) { - urls := []string{ - "NoSlashAtEnd", - "SlashAtEnd/", - } - expected := []string{ - "NoSlashAtEnd/", - "SlashAtEnd/", - } - for i := 0; i < len(expected); i++ { - th.CheckEquals(t, expected[i], eclcloud.NormalizeURL(urls[i])) - } - -} - -func TestNormalizePathURL(t *testing.T) { - baseDir := "/test/path" - - rawPath := "template.yaml" - basePath := "/test/path" - result, _ := eclcloud.NormalizePathURL(basePath, rawPath) - expected := strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "template.yaml"}, "/") - th.CheckEquals(t, expected, result) - - rawPath = "http://www.google.com" - basePath = "/test/path" - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = "http://www.google.com" - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml" - basePath = "/test/path" - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "very/nested/file.yaml"}, "/") - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml" - basePath = "http://www.google.com" - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = "http://www.google.com/very/nested/file.yaml" - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml/" - basePath = "http://www.google.com/" - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = "http://www.google.com/very/nested/file.yaml" - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml" - basePath = "http://www.google.com/even/more" - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = "http://www.google.com/even/more/very/nested/file.yaml" - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml" - basePath = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more"}, "/") - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more/very/nested/file.yaml"}, "/") - th.CheckEquals(t, expected, result) - - rawPath = "very/nested/file.yaml/" - basePath = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more"}, "/") - result, _ = eclcloud.NormalizePathURL(basePath, rawPath) - expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more/very/nested/file.yaml"}, "/") - th.CheckEquals(t, expected, result) - -} diff --git a/v3/util.go b/v3/util.go deleted file mode 100644 index 5726475..0000000 --- a/v3/util.go +++ /dev/null @@ -1,99 +0,0 @@ -package eclcloud - -import ( - "fmt" - "net/url" - "path/filepath" - "strings" - "time" -) - -// WaitFor polls a predicate function, once per second, up to a timeout limit. -// This is useful to wait for a resource to transition to a certain state. -// To handle situations when the predicate might hang indefinitely, the -// predicate will be prematurely cancelled after the timeout. -// Resource packages will wrap this in a more convenient function that's -// specific to a certain resource, but it can also be useful on its own. -func WaitFor(timeout int, predicate func() (bool, error)) error { - type WaitForResult struct { - Success bool - Error error - } - - start := time.Now().Unix() - - for { - // If a timeout is set, and that's been exceeded, shut it down. - if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) { - return fmt.Errorf("A timeout occurred") - } - - time.Sleep(1 * time.Second) - - var result WaitForResult - ch := make(chan bool, 1) - go func() { - defer close(ch) - satisfied, err := predicate() - result.Success = satisfied - result.Error = err - }() - - select { - case <-ch: - if result.Error != nil { - return result.Error - } - if result.Success { - return nil - } - // If the predicate has not finished by the timeout, cancel it. - case <-time.After(time.Duration(timeout) * time.Second): - return fmt.Errorf("A timeout occurred") - } - } -} - -// NormalizeURL is an internal function to be used by provider clients. -// -// It ensures that each endpoint URL has a closing `/`, as expected by -// ServiceClient's methods. -func NormalizeURL(url string) string { - if !strings.HasSuffix(url, "/") { - return url + "/" - } - return url -} - -// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as -// a reference in the filesystem, if necessary. basePath is assumed to contain -// either '.' when first used, or the file:// type fqdn of the parent resource. -// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml -func NormalizePathURL(basePath, rawPath string) (string, error) { - u, err := url.Parse(rawPath) - if err != nil { - return "", err - } - // if a scheme is defined, it must be a fqdn already - if u.Scheme != "" { - return u.String(), nil - } - // if basePath is a url, then child resources are assumed to be relative to it - bu, err := url.Parse(basePath) - if err != nil { - return "", err - } - var basePathSys, absPathSys string - if bu.Scheme != "" { - basePathSys = filepath.FromSlash(bu.Path) - absPathSys = filepath.Join(basePathSys, rawPath) - bu.Path = filepath.ToSlash(absPathSys) - return bu.String(), nil - } - - absPathSys = filepath.Join(basePath, rawPath) - u.Path = filepath.ToSlash(absPathSys) - u.Scheme = "file" - return u.String(), nil - -}