diff --git a/instances.go b/instances.go index a68ec55d8..7d6c7566e 100644 --- a/instances.go +++ b/instances.go @@ -174,6 +174,7 @@ type InstanceCloneOptions struct { BackupsEnabled bool `json:"backups_enabled"` Disks []int `json:"disks,omitempty"` Configs []int `json:"configs,omitempty"` + PrivateIP bool `json:"private_ip,omitempty"` } // InstanceResizeOptions is an options struct used when resizing an instance diff --git a/test/integration/fixtures/TestInstance_Clone.yaml b/test/integration/fixtures/TestInstance_Clone.yaml new file mode 100644 index 000000000..cd384aa53 --- /dev/null +++ b/test/integration/fixtures/TestInstance_Clone.yaml @@ -0,0 +1,931 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/regions + method: GET + response: + body: '{"data": [{"id": "ap-west", "country": "in", "capabilities": ["Linodes", + "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "172.105.34.5,172.105.35.5,172.105.36.5,172.105.37.5,172.105.38.5,172.105.39.5,172.105.40.5,172.105.41.5,172.105.42.5,172.105.43.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "ca-central", "country": "ca", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5,172.105.3.5,172.105.4.5,172.105.5.5,172.105.6.5,172.105.7.5,172.105.8.5,172.105.9.5,172.105.10.5,172.105.11.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "ap-southeast", "country": "au", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5,172.105.169.5,172.105.168.5,172.105.172.5,172.105.162.5,172.105.170.5,172.105.167.5,172.105.171.5,172.105.181.5,172.105.161.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "us-central", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5,72.14.188.5,173.255.199.5,66.228.53.5,96.126.122.5,96.126.124.5,96.126.127.5,198.58.107.5,198.58.111.5,23.239.24.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "us-west", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5,173.230.147.5,173.230.155.5,173.255.212.5,173.255.219.5,173.255.241.5,173.255.243.5,173.255.244.5,74.207.241.5,74.207.242.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "us-southeast", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "us-east", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Bare Metal", "Block Storage Migrations", "Managed Databases"], "status": "ok", + "resolvers": {"ipv4": "66.228.42.5,96.126.106.5,50.116.53.5,50.116.58.5,50.116.61.5,50.116.62.5,66.175.211.5,97.107.133.4,207.192.69.4,207.192.69.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "eu-west", "country": "uk", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5,176.58.107.5,176.58.116.5,176.58.121.5,151.236.220.5,212.71.252.5,212.71.253.5,109.74.192.20,109.74.193.20,109.74.194.20", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "ap-south", "country": "sg", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "eu-central", "country": "de", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}, + {"id": "ap-northeast", "country": "jp", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5", + "ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"}}], + "page": 1, "pages": 1, "results": 11}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=900 + - private, max-age=60, s-maxage=60 + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - '*' + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"ap-west","type":"g6-nanode-1","label":"go-test-ins-bzi7l8090x1m","root_pass":"R34lBAdP455","image":"linode/debian9","booted":false}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances + method: POST + response: + body: '{"id": 41855753, "label": "go-test-ins-bzi7l8090x1m", "group": "", "status": + "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "type": "g6-nanode-1", "ipv4": ["45.79.117.66"], "ipv6": "1234::5678/128", + "image": "linode/debian9", "region": "ap-west", "specs": {"disk": 25600, "memory": + 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": 90, "network_in": + 10, "network_out": 10, "transfer_quota": 80, "io": 10000}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "a93eefd741bb8d5276687ca6a9bacb15b3c0657d"}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=60, s-maxage=60 + Content-Length: + - "716" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "10" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_create","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode"}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630111, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 69, "time_remaining": null, "rate": null, + "duration": 15.113282, "action": "linode_create", "username": "zliang27", "entity": + {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", "url": + "/v4/linode/instances/41855753"}, "status": "started", "secondary_entity": {"id": + "linode/debian9", "type": "image", "label": "Debian 9", "url": "/v4/images/linode/debian9"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "545" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_create","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630111}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630111, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": + 15.0, "action": "linode_create", "username": "zliang27", "entity": {"label": + "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", "url": "/v4/linode/instances/41855753"}, + "status": "finished", "secondary_entity": {"id": "linode/debian9", "type": "image", + "label": "Debian 9", "url": "/v4/images/linode/debian9"}, "message": ""}], "page": + 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "539" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"region":"ap-west","type":"g6-nanode-1","backups_enabled":false,"private_ip":true}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/41855753/clone + method: POST + response: + body: '{"id": 41855764, "label": "linode41855764", "group": "", "status": "offline", + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "type": + "g6-nanode-1", "ipv4": ["45.79.117.205", "192.168.137.107"], "ipv6": "1234::5678/128", + "image": "linode/debian9", "region": "ap-west", "specs": {"disk": 25600, "memory": + 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": 90, "network_in": + 10, "network_out": 10, "transfer_quota": 80, "io": 10000}, "backups": {"enabled": + false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": + null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": + "26f6fdb8e6729aef2574dc39ca9330636bbe5724"}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=60, s-maxage=60 + Content-Length: + - "721" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode"}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 0, "time_remaining": null, "rate": null, + "duration": null, "action": "linode_clone", "username": "zliang27", "entity": + {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", "url": + "/v4/linode/instances/41855753"}, "status": "scheduled", "secondary_entity": + {"id": 41855764, "type": "linode", "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "543" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630279}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 35, "time_remaining": "0:2:51", "rate": "148.00 + MB/s", "duration": 30.556942, "action": "linode_clone", "username": "zliang27", + "entity": {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", + "url": "/v4/linode/instances/41855753"}, "status": "started", "secondary_entity": + {"id": 41855764, "type": "linode", "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "560" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630279}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 35, "time_remaining": "0:2:51", "rate": "148.00 + MB/s", "duration": 45.643679, "action": "linode_clone", "username": "zliang27", + "entity": {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", + "url": "/v4/linode/instances/41855753"}, "status": "started", "secondary_entity": + {"id": 41855764, "type": "linode", "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "560" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630279}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 58, "time_remaining": "0:0:13", "rate": "528.00 + MB/s", "duration": 60.619827, "action": "linode_clone", "username": "zliang27", + "entity": {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", + "url": "/v4/linode/instances/41855753"}, "status": "started", "secondary_entity": + {"id": 41855764, "type": "linode", "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "560" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630279}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 58, "time_remaining": "0:0:13", "rate": "528.00 + MB/s", "duration": 75.587197, "action": "linode_clone", "username": "zliang27", + "entity": {"label": "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", + "url": "/v4/linode/instances/41855753"}, "status": "started", "secondary_entity": + {"id": 41855764, "type": "linode", "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, + "message": ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "560" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + X-Filter: + - '{"+order":"desc","+order_by":"created","action":"linode_clone","created":{"+gte":"2018-01-02T03:04:05"},"entity.id":41855753,"entity.type":"linode","id":{"+gte":417630279}}' + url: https://api.linode.com/v4beta/account/events?page=1 + method: GET + response: + body: '{"data": [{"id": 417630279, "created": "2018-01-02T03:04:05", "seen": false, + "read": false, "percent_complete": 100, "time_remaining": 0, "rate": null, "duration": + 85.0, "action": "linode_clone", "username": "zliang27", "entity": {"label": + "go-test-ins-bzi7l8090x1m", "id": 41855753, "type": "linode", "url": "/v4/linode/instances/41855753"}, + "status": "finished", "secondary_entity": {"id": 41855764, "type": "linode", + "label": "linode41855764", "url": "/v4/linode/instances/41855764"}, "message": + ""}], "page": 1, "pages": 1, "results": 1}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "541" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - events:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/41855764/ips + method: GET + response: + body: '{"ipv4": {"public": [{"address": "45.79.117.205", "gateway": "45.79.117.1", + "subnet_mask": "255.255.255.0", "prefix": 24, "type": "ipv4", "public": true, + "rdns": "45-79-117-205.ip.linodeusercontent.com", "linode_id": 41855764, "region": + "ap-west"}], "private": [{"address": "192.168.137.107", "gateway": null, "subnet_mask": + "255.255.128.0", "prefix": 17, "type": "ipv4", "public": false, "rdns": null, + "linode_id": 41855764, "region": "ap-west"}], "shared": [], "reserved": []}, + "ipv6": {"slaac": {"address": "1234::5678", "gateway": "1234::5678", + "subnet_mask": "1234::5678", "prefix": 64, "type": "ipv6", "rdns": + null, "linode_id": 41855764, "region": "ap-west", "public": true}, "link_local": + {"address": "1234::5678", "gateway": "1234::5678", "subnet_mask": + "1234::5678", "prefix": 64, "type": "ipv6", "rdns": null, "linode_id": + 41855764, "region": "ap-west", "public": false}, "global": []}}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=0, s-maxage=0, no-cache, no-store + - private, max-age=60, s-maxage=60 + Content-Length: + - "948" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_only + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/41855764 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=60, s-maxage=60 + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/linode/instances/41855753 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Cache-Control: + - private, max-age=60, s-maxage=60 + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - linodes:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "800" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 5b791dab4..18ed93843 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -375,6 +375,74 @@ func TestInstance_Rebuild(t *testing.T) { } } +func TestInstance_Clone(t *testing.T) { + client, instance, teardownOriginalLinode, err := setupInstance(t, "fixtures/TestInstance_Clone") + defer teardownOriginalLinode() + + if err != nil { + t.Error(err) + } + + _, err = client.WaitForEventFinished( + context.Background(), + instance.ID, + linodego.EntityLinode, + linodego.ActionLinodeCreate, + *instance.Created, + 180, + ) + + if err != nil { + t.Errorf("Error waiting for instance created: %s", err) + } + + cloneOpts := linodego.InstanceCloneOptions{ + Region: "ap-west", + Type: "g6-nanode-1", + PrivateIP: true, + } + clonedInstance, err := client.CloneInstance(context.Background(), instance.ID, cloneOpts) + + teardownClonedLinode := func() { + client.DeleteInstance(context.Background(), clonedInstance.ID) + } + defer teardownClonedLinode() + + if err != nil { + t.Error(err) + } + + _, err = client.WaitForEventFinished( + context.Background(), + instance.ID, + linodego.EntityLinode, + linodego.ActionLinodeClone, + *clonedInstance.Created, + 240, + ) + + if err != nil { + t.Error(err) + } + + if clonedInstance.Image != instance.Image { + t.Error("Clone instance image mismatched.") + } + + clonedInstanceIPs, err := client.GetInstanceIPAddresses( + context.Background(), + clonedInstance.ID, + ) + + if err != nil { + t.Error(err) + } + + if len(clonedInstanceIPs.IPv4.Private) == 0 { + t.Error("No private IPv4 assigned to the cloned instance.") + } +} + func createInstance(t *testing.T, client *linodego.Client, modifiers ...instanceModifier) (*linodego.Instance, error) { if t != nil { t.Helper()