From 8921e10d71edb15bae55149dde3cac4989c321fd Mon Sep 17 00:00:00 2001 From: danielcbright Date: Sat, 20 Jun 2015 18:25:21 +0200 Subject: [PATCH] Added softlayer virtual guest and ssh keys functionality: Here is an example that will setup the following: + An SSH key resource. + A virtual server resource that uses an existing SSH key. + A virtual server resource using an existing SSH key and a Terraform managed SSH key (created as "test_key_1" in the example below). (create this as sl.tf and run terraform commands from this directory): ```hcl provider "softlayer" { username = "" api_key = "" } resource "softlayer_ssh_key" "test_key_1" { name = "test_key_1" public_key = "${file(\"~/.ssh/id_rsa_test_key_1.pub\")}" # Windows Example: # public_key = "${file(\"C:\ssh\keys\path\id_rsa_test_key_1.pub\")}" } resource "softlayer_virtual_guest" "my_server_1" { name = "my_server_1" domain = "example.com" ssh_keys = ["123456"] image = "DEBIAN_7_64" region = "ams01" public_network_speed = 10 cpu = 1 ram = 1024 } resource "softlayer_virtual_guest" "my_server_2" { name = "my_server_2" domain = "example.com" ssh_keys = ["123456", "${softlayer_ssh_key.test_key_1.id}"] image = "CENTOS_6_64" region = "ams01" public_network_speed = 10 cpu = 1 ram = 1024 } ``` You'll need to provide your SoftLayer username and API key, so that Terraform can connect. If you don't want to put credentials in your configuration file, you can leave them out: ``` provider "softlayer" {} ``` ...and instead set these environment variables: - **SOFTLAYER_USERNAME**: Your SoftLayer username - **SOFTLAYER_API_KEY**: Your API key --- builtin/bins/provider-softlayer/main.go | 12 + builtin/bins/provider-softlayer/main_test.go | 1 + builtin/providers/softlayer/config.go | 39 + builtin/providers/softlayer/provider.go | 41 + builtin/providers/softlayer/provider_test.go | 38 + .../softlayer/resource_softlayer_ssh_key.go | 159 +++ .../resource_softlayer_ssh_key_test.go | 131 +++ .../resource_softlayer_virtual_guest.go | 545 ++++++++++ .../resource_softlayer_virtual_guest_test.go | 299 ++++++ .../client/fakes/softlayer_client_fake.go | 302 ++++++ .../softlayer-go/client/softlayer_client.go | 350 +++++++ .../client/softlayer_client_suite_test.go | 13 + .../client/softlayer_client_test.go | 173 +++ .../softlayer-go/common/common_suite_test.go | 13 + .../maximilien/softlayer-go/common/utility.go | 16 + .../softlayer-go/common/utility_test.go | 29 + .../softLayer_network_storage_credential.go | 14 + .../data_types/softLayer_tag_reference.go | 24 + .../softLayer_virtual_guest_attribute.go | 12 + ...k_device_template_group_init_parameters.go | 17 + ...uest_block_device_template_group_status.go | 7 + .../data_types/softlayer_account_status.go | 6 + ...layer_billing_item_cancellation_request.go | 18 + ...r_container_disk_image_capture_template.go | 17 + .../softlayer_container_product_order.go | 60 ++ ...est_block_device_template_configuration.go | 12 + .../data_types/softlayer_dns_domain.go | 20 + .../data_types/softlayer_dns_domain_record.go | 49 + .../data_types/softlayer_hardware.go | 33 + .../data_types/softlayer_image_type.go | 7 + .../data_types/softlayer_location.go | 7 + .../data_types/softlayer_network_storage.go | 37 + .../softlayer_network_storage_allowed_host.go | 9 + ...softlayer_network_storage_iscsi_os_type.go | 12 + .../data_types/softlayer_network_vlan.go | 16 + .../softlayer_product_item_price.go | 19 + .../data_types/softlayer_product_package.go | 20 + ...layer_provisioning_version1_transaction.go | 29 + .../data_types/softlayer_security_ssh_key.go | 19 + .../data_types/softlayer_set_user_metadata.go | 8 + .../softlayer_software_component_password.go | 24 + .../softlayer_virtual_disk_image.go | 20 + .../data_types/softlayer_virtual_guest.go | 150 +++ ...rtual_guest_block_device_template_group.go | 18 + ...softlayer_virtual_guest_init_parameters.go | 9 + .../softlayer_virtual_guest_power_state.go | 7 + .../maximilien/softlayer-go/main/slgo.go | 9 + .../services/services_suite_test.go | 13 + .../services/softLayer_account.go | 291 ++++++ ...rtual_guest_block_device_template_group.go | 317 ++++++ ..._guest_block_device_template_group_test.go | 386 +++++++ .../services/softlayer_account_test.go | 213 ++++ ...layer_billing_item_cancellation_request.go | 50 + ..._billing_item_cancellation_request_test.go | 64 ++ .../services/softlayer_dns_domain.go | 96 ++ .../softlayer_dns_domain_resource_record.go | 141 +++ ...ftlayer_dns_domain_resource_record_test.go | 144 +++ .../services/softlayer_dns_domain_test.go | 63 ++ .../services/softlayer_hardware.go | 89 ++ .../services/softlayer_hardware_test.go | 92 ++ .../services/softlayer_network_storage.go | 324 ++++++ .../softlayer_network_storage_allowed_host.go | 40 + ...layer_network_storage_allowed_host_test.go | 60 ++ .../softlayer_network_storage_test.go | 159 +++ .../services/softlayer_product_order.go | 102 ++ .../services/softlayer_product_order_test.go | 88 ++ .../services/softlayer_product_package.go | 153 +++ .../softlayer_product_package_test.go | 161 +++ .../services/softlayer_security_ssh_key.go | 127 +++ .../softlayer_security_ssh_key_test.go | 158 +++ .../services/softlayer_virtual_disk_image.go | 39 + .../softlayer_virtual_disk_image_test.go | 73 ++ .../services/softlayer_virtual_guest.go | 948 +++++++++++++++++ .../services/softlayer_virtual_guest_test.go | 982 ++++++++++++++++++ .../softlayer-go/softlayer/client.go | 32 + .../softlayer-go/softlayer/service.go | 5 + .../softlayer/softlayer_account_service.go | 22 + ...lling_item_cancellation_request_service.go | 11 + ...ayer_dns_domain_resource_record_service.go | 14 + .../softlayer/softlayer_dns_domain_service.go | 15 + .../softlayer/softlayer_hardware_service.go | 12 + ...er_network_storage_allowed_host_service.go | 11 + .../softlayer_network_storage_service.go | 18 + .../softlayer_product_order_service.go | 13 + .../softlayer_product_package_service.go | 17 + .../softlayer_security_ssh_key_service.go | 16 + .../softlayer_virtual_disk_image_service.go | 11 + ...rtual_guest_block_device_template_group.go | 35 + .../softlayer_virtual_guest_service.go | 64 ++ website/source/assets/stylesheets/_docs.scss | 1 + .../providers/softlayer/index.html.markdown | 84 ++ .../softlayer/r/ssh_key.html.markdown | 39 + .../softlayer/r/virtual_guest.html.markdown | 134 +++ website/source/layouts/docs.erb | 4 + website/source/layouts/softlayer.erb | 29 + 95 files changed, 8830 insertions(+) create mode 100644 builtin/bins/provider-softlayer/main.go create mode 100644 builtin/bins/provider-softlayer/main_test.go create mode 100644 builtin/providers/softlayer/config.go create mode 100644 builtin/providers/softlayer/provider.go create mode 100644 builtin/providers/softlayer/provider_test.go create mode 100644 builtin/providers/softlayer/resource_softlayer_ssh_key.go create mode 100644 builtin/providers/softlayer/resource_softlayer_ssh_key_test.go create mode 100644 builtin/providers/softlayer/resource_softlayer_virtual_guest.go create mode 100644 builtin/providers/softlayer/resource_softlayer_virtual_guest_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/client/fakes/softlayer_client_fake.go create mode 100644 vendor/github.com/maximilien/softlayer-go/client/softlayer_client.go create mode 100644 vendor/github.com/maximilien/softlayer-go/client/softlayer_client_suite_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/client/softlayer_client_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/common/common_suite_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/common/utility.go create mode 100644 vendor/github.com/maximilien/softlayer-go/common/utility_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softLayer_network_storage_credential.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softLayer_tag_reference.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_attribute.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_init_parameters.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_status.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_account_status.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_billing_item_cancellation_request.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_disk_image_capture_template.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_product_order.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_virtual_guest_block_device_template_configuration.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain_record.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_hardware.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_image_type.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_location.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_allowed_host.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_iscsi_os_type.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_vlan.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_item_price.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_package.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_provisioning_version1_transaction.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_security_ssh_key.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_set_user_metadata.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_software_component_password.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_disk_image.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_block_device_template_group.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_init_parameters.go create mode 100644 vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_power_state.go create mode 100644 vendor/github.com/maximilien/softlayer-go/main/slgo.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/services_suite_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softLayer_account.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_account_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest.go create mode 100644 vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest_test.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/client.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_account_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_billing_item_cancellation_request_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_resource_record_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_hardware_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_allowed_host_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_order_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_package_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_security_ssh_key_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_disk_image_service.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_block_device_template_group.go create mode 100644 vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_service.go create mode 100644 website/source/docs/providers/softlayer/index.html.markdown create mode 100644 website/source/docs/providers/softlayer/r/ssh_key.html.markdown create mode 100644 website/source/docs/providers/softlayer/r/virtual_guest.html.markdown create mode 100644 website/source/layouts/softlayer.erb diff --git a/builtin/bins/provider-softlayer/main.go b/builtin/bins/provider-softlayer/main.go new file mode 100644 index 000000000..c3fdb4bcb --- /dev/null +++ b/builtin/bins/provider-softlayer/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/softlayer" + "github.com/hashicorp/terraform/plugin" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: softlayer.Provider, + }) +} diff --git a/builtin/bins/provider-softlayer/main_test.go b/builtin/bins/provider-softlayer/main_test.go new file mode 100644 index 000000000..06ab7d0f9 --- /dev/null +++ b/builtin/bins/provider-softlayer/main_test.go @@ -0,0 +1 @@ +package main diff --git a/builtin/providers/softlayer/config.go b/builtin/providers/softlayer/config.go new file mode 100644 index 000000000..8fb9d77ba --- /dev/null +++ b/builtin/providers/softlayer/config.go @@ -0,0 +1,39 @@ +package softlayer + +import ( + "log" + + slclient "github.com/maximilien/softlayer-go/client" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type Config struct { + Username string + ApiKey string +} + +type Client struct { + virtualGuestService softlayer.SoftLayer_Virtual_Guest_Service + sshKeyService softlayer.SoftLayer_Security_Ssh_Key_Service + productOrderService softlayer.SoftLayer_Product_Order_Service +} + +func (c *Config) Client() (*Client, error) { + slc := slclient.NewSoftLayerClient(c.Username, c.ApiKey) + virtualGuestService, err := slc.GetSoftLayer_Virtual_Guest_Service() + + if err != nil { + return nil, err + } + + sshKeyService, err := slc.GetSoftLayer_Security_Ssh_Key_Service() + + client := &Client{ + virtualGuestService: virtualGuestService, + sshKeyService: sshKeyService, + } + + log.Println("[INFO] Created SoftLayer client") + + return client, nil +} diff --git a/builtin/providers/softlayer/provider.go b/builtin/providers/softlayer/provider.go new file mode 100644 index 000000000..ceb62425c --- /dev/null +++ b/builtin/providers/softlayer/provider.go @@ -0,0 +1,41 @@ +package softlayer + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "username": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("SOFTLAYER_USERNAME", nil), + Description: "The user name for SoftLayer API operations.", + }, + "api_key": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("SOFTLAYER_API_KEY", nil), + Description: "The API key for SoftLayer API operations.", + }, + }, + + ResourcesMap: map[string]*schema.Resource{ + "softlayer_virtual_guest": resourceSoftLayerVirtualGuest(), + "softlayer_ssh_key": resourceSoftLayerSSHKey(), + }, + + ConfigureFunc: providerConfigure, + } +} + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + config := Config{ + Username: d.Get("username").(string), + ApiKey: d.Get("api_key").(string), + } + + return config.Client() +} diff --git a/builtin/providers/softlayer/provider_test.go b/builtin/providers/softlayer/provider_test.go new file mode 100644 index 000000000..585365193 --- /dev/null +++ b/builtin/providers/softlayer/provider_test.go @@ -0,0 +1,38 @@ +package softlayer + +import ( + "os" + "testing" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +var testAccProviders map[string]terraform.ResourceProvider +var testAccProvider *schema.Provider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "softlayer": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func TestProvider_impl(t *testing.T) { + var _ terraform.ResourceProvider = Provider() +} + +func testAccPreCheck(t *testing.T) { + if v := os.Getenv("SOFTLAYER_USERNAME"); v == "" { + t.Fatal("SOFTLAYER_USERNAME must be set for acceptance tests") + } + if v := os.Getenv("SOFTLAYER_API_KEY"); v == "" { + t.Fatal("SOFTLAYER_API_KEY must be set for acceptance tests") + } +} diff --git a/builtin/providers/softlayer/resource_softlayer_ssh_key.go b/builtin/providers/softlayer/resource_softlayer_ssh_key.go new file mode 100644 index 000000000..d03fb7f3b --- /dev/null +++ b/builtin/providers/softlayer/resource_softlayer_ssh_key.go @@ -0,0 +1,159 @@ +package softlayer + +import ( + "fmt" + "log" + "strconv" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +func resourceSoftLayerSSHKey() *schema.Resource { + return &schema.Resource{ + Create: resourceSoftLayerSSHKeyCreate, + Read: resourceSoftLayerSSHKeyRead, + Update: resourceSoftLayerSSHKeyUpdate, + Delete: resourceSoftLayerSSHKeyDelete, + Exists: resourceSoftLayerSSHKeyExists, + + Schema: map[string]*schema.Schema{ + "id": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "public_key": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "fingerprint": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "notes": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: nil, + }, + }, + } +} + +func resourceSoftLayerSSHKeyCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).sshKeyService + + // Build up our creation options + opts := datatypes.SoftLayer_Security_Ssh_Key{ + Label: d.Get("name").(string), + Key: d.Get("public_key").(string), + } + + if notes, ok := d.GetOk("notes"); ok { + opts.Notes = notes.(string) + } + + res, err := client.CreateObject(opts) + if err != nil { + return fmt.Errorf("Error creating SSH Key: %s", err) + } + + d.SetId(strconv.Itoa(res.Id)) + log.Printf("[INFO] SSH Key: %d", res.Id) + + return resourceSoftLayerSSHKeyRead(d, meta) +} + +func resourceSoftLayerSSHKeyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).sshKeyService + + keyId, _ := strconv.Atoi(d.Id()) + + key, err := client.GetObject(keyId) + if err != nil { + // If the key is somehow already destroyed, mark as + // succesfully gone + if strings.Contains(err.Error(), "404 Not Found") { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving SSH key: %s", err) + } + + d.Set("id", key.Id) + d.Set("name", key.Label) + d.Set("public_key", strings.TrimSpace(key.Key)) + d.Set("fingerprint", key.Fingerprint) + d.Set("notes", key.Notes) + + return nil +} + +func resourceSoftLayerSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).sshKeyService + + keyId, _ := strconv.Atoi(d.Id()) + + key, err := client.GetObject(keyId) + if err != nil { + return fmt.Errorf("Error retrieving SSH key: %s", err) + } + + if d.HasChange("name") { + key.Label = d.Get("name").(string) + } + + if d.HasChange("notes") { + key.Notes = d.Get("notes").(string) + } + + _, err = client.EditObject(keyId, key) + if err != nil { + return fmt.Errorf("Error editing SSH key: %s", err) + } + return nil +} + +func resourceSoftLayerSSHKeyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).sshKeyService + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error deleting SSH Key: %s", err) + } + + log.Printf("[INFO] Deleting SSH key: %d", id) + _, err = client.DeleteObject(id) + if err != nil { + return fmt.Errorf("Error deleting SSH key: %s", err) + } + + d.SetId("") + return nil +} + +func resourceSoftLayerSSHKeyExists(d *schema.ResourceData, meta interface{}) (bool, error) { + client := meta.(*Client).sshKeyService + + if client == nil { + return false, fmt.Errorf("The client was nil.") + } + + keyId, err := strconv.Atoi(d.Id()) + if err != nil { + return false, fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + + result, err := client.GetObject(keyId) + return result.Id == keyId && err == nil, nil +} diff --git a/builtin/providers/softlayer/resource_softlayer_ssh_key_test.go b/builtin/providers/softlayer/resource_softlayer_ssh_key_test.go new file mode 100644 index 000000000..70f7344fe --- /dev/null +++ b/builtin/providers/softlayer/resource_softlayer_ssh_key_test.go @@ -0,0 +1,131 @@ +package softlayer + +import ( + "fmt" + "strconv" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +func TestAccSoftLayerSSHKey_Basic(t *testing.T) { + var key datatypes.SoftLayer_Security_Ssh_Key + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSoftLayerSSHKeyDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckSoftLayerSSHKeyConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckSoftLayerSSHKeyExists("softlayer_ssh_key.testacc_foobar", &key), + testAccCheckSoftLayerSSHKeyAttributes(&key), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "name", "testacc_foobar"), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "public_key", testAccValidPublicKey), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "notes", "first_note"), + ), + }, + + resource.TestStep{ + Config: testAccCheckSoftLayerSSHKeyConfig_updated, + Check: resource.ComposeTestCheckFunc( + testAccCheckSoftLayerSSHKeyExists("softlayer_ssh_key.testacc_foobar", &key), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "name", "changed_name"), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "public_key", testAccValidPublicKey), + resource.TestCheckResourceAttr( + "softlayer_ssh_key.testacc_foobar", "notes", "changed_note"), + ), + }, + }, + }) +} + +func testAccCheckSoftLayerSSHKeyDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*Client).sshKeyService + + for _, rs := range s.RootModule().Resources { + if rs.Type != "softlayer_ssh_key" { + continue + } + + keyId, _ := strconv.Atoi(rs.Primary.ID) + + // Try to find the key + _, err := client.GetObject(keyId) + + if err == nil { + return fmt.Errorf("SSH key still exists") + } + } + + return nil +} + +func testAccCheckSoftLayerSSHKeyAttributes(key *datatypes.SoftLayer_Security_Ssh_Key) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if key.Label != "testacc_foobar" { + return fmt.Errorf("Bad name: %s", key.Label) + } + + return nil + } +} + +func testAccCheckSoftLayerSSHKeyExists(n string, key *datatypes.SoftLayer_Security_Ssh_Key) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + + keyId, _ := strconv.Atoi(rs.Primary.ID) + + client := testAccProvider.Meta().(*Client).sshKeyService + foundKey, err := client.GetObject(keyId) + + if err != nil { + return err + } + + if strconv.Itoa(int(foundKey.Id)) != rs.Primary.ID { + return fmt.Errorf("Record not found") + } + + *key = foundKey + + return nil + } +} + +var testAccCheckSoftLayerSSHKeyConfig_basic = fmt.Sprintf(` +resource "softlayer_ssh_key" "testacc_foobar" { + name = "testacc_foobar" + notes = "first_note" + public_key = "%s" +}`, testAccValidPublicKey) + +var testAccCheckSoftLayerSSHKeyConfig_updated = fmt.Sprintf(` +resource "softlayer_ssh_key" "testacc_foobar" { + name = "changed_name" + notes = "changed_note" + public_key = "%s" +}`, testAccValidPublicKey) + +var testAccValidPublicKey = strings.TrimSpace(` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR +`) diff --git a/builtin/providers/softlayer/resource_softlayer_virtual_guest.go b/builtin/providers/softlayer/resource_softlayer_virtual_guest.go new file mode 100644 index 000000000..54d4f9ba4 --- /dev/null +++ b/builtin/providers/softlayer/resource_softlayer_virtual_guest.go @@ -0,0 +1,545 @@ +package softlayer + +import ( + "fmt" + "log" + "strconv" + "time" + + "encoding/base64" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + datatypes "github.com/maximilien/softlayer-go/data_types" + "github.com/maximilien/softlayer-go/softlayer" + "math" + "strings" +) + +func resourceSoftLayerVirtualGuest() *schema.Resource { + return &schema.Resource{ + Create: resourceSoftLayerVirtualGuestCreate, + Read: resourceSoftLayerVirtualGuestRead, + Update: resourceSoftLayerVirtualGuestUpdate, + Delete: resourceSoftLayerVirtualGuestDelete, + Exists: resourceSoftLayerVirtualGuestExists, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "domain": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "image": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "hourly_billing": &schema.Schema{ + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + + "private_network_only": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + ForceNew: true, + }, + + "region": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "cpu": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + // TODO: This fields for now requires recreation, because currently for some reason SoftLayer resets "dedicated_acct_host_only" + // TODO: flag to false, while upgrading CPUs. That problem is reported to SoftLayer team. "ForceNew" can be set back + // TODO: to false as soon as it is fixed at their side. Also corresponding test for virtual guest upgrade will be uncommented. + ForceNew: true, + }, + + "ram": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + memoryInMB := float64(v.(int)) + + // Validate memory to match gigs format + remaining := math.Mod(memoryInMB, 1024) + if remaining > 0 { + suggested := math.Ceil(memoryInMB/1024) * 1024 + errors = append(errors, fmt.Errorf( + "Invalid 'ram' value %d megabytes, must be a multiple of 1024 (e.g. use %d)", int(memoryInMB), int(suggested))) + } + + return + }, + }, + + "dedicated_acct_host_only": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + }, + + "frontend_vlan_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "backend_vlan_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "disks": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + + "public_network_speed": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: 1000, + }, + + "ipv4_address": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "ipv4_address_private": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "ssh_keys": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + + "user_data": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "local_disk": &schema.Schema{ + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + + "post_install_script_uri": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: nil, + ForceNew: true, + }, + + "block_device_template_group_gid": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func getNameForBlockDevice(i int) string { + // skip 1, which is reserved for the swap disk. + // so we get 0, 2, 3, 4, 5 ... + if i == 0 { + return "0" + } else { + return strconv.Itoa(i + 1) + } +} + +func getBlockDevices(d *schema.ResourceData) []datatypes.BlockDevice { + numBlocks := d.Get("disks.#").(int) + if numBlocks == 0 { + return nil + } else { + blocks := make([]datatypes.BlockDevice, 0, numBlocks) + for i := 0; i < numBlocks; i++ { + blockRef := fmt.Sprintf("disks.%d", i) + name := getNameForBlockDevice(i) + capacity := d.Get(blockRef).(int) + block := datatypes.BlockDevice{ + Device: name, + DiskImage: datatypes.DiskImage{ + Capacity: capacity, + }, + } + blocks = append(blocks, block) + } + return blocks + } +} + +func resourceSoftLayerVirtualGuestCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).virtualGuestService + if client == nil { + return fmt.Errorf("The client was nil.") + } + + dc := datatypes.Datacenter{ + Name: d.Get("region").(string), + } + + networkComponent := datatypes.NetworkComponents{ + MaxSpeed: d.Get("public_network_speed").(int), + } + + privateNetworkOnly := d.Get("private_network_only").(bool) + opts := datatypes.SoftLayer_Virtual_Guest_Template{ + Hostname: d.Get("name").(string), + Domain: d.Get("domain").(string), + HourlyBillingFlag: d.Get("hourly_billing").(bool), + PrivateNetworkOnlyFlag: privateNetworkOnly, + Datacenter: dc, + StartCpus: d.Get("cpu").(int), + MaxMemory: d.Get("ram").(int), + NetworkComponents: []datatypes.NetworkComponents{networkComponent}, + BlockDevices: getBlockDevices(d), + LocalDiskFlag: d.Get("local_disk").(bool), + PostInstallScriptUri: d.Get("post_install_script_uri").(string), + } + + if dedicatedAcctHostOnly, ok := d.GetOk("dedicated_acct_host_only"); ok { + opts.DedicatedAccountHostOnlyFlag = dedicatedAcctHostOnly.(bool) + } + + if globalIdentifier, ok := d.GetOk("block_device_template_group_gid"); ok { + opts.BlockDeviceTemplateGroup = &datatypes.BlockDeviceTemplateGroup{ + GlobalIdentifier: globalIdentifier.(string), + } + } + + if operatingSystemReferenceCode, ok := d.GetOk("image"); ok { + opts.OperatingSystemReferenceCode = operatingSystemReferenceCode.(string) + } + + // Apply frontend VLAN if provided + if param, ok := d.GetOk("frontend_vlan_id"); ok { + frontendVlanId, err := strconv.Atoi(param.(string)) + if err != nil { + return fmt.Errorf("Not a valid frontend ID, must be an integer: %s", err) + } + opts.PrimaryNetworkComponent = &datatypes.PrimaryNetworkComponent{ + NetworkVlan: datatypes.NetworkVlan{Id: (frontendVlanId)}, + } + } + + // Apply backend VLAN if provided + if param, ok := d.GetOk("backend_vlan_id"); ok { + backendVlanId, err := strconv.Atoi(param.(string)) + if err != nil { + return fmt.Errorf("Not a valid backend ID, must be an integer: %s", err) + } + opts.PrimaryBackendNetworkComponent = &datatypes.PrimaryBackendNetworkComponent{ + NetworkVlan: datatypes.NetworkVlan{Id: (backendVlanId)}, + } + } + + if userData, ok := d.GetOk("user_data"); ok { + opts.UserData = []datatypes.UserData{ + datatypes.UserData{ + Value: userData.(string), + }, + } + } + + // Get configured ssh_keys + ssh_keys := d.Get("ssh_keys.#").(int) + if ssh_keys > 0 { + opts.SshKeys = make([]datatypes.SshKey, 0, ssh_keys) + for i := 0; i < ssh_keys; i++ { + key := fmt.Sprintf("ssh_keys.%d", i) + id := d.Get(key).(int) + sshKey := datatypes.SshKey{ + Id: id, + } + opts.SshKeys = append(opts.SshKeys, sshKey) + } + } + + log.Printf("[INFO] Creating virtual machine") + + guest, err := client.CreateObject(opts) + + if err != nil { + return fmt.Errorf("Error creating virtual guest: %s", err) + } + + d.SetId(fmt.Sprintf("%d", guest.Id)) + + log.Printf("[INFO] Virtual Machine ID: %s", d.Id()) + + // wait for machine availability + _, err = WaitForNoActiveTransactions(d, meta) + + if err != nil { + return fmt.Errorf( + "Error waiting for virtual machine (%s) to become ready: %s", d.Id(), err) + } + + if !privateNetworkOnly { + _, err = WaitForPublicIpAvailable(d, meta) + if err != nil { + return fmt.Errorf( + "Error waiting for virtual machine (%s) public ip to become ready: %s", d.Id(), err) + } + } + + return resourceSoftLayerVirtualGuestRead(d, meta) +} + +func resourceSoftLayerVirtualGuestRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).virtualGuestService + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + result, err := client.GetObject(id) + if err != nil { + return fmt.Errorf("Error retrieving virtual guest: %s", err) + } + + d.Set("name", result.Hostname) + d.Set("domain", result.Domain) + if result.Datacenter != nil { + d.Set("region", result.Datacenter.Name) + } + d.Set("public_network_speed", result.NetworkComponents[0].MaxSpeed) + d.Set("cpu", result.StartCpus) + d.Set("ram", result.MaxMemory) + d.Set("dedicated_acct_host_only", result.DedicatedAccountHostOnlyFlag) + d.Set("has_public_ip", result.PrimaryIpAddress != "") + d.Set("ipv4_address", result.PrimaryIpAddress) + d.Set("ipv4_address_private", result.PrimaryBackendIpAddress) + d.Set("private_network_only", result.PrivateNetworkOnlyFlag) + d.Set("hourly_billing", result.HourlyBillingFlag) + d.Set("local_disk", result.LocalDiskFlag) + d.Set("frontend_vlan_id", result.PrimaryNetworkComponent.NetworkVlan.Id) + d.Set("backend_vlan_id", result.PrimaryBackendNetworkComponent.NetworkVlan.Id) + + userData := result.UserData + if userData != nil && len(userData) > 0 { + data, err := base64.StdEncoding.DecodeString(userData[0].Value) + if err != nil { + log.Printf("Can't base64 decode user data %s. error: %s", userData, err) + d.Set("user_data", userData) + } else { + d.Set("user_data", string(data)) + } + } + + return nil +} + +func resourceSoftLayerVirtualGuestUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).virtualGuestService + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + result, err := client.GetObject(id) + if err != nil { + return fmt.Errorf("Error retrieving virtual guest: %s", err) + } + + // Update "name" and "domain" fields if present and changed + // Those are the only fields, which could be updated + if d.HasChange("name") || d.HasChange("domain") { + result.Hostname = d.Get("name").(string) + result.Domain = d.Get("domain").(string) + + _, err = client.EditObject(id, result) + + if err != nil { + return fmt.Errorf("Couldn't update virtual guest: %s", err) + } + } + + // Set user data if provided and not empty + if d.HasChange("user_data") { + client.SetMetadata(id, d.Get("user_data").(string)) + } + + // Upgrade "cpu", "ram" and "nic_speed" if provided and changed + upgradeOptions := softlayer.UpgradeOptions{} + if d.HasChange("cpu") { + upgradeOptions.Cpus = d.Get("cpu").(int) + } + if d.HasChange("ram") { + memoryInMB := float64(d.Get("ram").(int)) + + // Convert memory to GB, as softlayer only allows to upgrade RAM in Gigs + // Must be already validated at this step + upgradeOptions.MemoryInGB = int(memoryInMB / 1024) + } + if d.HasChange("public_network_speed") { + upgradeOptions.NicSpeed = d.Get("public_network_speed").(int) + } + + started, err := client.UpgradeObject(id, &upgradeOptions) + if err != nil { + return fmt.Errorf("Couldn't upgrade virtual guest: %s", err) + } + + if started { + // Wait for softlayer to start upgrading... + _, err = WaitForUpgradeTransactionsToAppear(d, meta) + + // Wait for upgrade transactions to finish + _, err = WaitForNoActiveTransactions(d, meta) + } + + return err +} + +func resourceSoftLayerVirtualGuestDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Client).virtualGuestService + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + + _, err = WaitForNoActiveTransactions(d, meta) + + if err != nil { + return fmt.Errorf("Error deleting virtual guest, couldn't wait for zero active transactions: %s", err) + } + + _, err = client.DeleteObject(id) + + if err != nil { + return fmt.Errorf("Error deleting virtual guest: %s", err) + } + + return nil +} + +func WaitForUpgradeTransactionsToAppear(d *schema.ResourceData, meta interface{}) (interface{}, error) { + + log.Printf("Waiting for server (%s) to have upgrade transactions", d.Id()) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return nil, fmt.Errorf("The instance ID %s must be numeric", d.Id()) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"pending_upgrade"}, + Target: []string{"upgrade_started"}, + Refresh: func() (interface{}, string, error) { + client := meta.(*Client).virtualGuestService + transactions, err := client.GetActiveTransactions(id) + if err != nil { + return nil, "", fmt.Errorf("Couldn't fetch active transactions: %s", err) + } + for _, transaction := range transactions { + if strings.Contains(transaction.TransactionStatus.Name, "UPGRADE") { + return transactions, "upgrade_started", nil + } + } + return transactions, "pending_upgrade", nil + }, + Timeout: 5 * time.Minute, + Delay: 5 * time.Second, + MinTimeout: 3 * time.Second, + } + + return stateConf.WaitForState() +} + +func WaitForPublicIpAvailable(d *schema.ResourceData, meta interface{}) (interface{}, error) { + log.Printf("Waiting for server (%s) to get a public IP", d.Id()) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"", "unavailable"}, + Target: []string{"available"}, + Refresh: func() (interface{}, string, error) { + fmt.Println("Refreshing server state...") + client := meta.(*Client).virtualGuestService + id, err := strconv.Atoi(d.Id()) + if err != nil { + return nil, "", fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + result, err := client.GetObject(id) + if err != nil { + return nil, "", fmt.Errorf("Error retrieving virtual guest: %s", err) + } + if result.PrimaryIpAddress == "" { + return result, "unavailable", nil + } else { + return result, "available", nil + } + }, + Timeout: 30 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + return stateConf.WaitForState() +} + +func WaitForNoActiveTransactions(d *schema.ResourceData, meta interface{}) (interface{}, error) { + log.Printf("Waiting for server (%s) to have zero active transactions", d.Id()) + id, err := strconv.Atoi(d.Id()) + if err != nil { + return nil, fmt.Errorf("The instance ID %s must be numeric", d.Id()) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"", "active"}, + Target: []string{"idle"}, + Refresh: func() (interface{}, string, error) { + client := meta.(*Client).virtualGuestService + transactions, err := client.GetActiveTransactions(id) + if err != nil { + return nil, "", fmt.Errorf("Couldn't get active transactions: %s", err) + } + if len(transactions) == 0 { + return transactions, "idle", nil + } else { + return transactions, "active", nil + } + }, + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + return stateConf.WaitForState() +} + +func resourceSoftLayerVirtualGuestExists(d *schema.ResourceData, meta interface{}) (bool, error) { + client := meta.(*Client).virtualGuestService + + if client == nil { + return false, fmt.Errorf("The client was nil.") + } + + guestId, err := strconv.Atoi(d.Id()) + if err != nil { + return false, fmt.Errorf("Not a valid ID, must be an integer: %s", err) + } + + result, err := client.GetObject(guestId) + return result.Id == guestId && err == nil, nil +} diff --git a/builtin/providers/softlayer/resource_softlayer_virtual_guest_test.go b/builtin/providers/softlayer/resource_softlayer_virtual_guest_test.go new file mode 100644 index 000000000..43c87e718 --- /dev/null +++ b/builtin/providers/softlayer/resource_softlayer_virtual_guest_test.go @@ -0,0 +1,299 @@ +package softlayer + +import ( + "fmt" + "strconv" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +func TestAccSoftLayerVirtualGuest_Basic(t *testing.T) { + var guest datatypes.SoftLayer_Virtual_Guest + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSoftLayerVirtualGuestDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckSoftLayerVirtualGuestConfig_basic, + Destroy: false, + Check: resource.ComposeTestCheckFunc( + testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-1", &guest), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "name", "terraform-test"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "domain", "bar.example.com"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "region", "ams01"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "public_network_speed", "10"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "hourly_billing", "true"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "private_network_only", "false"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "cpu", "1"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "ram", "1024"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "disks.0", "25"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "disks.1", "10"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "disks.2", "20"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "user_data", "{\"value\":\"newvalue\"}"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "local_disk", "false"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "dedicated_acct_host_only", "true"), + + // TODO: As agreed, will be enabled when VLAN support is implemented: https://github.com/TheWeatherCompany/softlayer-go/issues/3 + // resource.TestCheckResourceAttr( + // "softlayer_virtual_guest.terraform-acceptance-test-1", "frontend_vlan_id", "1085155"), + // resource.TestCheckResourceAttr( + // "softlayer_virtual_guest.terraform-acceptance-test-1", "backend_vlan_id", "1085157"), + ), + }, + + resource.TestStep{ + Config: testAccCheckSoftLayerVirtualGuestConfig_userDataUpdate, + Destroy: false, + Check: resource.ComposeTestCheckFunc( + testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-1", &guest), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "user_data", "updatedData"), + ), + }, + + resource.TestStep{ + Config: testAccCheckSoftLayerVirtualGuestConfig_upgradeMemoryNetworkSpeed, + Check: resource.ComposeTestCheckFunc( + testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-1", &guest), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "ram", "2048"), + resource.TestCheckResourceAttr( + "softlayer_virtual_guest.terraform-acceptance-test-1", "public_network_speed", "100"), + ), + }, + + // TODO: currently CPU upgrade test is disabled, due to unexpected behavior of field "dedicated_acct_host_only". + // TODO: For some reason it is reset by SoftLayer to "false". Daniel Bright reported corresponding issue to SoftLayer team. + // resource.TestStep{ + // Config: testAccCheckSoftLayerVirtualGuestConfig_vmUpgradeCPUs, + // Check: resource.ComposeTestCheckFunc( + // testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-1", &guest), + // resource.TestCheckResourceAttr( + // "softlayer_virtual_guest.terraform-acceptance-test-1", "cpu", "2"), + // ), + // }, + + }, + }) +} + +func TestAccSoftLayerVirtualGuest_BlockDeviceTemplateGroup(t *testing.T) { + var guest datatypes.SoftLayer_Virtual_Guest + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSoftLayerVirtualGuestDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckSoftLayerVirtualGuestConfig_blockDeviceTemplateGroup, + Check: resource.ComposeTestCheckFunc( + // block_device_template_group_gid value is hardcoded. If it's valid then virtual guest will be created well + testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-BDTGroup", &guest), + ), + }, + }, + }) +} + +func TestAccSoftLayerVirtualGuest_postInstallScriptUri(t *testing.T) { + var guest datatypes.SoftLayer_Virtual_Guest + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSoftLayerVirtualGuestDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckSoftLayerVirtualGuestConfig_postInstallScriptUri, + Check: resource.ComposeTestCheckFunc( + // block_device_template_group_gid value is hardcoded. If it's valid then virtual guest will be created well + testAccCheckSoftLayerVirtualGuestExists("softlayer_virtual_guest.terraform-acceptance-test-pISU", &guest), + ), + }, + }, + }) +} + +func testAccCheckSoftLayerVirtualGuestDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*Client).virtualGuestService + + for _, rs := range s.RootModule().Resources { + if rs.Type != "softlayer_virtual_guest" { + continue + } + + guestId, _ := strconv.Atoi(rs.Primary.ID) + + // Try to find the guest + _, err := client.GetObject(guestId) + + // Wait + + if err != nil && !strings.Contains(err.Error(), "404") { + return fmt.Errorf( + "Error waiting for virtual guest (%s) to be destroyed: %s", + rs.Primary.ID, err) + } + } + + return nil +} + +func testAccCheckSoftLayerVirtualGuestExists(n string, guest *datatypes.SoftLayer_Virtual_Guest) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No virtual guest ID is set") + } + + id, err := strconv.Atoi(rs.Primary.ID) + + if err != nil { + return err + } + + client := testAccProvider.Meta().(*Client).virtualGuestService + retrieveVirtGuest, err := client.GetObject(id) + + if err != nil { + return err + } + + fmt.Printf("The ID is %d", id) + + if retrieveVirtGuest.Id != id { + return fmt.Errorf("Virtual guest not found") + } + + *guest = retrieveVirtGuest + + return nil + } +} + +const testAccCheckSoftLayerVirtualGuestConfig_basic = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-1" { + name = "terraform-test" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 10 + hourly_billing = true + private_network_only = false + cpu = 1 + ram = 1024 + disks = [25, 10, 20] + user_data = "{\"value\":\"newvalue\"}" + dedicated_acct_host_only = true + local_disk = false +} +` + +const testAccCheckSoftLayerVirtualGuestConfig_userDataUpdate = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-1" { + name = "terraform-test" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 10 + hourly_billing = true + cpu = 1 + ram = 1024 + disks = [25, 10, 20] + user_data = "updatedData" + dedicated_acct_host_only = true + local_disk = false +} +` + +const testAccCheckSoftLayerVirtualGuestConfig_upgradeMemoryNetworkSpeed = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-1" { + name = "terraform-test" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 100 + hourly_billing = true + cpu = 1 + ram = 2048 + disks = [25, 10, 20] + user_data = "updatedData" + dedicated_acct_host_only = true + local_disk = false +} +` + +const testAccCheckSoftLayerVirtualGuestConfig_vmUpgradeCPUs = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-1" { + name = "terraform-test" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 100 + hourly_billing = true + cpu = 2 + ram = 2048 + disks = [25, 10, 20] + user_data = "updatedData" + dedicated_acct_host_only = true + local_disk = false +} +` + +const testAccCheckSoftLayerVirtualGuestConfig_postInstallScriptUri = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-pISU" { + name = "terraform-test-pISU" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 10 + hourly_billing = true + private_network_only = false + cpu = 1 + ram = 1024 + disks = [25, 10, 20] + user_data = "{\"value\":\"newvalue\"}" + dedicated_acct_host_only = true + local_disk = false + post_install_script_uri = "https://www.google.com" +} +` + +const testAccCheckSoftLayerVirtualGuestConfig_blockDeviceTemplateGroup = ` +resource "softlayer_virtual_guest" "terraform-acceptance-test-BDTGroup" { + name = "terraform-test-blockDeviceTemplateGroup" + domain = "bar.example.com" + region = "ams01" + public_network_speed = 10 + hourly_billing = false + cpu = 1 + ram = 1024 + local_disk = false + block_device_template_group_gid = "ac2b413c-9893-4178-8e62-a24cbe2864db" +} +` diff --git a/vendor/github.com/maximilien/softlayer-go/client/fakes/softlayer_client_fake.go b/vendor/github.com/maximilien/softlayer-go/client/fakes/softlayer_client_fake.go new file mode 100644 index 000000000..8790af723 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/client/fakes/softlayer_client_fake.go @@ -0,0 +1,302 @@ +package client_fakes + +import ( + "bytes" + "errors" + "fmt" + "os" + "path/filepath" + + services "github.com/maximilien/softlayer-go/services" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +const ( + SOFTLAYER_API_URL = "api.softlayer.com/rest/v3" + TEMPLATE_ROOT_PATH = "templates" +) + +type FakeSoftLayerClient struct { + Username string + ApiKey string + + TemplatePath string + + SoftLayerServices map[string]softlayer.Service + + DoRawHttpRequestResponseCount int + + DoRawHttpRequestResponse []byte + DoRawHttpRequestResponses [][]byte + DoRawHttpRequestResponsesIndex int + DoRawHttpRequestError error + DoRawHttpRequestPath string + DoRawHttpRequestRequestType string + + GenerateRequestBodyBuffer *bytes.Buffer + GenerateRequestBodyError error + + HasErrorsError, CheckForHttpResponseError error +} + +func NewFakeSoftLayerClient(username, apiKey string) *FakeSoftLayerClient { + pwd, _ := os.Getwd() + fslc := &FakeSoftLayerClient{ + Username: username, + ApiKey: apiKey, + + TemplatePath: filepath.Join(pwd, TEMPLATE_ROOT_PATH), + + SoftLayerServices: map[string]softlayer.Service{}, + + DoRawHttpRequestResponseCount: 0, + + DoRawHttpRequestResponse: nil, + DoRawHttpRequestResponses: [][]byte{}, + DoRawHttpRequestResponsesIndex: 0, + DoRawHttpRequestError: nil, + DoRawHttpRequestPath: "", + DoRawHttpRequestRequestType: "", + + GenerateRequestBodyBuffer: new(bytes.Buffer), + GenerateRequestBodyError: nil, + + HasErrorsError: nil, + CheckForHttpResponseError: nil, + } + + fslc.initSoftLayerServices() + + return fslc +} + +//softlayer.Client interface methods + +func (fslc *FakeSoftLayerClient) GetService(serviceName string) (softlayer.Service, error) { + slService, ok := fslc.SoftLayerServices[serviceName] + if !ok { + return nil, errors.New(fmt.Sprintf("softlayer-go does not support service '%s'", serviceName)) + } + + return slService, nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Account_Service() (softlayer.SoftLayer_Account_Service, error) { + slService, err := fslc.GetService("SoftLayer_Account") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Account_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Virtual_Guest_Service() (softlayer.SoftLayer_Virtual_Guest_Service, error) { + slService, err := fslc.GetService("SoftLayer_Virtual_Guest") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Guest_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Dns_Domain_Service() (softlayer.SoftLayer_Dns_Domain_Service, error) { + slService, err := fslc.GetService("SoftLayer_Dns_Domain") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Dns_Domain_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Virtual_Disk_Image_Service() (softlayer.SoftLayer_Virtual_Disk_Image_Service, error) { + slService, err := fslc.GetService("SoftLayer_Virtual_Disk_Image") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Disk_Image_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Security_Ssh_Key_Service() (softlayer.SoftLayer_Security_Ssh_Key_Service, error) { + slService, err := fslc.GetService("SoftLayer_Security_Ssh_Key") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Security_Ssh_Key_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Network_Storage_Service() (softlayer.SoftLayer_Network_Storage_Service, error) { + slService, err := fslc.GetService("SoftLayer_Network_Storage") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Network_Storage_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Network_Storage_Allowed_Host_Service() (softlayer.SoftLayer_Network_Storage_Allowed_Host_Service, error) { + slService, err := fslc.GetService("SoftLayer_Network_Storage_Allowed_Host") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Network_Storage_Allowed_Host_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Product_Order_Service() (softlayer.SoftLayer_Product_Order_Service, error) { + slService, err := fslc.GetService("SoftLayer_Product_Order") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Product_Order_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Product_Package_Service() (softlayer.SoftLayer_Product_Package_Service, error) { + slService, err := fslc.GetService("SoftLayer_Product_Package") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Product_Package_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Billing_Item_Cancellation_Request_Service() (softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service, error) { + slService, err := fslc.GetService("SoftLayer_Billing_Item_Cancellation_Request") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service() (softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service, error) { + slService, err := fslc.GetService("SoftLayer_Virtual_Guest_Block_Device_Template_Group") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Hardware_Service() (softlayer.SoftLayer_Hardware_Service, error) { + slService, err := fslc.GetService("SoftLayer_Hardware") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Hardware_Service), nil +} + +func (fslc *FakeSoftLayerClient) GetSoftLayer_Dns_Domain_ResourceRecord_Service() (softlayer.SoftLayer_Dns_Domain_ResourceRecord_Service, error) { + slService, err := fslc.GetService("SoftLayer_Dns_Domain_ResourceRecord") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Dns_Domain_ResourceRecord_Service), nil +} + +//Public methods +func (fslc *FakeSoftLayerClient) DoRawHttpRequestWithObjectMask(path string, masks []string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + fslc.DoRawHttpRequestPath = path + fslc.DoRawHttpRequestRequestType = requestType + + fslc.DoRawHttpRequestResponseCount += 1 + + if fslc.DoRawHttpRequestError != nil { + return []byte{}, fslc.DoRawHttpRequestError + } + + if fslc.DoRawHttpRequestResponse != nil && len(fslc.DoRawHttpRequestResponses) == 0 { + return fslc.DoRawHttpRequestResponse, fslc.DoRawHttpRequestError + } else { + fslc.DoRawHttpRequestResponsesIndex = fslc.DoRawHttpRequestResponsesIndex + 1 + return fslc.DoRawHttpRequestResponses[fslc.DoRawHttpRequestResponsesIndex-1], fslc.DoRawHttpRequestError + } +} + +func (fslc *FakeSoftLayerClient) DoRawHttpRequestWithObjectFilter(path string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + fslc.DoRawHttpRequestPath = path + fslc.DoRawHttpRequestRequestType = requestType + + fslc.DoRawHttpRequestResponseCount += 1 + + if fslc.DoRawHttpRequestError != nil { + return []byte{}, fslc.DoRawHttpRequestError + } + + if fslc.DoRawHttpRequestResponse != nil && len(fslc.DoRawHttpRequestResponses) == 0 { + return fslc.DoRawHttpRequestResponse, fslc.DoRawHttpRequestError + } else { + fslc.DoRawHttpRequestResponsesIndex = fslc.DoRawHttpRequestResponsesIndex + 1 + return fslc.DoRawHttpRequestResponses[fslc.DoRawHttpRequestResponsesIndex-1], fslc.DoRawHttpRequestError + } +} + +func (fslc *FakeSoftLayerClient) DoRawHttpRequestWithObjectFilterAndObjectMask(path string, masks []string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + fslc.DoRawHttpRequestPath = path + fslc.DoRawHttpRequestRequestType = requestType + + fslc.DoRawHttpRequestResponseCount += 1 + + if fslc.DoRawHttpRequestError != nil { + return []byte{}, fslc.DoRawHttpRequestError + } + + if fslc.DoRawHttpRequestResponse != nil && len(fslc.DoRawHttpRequestResponses) == 0 { + return fslc.DoRawHttpRequestResponse, fslc.DoRawHttpRequestError + } else { + fslc.DoRawHttpRequestResponsesIndex = fslc.DoRawHttpRequestResponsesIndex + 1 + return fslc.DoRawHttpRequestResponses[fslc.DoRawHttpRequestResponsesIndex-1], fslc.DoRawHttpRequestError + } +} + +func (fslc *FakeSoftLayerClient) DoRawHttpRequest(path string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + fslc.DoRawHttpRequestPath = path + fslc.DoRawHttpRequestRequestType = requestType + + fslc.DoRawHttpRequestResponseCount += 1 + + if fslc.DoRawHttpRequestError != nil { + return []byte{}, fslc.DoRawHttpRequestError + } + + if fslc.DoRawHttpRequestResponse != nil && len(fslc.DoRawHttpRequestResponses) == 0 { + return fslc.DoRawHttpRequestResponse, fslc.DoRawHttpRequestError + } else { + fslc.DoRawHttpRequestResponsesIndex = fslc.DoRawHttpRequestResponsesIndex + 1 + return fslc.DoRawHttpRequestResponses[fslc.DoRawHttpRequestResponsesIndex-1], fslc.DoRawHttpRequestError + } +} + +func (fslc *FakeSoftLayerClient) GenerateRequestBody(templateData interface{}) (*bytes.Buffer, error) { + return fslc.GenerateRequestBodyBuffer, fslc.GenerateRequestBodyError +} + +func (fslc *FakeSoftLayerClient) HasErrors(body map[string]interface{}) error { + return fslc.HasErrorsError +} + +func (fslc *FakeSoftLayerClient) CheckForHttpResponseErrors(data []byte) error { + return fslc.CheckForHttpResponseError +} + +//Private methods + +func (fslc *FakeSoftLayerClient) initSoftLayerServices() { + fslc.SoftLayerServices["SoftLayer_Account"] = services.NewSoftLayer_Account_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Virtual_Guest"] = services.NewSoftLayer_Virtual_Guest_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Virtual_Disk_Image"] = services.NewSoftLayer_Virtual_Disk_Image_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Security_Ssh_Key"] = services.NewSoftLayer_Security_Ssh_Key_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Network_Storage"] = services.NewSoftLayer_Network_Storage_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Network_Storage_Allowed_Host"] = services.NewSoftLayer_Network_Storage_Allowed_Host_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Product_Order"] = services.NewSoftLayer_Product_Order_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Product_Package"] = services.NewSoftLayer_Product_Package_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Billing_Item_Cancellation_Request"] = services.NewSoftLayer_Billing_Item_Cancellation_Request_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Virtual_Guest_Block_Device_Template_Group"] = services.NewSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Hardware"] = services.NewSoftLayer_Hardware_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Dns_Domain"] = services.NewSoftLayer_Dns_Domain_Service(fslc) + fslc.SoftLayerServices["SoftLayer_Dns_Domain_ResourceRecord"] = services.NewSoftLayer_Dns_Domain_ResourceRecord_Service(fslc) +} diff --git a/vendor/github.com/maximilien/softlayer-go/client/softlayer_client.go b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client.go new file mode 100644 index 000000000..9a8423586 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client.go @@ -0,0 +1,350 @@ +package client + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/http/httputil" + "os" + "path/filepath" + "regexp" + "text/template" + + services "github.com/maximilien/softlayer-go/services" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +const ( + SOFTLAYER_API_URL = "api.softlayer.com/rest/v3" + TEMPLATE_ROOT_PATH = "templates" + SL_GO_NON_VERBOSE = "SL_GO_NON_VERBOSE" +) + +type SoftLayerClient struct { + username string + apiKey string + + templatePath string + + HTTPClient *http.Client + + softLayerServices map[string]softlayer.Service + + nonVerbose bool +} + +func NewSoftLayerClient(username, apiKey string) *SoftLayerClient { + pwd, err := os.Getwd() + if err != nil { + panic(err) // this should be handled by the user + } + + slc := &SoftLayerClient{ + username: username, + apiKey: apiKey, + + templatePath: filepath.Join(pwd, TEMPLATE_ROOT_PATH), + + HTTPClient: http.DefaultClient, + nonVerbose: checkNonVerbose(), + + softLayerServices: map[string]softlayer.Service{}, + } + + slc.initSoftLayerServices() + + return slc +} + +//softlayer.Client interface methods + +func (slc *SoftLayerClient) GetService(serviceName string) (softlayer.Service, error) { + slService, ok := slc.softLayerServices[serviceName] + if !ok { + return nil, errors.New(fmt.Sprintf("softlayer-go does not support service '%s'", serviceName)) + } + + return slService, nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Account_Service() (softlayer.SoftLayer_Account_Service, error) { + slService, err := slc.GetService("SoftLayer_Account") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Account_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Virtual_Guest_Service() (softlayer.SoftLayer_Virtual_Guest_Service, error) { + slService, err := slc.GetService("SoftLayer_Virtual_Guest") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Guest_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Dns_Domain_Service() (softlayer.SoftLayer_Dns_Domain_Service, error) { + slService, err := slc.GetService("SoftLayer_Dns_Domain") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Dns_Domain_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Virtual_Disk_Image_Service() (softlayer.SoftLayer_Virtual_Disk_Image_Service, error) { + slService, err := slc.GetService("SoftLayer_Virtual_Disk_Image") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Disk_Image_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Security_Ssh_Key_Service() (softlayer.SoftLayer_Security_Ssh_Key_Service, error) { + slService, err := slc.GetService("SoftLayer_Security_Ssh_Key") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Security_Ssh_Key_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Product_Package_Service() (softlayer.SoftLayer_Product_Package_Service, error) { + slService, err := slc.GetService("SoftLayer_Product_Package") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Product_Package_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service() (softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service, error) { + slService, err := slc.GetService("SoftLayer_Virtual_Guest_Block_Device_Template_Group") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Network_Storage_Service() (softlayer.SoftLayer_Network_Storage_Service, error) { + slService, err := slc.GetService("SoftLayer_Network_Storage") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Network_Storage_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Network_Storage_Allowed_Host_Service() (softlayer.SoftLayer_Network_Storage_Allowed_Host_Service, error) { + slService, err := slc.GetService("SoftLayer_Network_Storage_Allowed_Host") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Network_Storage_Allowed_Host_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Product_Order_Service() (softlayer.SoftLayer_Product_Order_Service, error) { + slService, err := slc.GetService("SoftLayer_Product_Order") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Product_Order_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Billing_Item_Cancellation_Request_Service() (softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service, error) { + slService, err := slc.GetService("SoftLayer_Billing_Item_Cancellation_Request") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Hardware_Service() (softlayer.SoftLayer_Hardware_Service, error) { + slService, err := slc.GetService("SoftLayer_Hardware") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Hardware_Service), nil +} + +func (slc *SoftLayerClient) GetSoftLayer_Dns_Domain_ResourceRecord_Service() (softlayer.SoftLayer_Dns_Domain_ResourceRecord_Service, error) { + slService, err := slc.GetService("SoftLayer_Dns_Domain_ResourceRecord") + if err != nil { + return nil, err + } + + return slService.(softlayer.SoftLayer_Dns_Domain_ResourceRecord_Service), nil +} + +//Public methods + +func (slc *SoftLayerClient) DoRawHttpRequestWithObjectMask(path string, masks []string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + url := fmt.Sprintf("https://%s:%s@%s/%s", slc.username, slc.apiKey, SOFTLAYER_API_URL, path) + + url += "?objectMask=" + for i := 0; i < len(masks); i++ { + url += masks[i] + if i != len(masks)-1 { + url += ";" + } + } + + return slc.makeHttpRequest(url, requestType, requestBody) +} + +func (slc *SoftLayerClient) DoRawHttpRequestWithObjectFilter(path string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + url := fmt.Sprintf("https://%s:%s@%s/%s", slc.username, slc.apiKey, SOFTLAYER_API_URL, path) + url += "?objectFilter=" + filters + + return slc.makeHttpRequest(url, requestType, requestBody) +} + +func (slc *SoftLayerClient) DoRawHttpRequestWithObjectFilterAndObjectMask(path string, masks []string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + url := fmt.Sprintf("https://%s:%s@%s/%s", slc.username, slc.apiKey, SOFTLAYER_API_URL, path) + + url += "?objectFilter=" + filters + + url += "&objectMask=filteredMask[" + for i := 0; i < len(masks); i++ { + url += masks[i] + if i != len(masks)-1 { + url += ";" + } + } + url += "]" + + return slc.makeHttpRequest(url, requestType, requestBody) +} + +func (slc *SoftLayerClient) DoRawHttpRequest(path string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + url := fmt.Sprintf("https://%s:%s@%s/%s", slc.username, slc.apiKey, SOFTLAYER_API_URL, path) + return slc.makeHttpRequest(url, requestType, requestBody) +} + +func (slc *SoftLayerClient) GenerateRequestBody(templateData interface{}) (*bytes.Buffer, error) { + cwd, err := os.Getwd() + if err != nil { + return nil, err + } + + bodyTemplate := template.Must(template.ParseFiles(filepath.Join(cwd, slc.templatePath))) + body := new(bytes.Buffer) + bodyTemplate.Execute(body, templateData) + + return body, nil +} + +func (slc *SoftLayerClient) HasErrors(body map[string]interface{}) error { + if errString, ok := body["error"]; !ok { + return nil + } else { + return errors.New(errString.(string)) + } +} + +func (slc *SoftLayerClient) CheckForHttpResponseErrors(data []byte) error { + var decodedResponse map[string]interface{} + err := json.Unmarshal(data, &decodedResponse) + if err != nil { + return err + } + + if err := slc.HasErrors(decodedResponse); err != nil { + return err + } + + return nil +} + +//Private methods + +func (slc *SoftLayerClient) initSoftLayerServices() { + slc.softLayerServices["SoftLayer_Account"] = services.NewSoftLayer_Account_Service(slc) + slc.softLayerServices["SoftLayer_Virtual_Guest"] = services.NewSoftLayer_Virtual_Guest_Service(slc) + slc.softLayerServices["SoftLayer_Virtual_Disk_Image"] = services.NewSoftLayer_Virtual_Disk_Image_Service(slc) + slc.softLayerServices["SoftLayer_Security_Ssh_Key"] = services.NewSoftLayer_Security_Ssh_Key_Service(slc) + slc.softLayerServices["SoftLayer_Product_Package"] = services.NewSoftLayer_Product_Package_Service(slc) + slc.softLayerServices["SoftLayer_Network_Storage"] = services.NewSoftLayer_Network_Storage_Service(slc) + slc.softLayerServices["SoftLayer_Network_Storage_Allowed_Host"] = services.NewSoftLayer_Network_Storage_Allowed_Host_Service(slc) + slc.softLayerServices["SoftLayer_Product_Order"] = services.NewSoftLayer_Product_Order_Service(slc) + slc.softLayerServices["SoftLayer_Billing_Item_Cancellation_Request"] = services.NewSoftLayer_Billing_Item_Cancellation_Request_Service(slc) + slc.softLayerServices["SoftLayer_Virtual_Guest_Block_Device_Template_Group"] = services.NewSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service(slc) + slc.softLayerServices["SoftLayer_Hardware"] = services.NewSoftLayer_Hardware_Service(slc) + slc.softLayerServices["SoftLayer_Dns_Domain"] = services.NewSoftLayer_Dns_Domain_Service(slc) + slc.softLayerServices["SoftLayer_Dns_Domain_ResourceRecord"] = services.NewSoftLayer_Dns_Domain_ResourceRecord_Service(slc) +} + +func hideCredentials(s string) string { + hiddenStr := "\"password\":\"******\"" + r := regexp.MustCompile(`"password":"[^"]*"`) + + return r.ReplaceAllString(s, hiddenStr) +} + +func (slc *SoftLayerClient) makeHttpRequest(url string, requestType string, requestBody *bytes.Buffer) ([]byte, error) { + req, err := http.NewRequest(requestType, url, requestBody) + if err != nil { + return nil, err + } + + bs, err := httputil.DumpRequest(req, true) + if err != nil { + return nil, err + } + + if !slc.nonVerbose { + fmt.Fprintf(os.Stderr, "\n---\n[softlayer-go] Request:\n%s\n", hideCredentials(string(bs))) + } + + resp, err := slc.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + bs, err = httputil.DumpResponse(resp, true) + if err != nil { + return nil, err + } + + if !slc.nonVerbose { + fmt.Fprintf(os.Stderr, "[softlayer-go] Response:\n%s\n", hideCredentials(string(bs))) + } + + responseBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return responseBody, nil +} + +//Private helper methods + +func checkNonVerbose() bool { + slGoNonVerbose := os.Getenv(SL_GO_NON_VERBOSE) + switch slGoNonVerbose { + case "yes": + return true + case "YES": + return true + case "true": + return true + case "TRUE": + return true + } + + return false +} diff --git a/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_suite_test.go b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_suite_test.go new file mode 100644 index 000000000..865cc2855 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_suite_test.go @@ -0,0 +1,13 @@ +package client_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestClient(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "SoftLayer Client Suite") +} diff --git a/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_test.go b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_test.go new file mode 100644 index 000000000..b24312ff2 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/client/softlayer_client_test.go @@ -0,0 +1,173 @@ +package client_test + +import ( + "bytes" + "errors" + "net" + "net/http" + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclient "github.com/maximilien/softlayer-go/client" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +var _ = Describe("SoftLayerClient", func() { + var ( + username string + apiKey string + + client softlayer.Client + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + apiKey = os.Getenv("SL_API_KEY") + + client = slclient.NewSoftLayerClient(username, apiKey) + }) + + Context("#NewSoftLayerClient", func() { + It("creates a new client with username and apiKey", func() { + Expect(username).ToNot(Equal(""), "username cannot be empty, set SL_USERNAME") + Expect(apiKey).ToNot(Equal(""), "apiKey cannot be empty, set SL_API_KEY") + + client = slclient.NewSoftLayerClient(username, apiKey) + Expect(client).ToNot(BeNil()) + }) + }) + + Context("#NewSoftLayerClient_HTTPClient", func() { + It("creates a new client which should have an initialized default HTTP client", func() { + client = slclient.NewSoftLayerClient(username, apiKey) + if c, ok := client.(*slclient.SoftLayerClient); ok { + Expect(c.HTTPClient).ToNot(BeNil()) + } + }) + + It("creates a new client with a custom HTTP client", func() { + client = slclient.NewSoftLayerClient(username, apiKey) + c, _ := client.(*slclient.SoftLayerClient) + + // Assign a malformed dialer to test if the HTTP client really works + var errDialFailed = errors.New("dial failed") + c.HTTPClient = &http.Client{ + Transport: &http.Transport{ + Dial: func(network, addr string) (net.Conn, error) { + return nil, errDialFailed + }, + }, + } + + _, err := c.DoRawHttpRequest("/foo", "application/text", bytes.NewBufferString("random text")) + Expect(err).To(Equal(errDialFailed)) + + }) + }) + + Context("#GetService", func() { + It("returns a service with name specified", func() { + accountService, err := client.GetService("SoftLayer_Account") + Expect(err).ToNot(HaveOccurred()) + Expect(accountService).ToNot(BeNil()) + }) + + It("fails when passed a bad service name", func() { + _, err := client.GetService("fake-service-name") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("softlayer-go does not support service 'fake-service-name'")) + }) + }) + + Context("#GetSoftLayer_Account_Service", func() { + It("returns a instance implemementing the SoftLayer_Account_Service interface", func() { + var accountService softlayer.SoftLayer_Account_Service + accountService, err := client.GetSoftLayer_Account_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(accountService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Virtual_Guest_Service", func() { + It("returns a instance implemementing the SoftLayer_Virtual_Guest_Service interface", func() { + var virtualGuestService softlayer.SoftLayer_Virtual_Guest_Service + virtualGuestService, err := client.GetSoftLayer_Virtual_Guest_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(virtualGuestService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Ssh_Key_Service", func() { + It("returns a instance implemementing the SoftLayer_Ssh_Key_Service interface", func() { + var sshKeyService softlayer.SoftLayer_Security_Ssh_Key_Service + sshKeyService, err := client.GetSoftLayer_Security_Ssh_Key_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(sshKeyService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Product_Order_Service", func() { + It("returns a instance implemementing the SoftLayer_Product_Order_Service interface", func() { + var productOrderService softlayer.SoftLayer_Product_Order_Service + productOrderService, err := client.GetSoftLayer_Product_Order_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(productOrderService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Product_Package_Service", func() { + It("returns a instance implemementing the SoftLayer_Product_Package interface", func() { + var productPackageService softlayer.SoftLayer_Product_Package_Service + productPackageService, err := client.GetSoftLayer_Product_Package_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(productPackageService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Network_Storage_Service", func() { + It("returns a instance implemementing the GetSoftLayer_Network_Storage_Service interface", func() { + var networkStorageService softlayer.SoftLayer_Network_Storage_Service + networkStorageService, err := client.GetSoftLayer_Network_Storage_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(networkStorageService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Network_Storage_Allowed_Host_Service", func() { + It("returns a instance implemementing the GetSoftLayer_Network_Storage_Allowed_Host_Service interface", func() { + var networkStorageAllowedHostService softlayer.SoftLayer_Network_Storage_Allowed_Host_Service + networkStorageAllowedHostService, err := client.GetSoftLayer_Network_Storage_Allowed_Host_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(networkStorageAllowedHostService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Billing_Item_Cancellation_Request", func() { + It("returns a instance implemementing the SoftLayer_Billing_Item_Cancellation_Request interface", func() { + var billingItemCancellationRequestService softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service + billingItemCancellationRequestService, err := client.GetSoftLayer_Billing_Item_Cancellation_Request_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(billingItemCancellationRequestService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service", func() { + It("returns a instance implemementing the SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service interface", func() { + var vgbdtgService softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service + vgbdtgService, err := client.GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(vgbdtgService).ToNot(BeNil()) + }) + }) + + Context("#GetSoftLayer_Hardware_Service", func() { + It("returns an instance implemementing the SoftLayer_Hardware_Service interface", func() { + var hardwareService softlayer.SoftLayer_Hardware_Service + hardwareService, err := client.GetSoftLayer_Hardware_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(hardwareService).ToNot(BeNil()) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/common/common_suite_test.go b/vendor/github.com/maximilien/softlayer-go/common/common_suite_test.go new file mode 100644 index 000000000..b0095532f --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/common/common_suite_test.go @@ -0,0 +1,13 @@ +package common_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestCommon(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Common Suite") +} diff --git a/vendor/github.com/maximilien/softlayer-go/common/utility.go b/vendor/github.com/maximilien/softlayer-go/common/utility.go new file mode 100644 index 000000000..4d1700f9c --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/common/utility.go @@ -0,0 +1,16 @@ +package common + +import ( + "encoding/json" +) + +func ValidateJson(s string) (bool, error) { + var js map[string]interface{} + + err := json.Unmarshal([]byte(s), &js) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/common/utility_test.go b/vendor/github.com/maximilien/softlayer-go/common/utility_test.go new file mode 100644 index 000000000..c88ec40d3 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/common/utility_test.go @@ -0,0 +1,29 @@ +package common_test + +import ( + . "github.com/maximilien/softlayer-go/common" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Utility", func() { + var ( + result bool + err error + ) + + Context("#ValidateJson", func() { + It("returns true if the input string is valid Json format", func() { + result, err = ValidateJson(`{"correct_json":"whatever"}`) + Expect(result).To(Equal(true)) + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns false if the input string is invalid Json format", func() { + result, err = ValidateJson(`{{"wrong_json":"whatever"}`) + Expect(result).To(Equal(false)) + Expect(err).To(HaveOccurred()) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_network_storage_credential.go b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_network_storage_credential.go new file mode 100644 index 000000000..98a4e1718 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_network_storage_credential.go @@ -0,0 +1,14 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Network_Storage_Credential struct { + AccountId string `json:"accountId"` + CreateDate time.Time `json:"createDate"` + Id int `json:"Id"` + NasCredentialTypeId int `json:"nasCredentialTypeId"` + Password string `json:"password"` + Username string `json:"username"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_tag_reference.go b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_tag_reference.go new file mode 100644 index 000000000..4297d9c6e --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_tag_reference.go @@ -0,0 +1,24 @@ +package data_types + +type SoftLayer_Tag_Reference struct { + EmpRecordId *int `json:"empRecordId"` + Id int `json:"id"` + ResourceTableId int `json:"resourceTableId"` + Tag TagReference `json:"tag"` + TagId int `json:"tagId"` + TagType TagType `json:"tagType"` + TagTypeId int `json:"tagTypeId"` + UsrRecordId int `json:"usrRecordId"` +} + +type TagReference struct { + AccountId int `json:"accountId"` + Id int `json:"id"` + Internal int `json:"internal"` + Name string `json:"name"` +} + +type TagType struct { + Description string `json:"description"` + KeyName string `json:"keyName"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_attribute.go b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_attribute.go new file mode 100644 index 000000000..3f9494fd8 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_attribute.go @@ -0,0 +1,12 @@ +package data_types + +type SoftLayer_Virtual_Guest_Attribute_Type struct { + Keyname string `json:"keyname"` + Name string `json:"name"` +} + +type SoftLayer_Virtual_Guest_Attribute struct { + Value string `json:"value"` + + Type SoftLayer_Virtual_Guest_Attribute_Type `json:"type"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_init_parameters.go b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_init_parameters.go new file mode 100644 index 000000000..b257eb4b5 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_init_parameters.go @@ -0,0 +1,17 @@ +package data_types + +type SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameters struct { + Parameters SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameter `json:"parameters"` +} + +type SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameter struct { + AccountId int `json:"accountId"` +} + +type SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameters struct { + Parameters SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameter `json:"parameters"` +} + +type SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameter struct { + Locations []SoftLayer_Location `json:"locations"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_status.go b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_status.go new file mode 100644 index 000000000..91eaabe7d --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softLayer_virtual_guest_block_device_template_group_status.go @@ -0,0 +1,7 @@ +package data_types + +type SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status struct { + Description string `json:"description"` + KeyName string `json:"keyName"` + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_account_status.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_account_status.go new file mode 100644 index 000000000..a653d9740 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_account_status.go @@ -0,0 +1,6 @@ +package data_types + +type SoftLayer_Account_Status struct { + Id int `json:"id"` + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_billing_item_cancellation_request.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_billing_item_cancellation_request.go new file mode 100644 index 000000000..9124fb012 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_billing_item_cancellation_request.go @@ -0,0 +1,18 @@ +package data_types + +type SoftLayer_Billing_Item_Cancellation_Request_Parameters struct { + Parameters []SoftLayer_Billing_Item_Cancellation_Request `json:"parameters"` +} + +type SoftLayer_Billing_Item_Cancellation_Request struct { + ComplexType string `json:"complexType"` + AccountId int `json:"accountId"` + Id int `json:"id"` + TicketId int `json:"ticketId"` + Items []SoftLayer_Billing_Item_Cancellation_Request_Item `json:"items"` +} + +type SoftLayer_Billing_Item_Cancellation_Request_Item struct { + BillingItemId int `json:"billingItemId"` + ImmediateCancellationFlag bool `json:"immediateCancellationFlag"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_disk_image_capture_template.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_disk_image_capture_template.go new file mode 100644 index 000000000..6cb86ab31 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_disk_image_capture_template.go @@ -0,0 +1,17 @@ +package data_types + +type SoftLayer_Container_Disk_Image_Capture_Template struct { + Description string `json:"description"` + Name string `json:"name"` + Summary string `json:"summary"` + Volumes []SoftLayer_Container_Disk_Image_Capture_Template_Volume `json:"volumes"` +} + +type SoftLayer_Container_Disk_Image_Capture_Template_Volume struct { + Name string `json:"name"` + Partitions []SoftLayer_Container_Disk_Image_Capture_Template_Volume_Partition +} + +type SoftLayer_Container_Disk_Image_Capture_Template_Volume_Partition struct { + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_product_order.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_product_order.go new file mode 100644 index 000000000..e9bca3bca --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_product_order.go @@ -0,0 +1,60 @@ +package data_types + +type SoftLayer_Container_Product_Order_Receipt struct { + OrderId int `json:"orderId"` +} + +type SoftLayer_Container_Product_Order_Parameters struct { + Parameters []SoftLayer_Container_Product_Order `json:"parameters"` +} + +type SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi_Parameters struct { + Parameters []SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi `json:"parameters"` +} + +type SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade_Parameters struct { + Parameters []SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade `json:"parameters"` +} + +//http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order +type SoftLayer_Container_Product_Order struct { + ComplexType string `json:"complexType"` + Location string `json:"location,omitempty"` + PackageId int `json:"packageId"` + Prices []SoftLayer_Product_Item_Price `json:"prices,omitempty"` + VirtualGuests []VirtualGuest `json:"virtualGuests,omitempty"` + Properties []Property `json:"properties,omitempty"` + Quantity int `json:"quantity,omitempty"` +} + +//http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi +type SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi struct { + ComplexType string `json:"complexType"` + Location string `json:"location,omitempty"` + PackageId int `json:"packageId"` + Prices []SoftLayer_Product_Item_Price `json:"prices,omitempty"` + VirtualGuests []VirtualGuest `json:"virtualGuests,omitempty"` + Properties []Property `json:"properties,omitempty"` + Quantity int `json:"quantity,omitempty"` + OsFormatType SoftLayer_Network_Storage_Iscsi_OS_Type `json:"osFormatType,omitempty"` +} + +//http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade +type SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade struct { + ComplexType string `json:"complexType"` + Location string `json:"location,omitempty"` + PackageId int `json:"packageId"` + Prices []SoftLayer_Product_Item_Price `json:"prices,omitempty"` + VirtualGuests []VirtualGuest `json:"virtualGuests,omitempty"` + Properties []Property `json:"properties,omitempty"` + Quantity int `json:"quantity,omitempty"` +} + +type Property struct { + Name string `json:"name"` + Value string `json:"value"` +} + +type VirtualGuest struct { + Id int `json:"id"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_virtual_guest_block_device_template_configuration.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_virtual_guest_block_device_template_configuration.go new file mode 100644 index 000000000..003a396d2 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_container_virtual_guest_block_device_template_configuration.go @@ -0,0 +1,12 @@ +package data_types + +type SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration_Parameters struct { + Parameters []SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration `json:"parameters"` +} + +type SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration struct { + Name string `json:"name"` + Note string `json:"note"` + OperatingSystemReferenceCode string `json:"operatingSystemReferenceCode"` + Uri string `json:"uri"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain.go new file mode 100644 index 000000000..a84e5939b --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain.go @@ -0,0 +1,20 @@ +package data_types + +type SoftLayer_Dns_Domain_Template struct { + Name string `json:"name"` + ResourceRecords []SoftLayer_Dns_Domain_ResourceRecord `json:"resourceRecords"` +} + +type SoftLayer_Dns_Domain_Template_Parameters struct { + Parameters []SoftLayer_Dns_Domain_Template `json:"parameters"` +} + +type SoftLayer_Dns_Domain struct { + Id int `json:"id"` + Name string `json:"name"` + Serial int `json:"serial"` + UpdateDate string `json:"updateDate"` + ManagedResourceFlag bool `json:"managedResourceFlag"` + ResourceRecordCount int `json:"resourceRecordCount"` + ResourceRecords []SoftLayer_Dns_Domain_ResourceRecord `json:"resourceRecords"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain_record.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain_record.go new file mode 100644 index 000000000..c80956127 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_dns_domain_record.go @@ -0,0 +1,49 @@ +package data_types + +type SoftLayer_Dns_Domain_ResourceRecord_Template_Parameters struct { + Parameters []SoftLayer_Dns_Domain_ResourceRecord_Template `json:"parameters"` +} + +type SoftLayer_Dns_Domain_ResourceRecord_Template struct { + Data string `json:"data"` + DomainId int `json:"domainId"` + Expire int `json:"expire"` + Host string `json:"host"` + Id int `json:"id"` + Minimum int `json:"minimum"` + MxPriority int `json:"mxPriority"` + Refresh int `json:"refresh"` + ResponsiblePerson string `json:"responsiblePerson"` + Retry int `json:"retry"` + Ttl int `json:"ttl"` + Type string `json:"type"` + Service string `json:"service,omitempty"` + Protocol string `json:"protocol,omitempty"` + Priority int `json:"priority,omitempty"` + Port int `json:"port,omitempty"` + Weight int `json:"weight,omitempty"` +} + +type SoftLayer_Dns_Domain_ResourceRecord_Parameters struct { + Parameters []SoftLayer_Dns_Domain_ResourceRecord `json:"parameters"` +} + +type SoftLayer_Dns_Domain_ResourceRecord struct { + Data string `json:"data"` + DomainId int `json:"domainId"` + Expire int `json:"expire"` + Host string `json:"host"` + Id int `json:"id"` + Minimum int `json:"minimum"` + MxPriority int `json:"mxPriority"` + Refresh int `json:"refresh"` + ResponsiblePerson string `json:"responsiblePerson"` + Retry int `json:"retry"` + Ttl int `json:"ttl"` + Type string `json:"type"` + Service string `json:"service,omitempty"` + Protocol string `json:"protocol,omitempty"` + Priority int `json:"priority,omitempty"` + Port int `json:"port,omitempty"` + Weight int `json:"weight,omitempty"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_hardware.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_hardware.go new file mode 100644 index 000000000..0cb54dbc0 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_hardware.go @@ -0,0 +1,33 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Hardware_Template_Parameters struct { + Parameters []SoftLayer_Hardware_Template `json:"parameters"` +} + +type SoftLayer_Hardware_Template struct { + Hostname string `json:"hostname"` + Domain string `json:"domain"` + ProcessorCoreAmount int `json:"processorCoreAmount"` + MemoryCapacity int `json:"memoryCapacity"` + HourlyBillingFlag bool `json:"hourlyBillingFlag"` + OperatingSystemReferenceCode string `json:"operatingSystemReferenceCode"` + + Datacenter *Datacenter `json:"datacenter"` +} + +type SoftLayer_Hardware struct { + BareMetalInstanceFlag int `json:"bareMetalInstanceFlag"` + Domain string `json:"domain"` + Hostname string `json:"hostname"` + Id int `json:"id"` + HardwareStatusId int `json:"hardwareStatusId"` + ProvisionDate *time.Time `json:"provisionDate"` + GlobalIdentifier string `json:"globalIdentifier"` + PrimaryIpAddress string `json:"primaryIpAddress"` + + OperatingSystem *SoftLayer_Operating_System `json:"operatingSystem"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_image_type.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_image_type.go new file mode 100644 index 000000000..dd99e8031 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_image_type.go @@ -0,0 +1,7 @@ +package data_types + +type SoftLayer_Image_Type struct { + Description string `json:"description"` + KeyName string `json:"keyName"` + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_location.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_location.go new file mode 100644 index 000000000..dff22b5a4 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_location.go @@ -0,0 +1,7 @@ +package data_types + +type SoftLayer_Location struct { + Id int `json:"id"` + LongName string `json:"longName"` + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage.go new file mode 100644 index 000000000..bb5a2300c --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage.go @@ -0,0 +1,37 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Network_Storage struct { + AccountId int `json:"accountId,omitempty"` + CapacityGb int `json:"capacityGb,omitempty"` + CreateDate time.Time `json:"createDate,omitempty"` + GuestId int `json:"guestId,omitempty"` + HardwareId int `json:"hardwareId,omitempty"` + HostId int `json:"hostId,omitempty"` + Id int `json:"id,omitempty"` + NasType string `json:"nasType,omitempty"` + Notes string `json:"notes,omitempty"` + Password string `json:"password,omitempty"` + ServiceProviderId int `json:"serviceProviderId,omitempty"` + UpgradableFlag bool `json:"upgradableFlag,omitempty"` + Username string `json:"username,omitempty"` + BillingItem *Billing_Item `json:"billingItem,omitempty"` + LunId string `json:"lunId,omitempty"` + ServiceResourceBackendIpAddress string `json:"serviceResourceBackendIpAddress,omitempty"` +} + +type Billing_Item struct { + Id int `json:"id,omitempty"` + OrderItem *Order_Item `json:"orderItem,omitempty"` +} + +type Order_Item struct { + Order *Order `json:"order,omitempty"` +} + +type Order struct { + Id int `json:"id,omitempty"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_allowed_host.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_allowed_host.go new file mode 100644 index 000000000..8a4ee171b --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_allowed_host.go @@ -0,0 +1,9 @@ +package data_types + +type SoftLayer_Network_Storage_Allowed_Host struct { + CredentialId int `json:"credentialId"` + Id int `json:"id"` + Name string `json:"name"` + ResourceTableId int `json:"resourceTabledId"` + ResourceTableName string `jsob:"resourceTableName"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_iscsi_os_type.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_iscsi_os_type.go new file mode 100644 index 000000000..68356e58f --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_storage_iscsi_os_type.go @@ -0,0 +1,12 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Network_Storage_Iscsi_OS_Type struct { + CreateDate time.Time `json:"createDate"` + Id int `json:"id"` + Name string `json:"name"` + KeyName string `json:"keyName"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_vlan.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_vlan.go new file mode 100644 index 000000000..16739c6c1 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_network_vlan.go @@ -0,0 +1,16 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Network_Vlan struct { + AccountId int `json:"accountId"` + Id int `json:"Id"` + ModifyDate *time.Time `json:"modifyDate,omitempty"` + Name string `json:"name"` + NetworkVrfId int `json:"networkVrfId"` + Note string `json:"note"` + PrimarySubnetId int `json:"primarySubnetId"` + VlanNumber int `json:"vlanNumber"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_item_price.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_item_price.go new file mode 100644 index 000000000..ab912b787 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_item_price.go @@ -0,0 +1,19 @@ +package data_types + +type SoftLayer_Product_Item_Price struct { + Id int `json:"id"` + LocationGroupId int `json:"locationGroupId"` + Categories []Category `json:"categories,omitempty"` + Item *Item `json:"item,omitempty"` +} + +type Item struct { + Id int `json:"id"` + Description string `json:"description"` + Capacity string `json:"capacity"` +} + +type Category struct { + Id int `json:"id"` + CategoryCode string `json:"categoryCode"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_package.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_package.go new file mode 100644 index 000000000..15c86f28b --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_product_package.go @@ -0,0 +1,20 @@ +package data_types + +type Softlayer_Product_Package struct { + Id int `json:"id"` + Name string `json:"name"` + IsActive int `json:"isActive"` + Description string `json:"description"` + PackageType *Package_Type `json:"type"` +} + +type Package_Type struct { + KeyName string `json:"keyName"` +} + +type SoftLayer_Product_Item struct { + Id int `json:"id"` + Description string `json:"description"` + Capacity string `json:"capacity"` + Prices []SoftLayer_Product_Item_Price `json:"prices,omitempty"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_provisioning_version1_transaction.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_provisioning_version1_transaction.go new file mode 100644 index 000000000..3fb042575 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_provisioning_version1_transaction.go @@ -0,0 +1,29 @@ +package data_types + +import ( + "time" +) + +type TransactionGroup struct { + AverageTimeToComplete string `json:"averageTimeToComplete"` + Name string `json:"name"` +} + +type TransactionStatus struct { + AverageDuration string `json:"averageDuration"` + FriendlyName string `json:"friendlyName"` + Name string `json:"name"` +} + +type SoftLayer_Provisioning_Version1_Transaction struct { + CreateDate *time.Time `json:"createDate"` + ElapsedSeconds int `json:"elapsedSeconds"` + GuestId int `json:"guestId"` + HardwareId int `json:"hardwareId"` + Id int `json:"id"` + ModifyDate *time.Time `json:"modifyDate"` + StatusChangeDate *time.Time `json:"statusChangeDate"` + + TransactionGroup TransactionGroup `json:"transactionGroup,omitempty"` + TransactionStatus TransactionStatus `json:"transactionStatus,omitempty"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_security_ssh_key.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_security_ssh_key.go new file mode 100644 index 000000000..8695cdc95 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_security_ssh_key.go @@ -0,0 +1,19 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Shh_Key_Parameters struct { + Parameters []SoftLayer_Security_Ssh_Key `json:"parameters"` +} + +type SoftLayer_Security_Ssh_Key struct { + CreateDate *time.Time `json:"createDate"` + Fingerprint string `json:"fingerprint"` + Id int `json:"id"` + Key string `json:"key"` + Label string `json:"label"` + ModifyDate *time.Time `json:"modifyDate"` + Notes string `json:"notes"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_set_user_metadata.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_set_user_metadata.go new file mode 100644 index 000000000..036a9ac64 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_set_user_metadata.go @@ -0,0 +1,8 @@ +package data_types + +type UserMetadata string +type UserMetadataArray []UserMetadata + +type SoftLayer_SetUserMetadata_Parameters struct { + Parameters []UserMetadataArray `json:"parameters"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_software_component_password.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_software_component_password.go new file mode 100644 index 000000000..3f1fe1b3d --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_software_component_password.go @@ -0,0 +1,24 @@ +package data_types + +import ( + "time" +) + +type Software struct { + HardwareId int `json:"hardwareId,omitempty"` + Id int `json:"id"` + ManufacturerLicenseInstance string `json:"manufacturerLicenseInstance"` +} + +type SoftLayer_Software_Component_Password struct { + CreateDate *time.Time `json:"createDate"` + Id int `json:"id"` + ModifyDate *time.Time `json:"modifyDate"` + Notes string `json:"notes"` + Password string `json:"password"` + Port int `json:"port"` + SoftwareId int `json:"softwareId"` + Username string `json:"username"` + + Software Software `json:"software"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_disk_image.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_disk_image.go new file mode 100644 index 000000000..d29de9094 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_disk_image.go @@ -0,0 +1,20 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Virtual_Disk_Image struct { + Capacity int `json:"capacity"` + Checksum string `json:"checksum"` + CreateDate *time.Time `json:"createDate"` + Description string `json:"description"` + Id int `json:"id"` + ModifyDate *time.Time `json:"modifyDate"` + Name string `json:"name"` + ParentId int `json:"parentId"` + StorageRepositoryId int `json:"storageRepositoryId"` + TypeId int `json:"typeId"` + Units string `json:"units"` + Uuid string `json:"uuid"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest.go new file mode 100644 index 000000000..8a4d7dc84 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest.go @@ -0,0 +1,150 @@ +package data_types + +import ( + "time" +) + +type SoftLayer_Virtual_Guest_Parameters struct { + Parameters []SoftLayer_Virtual_Guest `json:"parameters"` +} + +type SoftLayer_Virtual_Guest struct { + AccountId int `json:"accountId,omitempty"` + CreateDate *time.Time `json:"createDate,omitempty"` + DedicatedAccountHostOnlyFlag bool `json:"dedicatedAccountHostOnlyFlag,omitempty"` + Domain string `json:"domain,omitempty"` + FullyQualifiedDomainName string `json:"fullyQualifiedDomainName,omitempty"` + Hostname string `json:"hostname,omitempty"` + Id int `json:"id,omitempty"` + LastPowerStateId int `json:"lastPowerStateId,omitempty"` + LastVerifiedDate *time.Time `json:"lastVerifiedDate,omitempty"` + MaxCpu int `json:"maxCpu,omitempty"` + MaxCpuUnits string `json:"maxCpuUnits,omitempty"` + MaxMemory int `json:"maxMemory,omitempty"` + MetricPollDate *time.Time `json:"metricPollDate,omitempty"` + ModifyDate *time.Time `json:"modifyDate,omitempty"` + Notes string `json:"notes,omitempty"` + PostInstallScriptUri string `json:"postInstallScriptUri,omitempty"` + PrivateNetworkOnlyFlag bool `json:"privateNetworkOnlyFlag,omitempty"` + StartCpus int `json:"startCpus,omitempty"` + StatusId int `json:"statusId,omitempty"` + Uuid string `json:"uuid,omitempty"` + LocalDiskFlag bool `json:"localDiskFlag,omitempty"` + HourlyBillingFlag bool `json:"hourlyBillingFlag,omitempty"` + + GlobalIdentifier string `json:"globalIdentifier,omitempty"` + ManagedResourceFlag bool `json:"managedResourceFlag,omitempty"` + PrimaryBackendIpAddress string `json:"primaryBackendIpAddress,omitempty"` + PrimaryIpAddress string `json:"primaryIpAddress,omitempty"` + + PrimaryNetworkComponent *PrimaryNetworkComponent `json:"primaryNetworkComponent,omitempty"` + PrimaryBackendNetworkComponent *PrimaryBackendNetworkComponent `json:"primaryBackendNetworkComponent,omitempty"` + + Location *SoftLayer_Location `json:"location"` + Datacenter *SoftLayer_Location `json:"datacenter"` + NetworkComponents []NetworkComponents `json:"networkComponents,omitempty"` + UserData []UserData `json:"userData,omitempty"` + + OperatingSystem *SoftLayer_Operating_System `json:"operatingSystem"` + + BlockDeviceTemplateGroup *BlockDeviceTemplateGroup `json:"blockDeviceTemplateGroup,omitempty"` +} + +type SoftLayer_Operating_System struct { + Passwords []SoftLayer_Password `json:"passwords"` +} + +type SoftLayer_Password struct { + Username string `json:"username"` + Password string `json:"password"` +} + +type SoftLayer_Virtual_Guest_Template_Parameters struct { + Parameters []SoftLayer_Virtual_Guest_Template `json:"parameters"` +} + +type SoftLayer_Virtual_Guest_Template struct { + //Required + Hostname string `json:"hostname"` + Domain string `json:"domain"` + StartCpus int `json:"startCpus"` + MaxMemory int `json:"maxMemory"` + Datacenter Datacenter `json:"datacenter"` + HourlyBillingFlag bool `json:"hourlyBillingFlag"` + LocalDiskFlag bool `json:"localDiskFlag"` + + //Conditionally required + OperatingSystemReferenceCode string `json:"operatingSystemReferenceCode,omitempty"` + BlockDeviceTemplateGroup *BlockDeviceTemplateGroup `json:"blockDeviceTemplateGroup,omitempty"` + + //Optional + DedicatedAccountHostOnlyFlag bool `json:"dedicatedAccountHostOnlyFlag,omitempty"` + NetworkComponents []NetworkComponents `json:"networkComponents,omitempty"` + PrivateNetworkOnlyFlag bool `json:"privateNetworkOnlyFlag,omitempty"` + PrimaryNetworkComponent *PrimaryNetworkComponent `json:"primaryNetworkComponent,omitempty"` + PrimaryBackendNetworkComponent *PrimaryBackendNetworkComponent `json:"primaryBackendNetworkComponent,omitempty"` + PostInstallScriptUri string `json:"postInstallScriptUri,omitempty"` + + BlockDevices []BlockDevice `json:"blockDevices,omitempty"` + UserData []UserData `json:"userData,omitempty"` + SshKeys []SshKey `json:"sshKeys,omitempty"` +} + +type Datacenter struct { + //Required + Name string `json:"name"` +} + +type BlockDeviceTemplateGroup struct { + //Required + GlobalIdentifier string `json:"globalIdentifier,omitempty"` +} + +type NetworkComponents struct { + //Required, defaults to 10 + MaxSpeed int `json:"maxSpeed,omitempty"` +} + +type NetworkVlan struct { + //Required + Id int `json:"id,omitempty"` +} + +type PrimaryNetworkComponent struct { + //Required + NetworkVlan NetworkVlan `json:"networkVlan,omitempty"` +} + +type PrimaryBackendNetworkComponent struct { + //Required + NetworkVlan NetworkVlan `json:"networkVlan,omitempty"` +} + +type DiskImage struct { + //Required + Capacity int `json:"capacity,omitempty"` +} + +type BlockDevice struct { + //Required + Device string `json:"device,omitempty"` + DiskImage DiskImage `json:"diskImage,omitempty"` +} + +type UserData struct { + //Required + Value string `json:"value,omitempty"` +} + +type SshKey struct { + //Required + Id int `json:"id,omitempty"` +} + +type SoftLayer_Virtual_Guest_SetTags_Parameters struct { + Parameters []string `json:"parameters"` +} + +type Image_Template_Config struct { + ImageTemplateId string `json:"imageTemplateId"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_block_device_template_group.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_block_device_template_group.go new file mode 100644 index 000000000..bf0a7355b --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_block_device_template_group.go @@ -0,0 +1,18 @@ +package data_types + +import "time" + +type SoftLayer_Virtual_Guest_Block_Device_Template_Group struct { + AccountId int `json:"accountId"` + CreateDate *time.Time `json:"createDate"` + Id int `json:"id"` + Name string `json:"name"` + Note string `json:"note"` + ParentId *int `json:"parentId"` + PublicFlag int `json:"publicFlag"` + StatusId int `json:"statusId"` + Summary string `json:"summary"` + TransactionId *int `json:"transactionId"` + UserRecordId int `json:"userRecordId"` + GlobalIdentifier string `json:"globalIdentifier"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_init_parameters.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_init_parameters.go new file mode 100644 index 000000000..ec0b0f330 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_init_parameters.go @@ -0,0 +1,9 @@ +package data_types + +type SoftLayer_Virtual_GuestInitParameters struct { + Parameters SoftLayer_Virtual_GuestInitParameter `json:"parameters"` +} + +type SoftLayer_Virtual_GuestInitParameter struct { + ImageId int `json:"imageId"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_power_state.go b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_power_state.go new file mode 100644 index 000000000..6dd271db0 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/data_types/softlayer_virtual_guest_power_state.go @@ -0,0 +1,7 @@ +package data_types + +type SoftLayer_Virtual_Guest_Power_State struct { + Description string `json:"description"` + KeyName string `json:"keyName"` + Name string `json:"name"` +} diff --git a/vendor/github.com/maximilien/softlayer-go/main/slgo.go b/vendor/github.com/maximilien/softlayer-go/main/slgo.go new file mode 100644 index 000000000..1e7bd3156 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/main/slgo.go @@ -0,0 +1,9 @@ +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("SoftLayer go client") +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/services_suite_test.go b/vendor/github.com/maximilien/softlayer-go/services/services_suite_test.go new file mode 100644 index 000000000..2e4147950 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/services_suite_test.go @@ -0,0 +1,13 @@ +package services_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestServices(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Services Suite") +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softLayer_account.go b/vendor/github.com/maximilien/softlayer-go/services/softLayer_account.go new file mode 100644 index 000000000..8ad5647e9 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softLayer_account.go @@ -0,0 +1,291 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + "github.com/maximilien/softlayer-go/common" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Account_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Account_Service(client softlayer.Client) *softLayer_Account_Service { + return &softLayer_Account_Service{ + client: client, + } +} + +func (slas *softLayer_Account_Service) GetName() string { + return "SoftLayer_Account" +} + +func (slas *softLayer_Account_Service) GetAccountStatus() (datatypes.SoftLayer_Account_Status, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getAccountStatus.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getAccountStatus, error message '%s'", err.Error()) + return datatypes.SoftLayer_Account_Status{}, errors.New(errorMessage) + } + + accountStatus := datatypes.SoftLayer_Account_Status{} + err = json.Unmarshal(responseBytes, &accountStatus) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return datatypes.SoftLayer_Account_Status{}, err + } + + return accountStatus, nil +} + +func (slas *softLayer_Account_Service) GetVirtualGuests() ([]datatypes.SoftLayer_Virtual_Guest, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getVirtualGuests.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getVirtualGuests, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Virtual_Guest{}, errors.New(errorMessage) + } + + virtualGuests := []datatypes.SoftLayer_Virtual_Guest{} + err = json.Unmarshal(responseBytes, &virtualGuests) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Virtual_Guest{}, err + } + + return virtualGuests, nil +} + +func (slas *softLayer_Account_Service) GetNetworkStorage() ([]datatypes.SoftLayer_Network_Storage, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getNetworkStorage.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getNetworkStorage, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Network_Storage{}, errors.New(errorMessage) + } + + networkStorage := []datatypes.SoftLayer_Network_Storage{} + err = json.Unmarshal(responseBytes, &networkStorage) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Network_Storage{}, err + } + + return networkStorage, nil +} + +func (slas *softLayer_Account_Service) GetIscsiNetworkStorage() ([]datatypes.SoftLayer_Network_Storage, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getIscsiNetworkStorage.json") + + objectMasks := []string{ + "username", + "accountId", + "capacityGb", + "id", + "billingItem.id", + "billingItem.orderItem.order.id", + } + + responseBytes, err := slas.client.DoRawHttpRequestWithObjectMask(path, objectMasks, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getIscsiNetworkStorage, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Network_Storage{}, errors.New(errorMessage) + } + + networkStorage := []datatypes.SoftLayer_Network_Storage{} + err = json.Unmarshal(responseBytes, &networkStorage) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Network_Storage{}, err + } + + return networkStorage, nil +} + +func (slas *softLayer_Account_Service) GetIscsiNetworkStorageWithFilter(filter string) ([]datatypes.SoftLayer_Network_Storage, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getIscsiNetworkStorage.json") + + objectMasks := []string{ + "username", + "accountId", + "capacityGb", + "id", + "billingItem.id", + "billingItem.orderItem.order.id", + } + + responseBytes, err := slas.client.DoRawHttpRequestWithObjectFilterAndObjectMask(path, objectMasks, filter, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getIscsiNetworkStorage, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Network_Storage{}, errors.New(errorMessage) + } + + networkStorage := []datatypes.SoftLayer_Network_Storage{} + err = json.Unmarshal(responseBytes, &networkStorage) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Network_Storage{}, err + } + + return networkStorage, nil +} + +func (slas *softLayer_Account_Service) GetVirtualDiskImages() ([]datatypes.SoftLayer_Virtual_Disk_Image, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getVirtualDiskImages.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could get SoftLayer_Account#getVirtualDiskImages, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Virtual_Disk_Image{}, errors.New(errorMessage) + } + + virtualDiskImages := []datatypes.SoftLayer_Virtual_Disk_Image{} + err = json.Unmarshal(responseBytes, &virtualDiskImages) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Virtual_Disk_Image{}, err + } + + return virtualDiskImages, nil +} + +func (slas *softLayer_Account_Service) GetVirtualDiskImagesWithFilter(filters string) ([]datatypes.SoftLayer_Virtual_Disk_Image, error) { + isJson, err := common.ValidateJson(filters) + if !isJson || err != nil { + errorMessage := fmt.Sprintf("softlayer-go: filters string %s is not a valid Json formatted string, error message '%s'", filters, err.Error()) + return []datatypes.SoftLayer_Virtual_Disk_Image{}, errors.New(errorMessage) + } + + path := fmt.Sprintf("%s/%s", slas.GetName(), "getVirtualDiskImages.json") + responseBytes, err := slas.client.DoRawHttpRequestWithObjectFilter(path, filters, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could get SoftLayer_Account#getVirtualDiskImages, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Virtual_Disk_Image{}, errors.New(errorMessage) + } + + virtualDiskImages := []datatypes.SoftLayer_Virtual_Disk_Image{} + err = json.Unmarshal(responseBytes, &virtualDiskImages) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Virtual_Disk_Image{}, err + } + + return virtualDiskImages, nil +} + +func (slas *softLayer_Account_Service) GetSshKeys() ([]datatypes.SoftLayer_Security_Ssh_Key, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getSshKeys.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getSshKeys, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Security_Ssh_Key{}, errors.New(errorMessage) + } + + sshKeys := []datatypes.SoftLayer_Security_Ssh_Key{} + err = json.Unmarshal(responseBytes, &sshKeys) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + return sshKeys, nil +} + +func (slas *softLayer_Account_Service) GetBlockDeviceTemplateGroups() ([]datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getBlockDeviceTemplateGroups.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getBlockDeviceTemplateGroups, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, errors.New(errorMessage) + } + + vgbdtGroups := []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{} + err = json.Unmarshal(responseBytes, &vgbdtGroups) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + return vgbdtGroups, nil +} + +func (slas *softLayer_Account_Service) GetBlockDeviceTemplateGroupsWithFilter(filters string) ([]datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) { + isJson, err := common.ValidateJson(filters) + if !isJson || err != nil { + errorMessage := fmt.Sprintf("softlayer-go: filters string %s is not a valid Json formatted string, error message '%s'", filters, err.Error()) + return []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, errors.New(errorMessage) + } + + path := fmt.Sprintf("%s/%s", slas.GetName(), "getBlockDeviceTemplateGroups.json") + responseBytes, err := slas.client.DoRawHttpRequestWithObjectFilter(path, filters, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getBlockDeviceTemplateGroups, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, errors.New(errorMessage) + } + + vgbdtGroups := []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{} + err = json.Unmarshal(responseBytes, &vgbdtGroups) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + return vgbdtGroups, nil +} + +func (slas *softLayer_Account_Service) GetDatacentersWithSubnetAllocations() ([]datatypes.SoftLayer_Location, error) { + return []datatypes.SoftLayer_Location{}, nil +} + +func (slas *softLayer_Account_Service) GetHardware() ([]datatypes.SoftLayer_Hardware, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getHardware.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getHardware, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Hardware{}, errors.New(errorMessage) + } + + hardwares := []datatypes.SoftLayer_Hardware{} + err = json.Unmarshal(responseBytes, &hardwares) + + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Hardware{}, err + } + + return hardwares, nil +} + +func (slas *softLayer_Account_Service) GetDnsDomains() ([]datatypes.SoftLayer_Dns_Domain, error) { + path := fmt.Sprintf("%s/%s", slas.GetName(), "getDomains.json") + responseBytes, err := slas.client.DoRawHttpRequest(path, "GET", &bytes.Buffer{}) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: could not SoftLayer_Account#getDomains, error message '%s'", err.Error()) + return []datatypes.SoftLayer_Dns_Domain{}, errors.New(errorMessage) + } + + domains := []datatypes.SoftLayer_Dns_Domain{} + err = json.Unmarshal(responseBytes, &domains) + if err != nil { + errorMessage := fmt.Sprintf("softlayer-go: failed to decode JSON response, err message '%s'", err.Error()) + err := errors.New(errorMessage) + return []datatypes.SoftLayer_Dns_Domain{}, err + } + + return domains, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group.go b/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group.go new file mode 100644 index 000000000..47b6208d0 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group.go @@ -0,0 +1,317 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Virtual_Guest_Block_Device_Template_Group_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service(client softlayer.Client) *softLayer_Virtual_Guest_Block_Device_Template_Group_Service { + return &softLayer_Virtual_Guest_Block_Device_Template_Group_Service{ + client: client, + } +} + +func (slvgs *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetName() string { + return "SoftLayer_Virtual_Guest_Block_Device_Template_Group" +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetObject(id int) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getObject.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + vgbdtGroup := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{} + err = json.Unmarshal(response, &vgbdtGroup) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + return vgbdtGroup, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) DeleteObject(id int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", slvgbdtg.GetName(), id), "DELETE", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + transaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &transaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return transaction, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetDatacenters(id int) ([]datatypes.SoftLayer_Location, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getDatacenters.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Location{}, err + } + + locations := []datatypes.SoftLayer_Location{} + err = json.Unmarshal(response, &locations) + if err != nil { + return []datatypes.SoftLayer_Location{}, err + } + + return locations, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetSshKeys(id int) ([]datatypes.SoftLayer_Security_Ssh_Key, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getSshKeys.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + sshKeys := []datatypes.SoftLayer_Security_Ssh_Key{} + err = json.Unmarshal(response, &sshKeys) + if err != nil { + return []datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + return sshKeys, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetStatus(id int) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getStatus.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status{}, err + } + + status := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status{} + err = json.Unmarshal(response, &status) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status{}, err + } + + return status, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetImageType(id int) (datatypes.SoftLayer_Image_Type, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getImageType.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Image_Type{}, err + } + + imageType := datatypes.SoftLayer_Image_Type{} + err = json.Unmarshal(response, &imageType) + if err != nil { + return datatypes.SoftLayer_Image_Type{}, err + } + + return imageType, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetStorageLocations(id int) ([]datatypes.SoftLayer_Location, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getStorageLocations.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Location{}, err + } + + locations := []datatypes.SoftLayer_Location{} + err = json.Unmarshal(response, &locations) + if err != nil { + return []datatypes.SoftLayer_Location{}, err + } + + return locations, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) CreateFromExternalSource(configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) { + parameters := datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration_Parameters{ + Parameters: []datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration{configuration}, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/createFromExternalSource.json", slvgbdtg.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + vgbdtGroup := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{} + err = json.Unmarshal(response, &vgbdtGroup) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{}, err + } + + return vgbdtGroup, err +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) CopyToExternalSource(configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration) (bool, error) { + parameters := datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration_Parameters{ + Parameters: []datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration{configuration}, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/copyToExternalSource.json", slvgbdtg.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to create virtual guest block device template group, got '%s' as response from the API.", res)) + } + + return true, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetImageTypeKeyName(id int) (string, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getImageTypeKeyName.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + + return string(response), err +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) GetTransaction(id int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getTransaction.json", slvgbdtg.GetName(), id), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + transaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &transaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return transaction, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) DenySharingAccess(id int, accountId int) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameter{ + AccountId: accountId, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/denySharingAccess.json", slvgbdtg.GetName(), id), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to permit sharing access to VGDBTG with ID: %d to account ID: %d", id, accountId)) + } + + return true, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) PermitSharingAccess(id int, accountId int) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_GroupInitParameter{ + AccountId: accountId, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/permitSharingAccess.json", slvgbdtg.GetName(), id), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to permit sharing access to VGDBTG with ID: %d to account ID: %d", id, accountId)) + } + + return true, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) AddLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameter{ + Locations: locations, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/addLocations.json", slvgbdtg.GetName(), id), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to add locations access to VGDBTG with ID: %d", id)) + } + + return true, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) RemoveLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameter{ + Locations: locations, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/removeLocations.json", slvgbdtg.GetName(), id), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to remove locations access to VGDBTG with ID: %d", id)) + } + + return true, nil +} + +func (slvgbdtg *softLayer_Virtual_Guest_Block_Device_Template_Group_Service) SetAvailableLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_LocationsInitParameter{ + Locations: locations, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgbdtg.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/setAvailableLocations.json", slvgbdtg.GetName(), id), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to set available locations access to VGDBTG with ID: %d", id)) + } + + return true, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group_test.go b/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group_test.go new file mode 100644 index 000000000..ac04bb6fd --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softLayer_virtual_guest_block_device_template_group_test.go @@ -0,0 +1,386 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Virtual_Guest_Service", func() { + var ( + username, apiKey string + err error + + fakeClient *slclientfakes.FakeSoftLayerClient + + vgbdtgService softlayer.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service + + vgbdtGroup datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group + + locations []datatypes.SoftLayer_Location + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + vgbdtgService, err = fakeClient.GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(vgbdtgService).ToNot(BeNil()) + + vgbdtGroup = datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group{} + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := vgbdtgService.GetName() + Expect(name).To(Equal("SoftLayer_Virtual_Guest_Block_Device_Template_Group")) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + vgbdtGroup.Id = 200150 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Virtual_Guest_Block_Device_Template_Group instance", func() { + vgbdtg, err := vgbdtgService.GetObject(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(vgbdtg.AccountId).To(Equal(278444)) + Expect(vgbdtg.CreateDate).ToNot(BeNil()) + Expect(vgbdtg.Id).To(Equal(vgbdtGroup.Id)) + Expect(vgbdtg.Name).To(Equal("BOSH-eCPI-packer-centos-2014-08-12T15:54:16Z")) + Expect(vgbdtg.Note).To(Equal("centos image created by packer at 2014-08-12T15:54:16Z")) + Expect(vgbdtg.ParentId).To(BeNil()) + Expect(vgbdtg.PublicFlag).To(Equal(0)) + Expect(vgbdtg.StatusId).To(Equal(1)) + Expect(vgbdtg.Summary).To(Equal("centos image created by packer at 2014-08-12T15:54:16Z")) + Expect(vgbdtg.TransactionId).To(BeNil()) + Expect(vgbdtg.UserRecordId).To(Equal(239954)) + Expect(vgbdtg.GlobalIdentifier).To(Equal("8071601b-5ee1-483e-a9e8-6e5582dcb9f7")) + }) + }) + + Context("#DeleteObject", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_deleteObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully deletes the SoftLayer_Virtual_Guest_Block_Device_Template_Group instance", func() { + transaction, err := vgbdtgService.DeleteObject(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + + Expect(transaction.CreateDate).ToNot(BeNil()) + Expect(transaction.ElapsedSeconds).To(Equal(1)) + Expect(transaction.GuestId).To(Equal(1234567)) + Expect(transaction.HardwareId).To(Equal(0)) + Expect(transaction.Id).To(Equal(11878004)) + Expect(transaction.ModifyDate).ToNot(BeNil()) + Expect(transaction.StatusChangeDate).ToNot(BeNil()) + + Expect(transaction.TransactionGroup).To(Equal(datatypes.TransactionGroup{})) + + Expect(transaction.TransactionStatus.AverageDuration).To(Equal(".42")) + Expect(transaction.TransactionStatus.FriendlyName).To(Equal("Cloud Reclaim Prep")) + Expect(transaction.TransactionStatus.Name).To(Equal("CLOUD_RECLAIM_PREP")) + }) + }) + + Context("#GetDatacenters", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getDatacenters.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves an array of SoftLayer_Location array for virtual guest device template group", func() { + locations, err := vgbdtgService.GetDatacenters(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(locations)).To(BeNumerically("==", 2)) + + Expect(locations[0].Id).To(Equal(265592)) + Expect(locations[0].LongName).To(Equal("Amsterdam 1")) + Expect(locations[0].Name).To(Equal("ams01")) + + Expect(locations[1].Id).To(Equal(154820)) + Expect(locations[1].LongName).To(Equal("Dallas 6")) + Expect(locations[1].Name).To(Equal("dal06")) + }) + }) + + Context("#GetSshKeys", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getSshKeys.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves an array of SoftLayer_Security_Ssh_Key array for virtual guest device template group", func() { + sshKeys, err := vgbdtgService.GetSshKeys(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(sshKeys)).To(BeNumerically(">", 0)) + + for _, sshKey := range sshKeys { + Expect(sshKey.CreateDate).ToNot(BeNil()) + Expect(sshKey.Fingerprint).To(Equal("f6:c2:9d:57:2f:74:be:a1:db:71:f2:e5:8e:0f:84:7e")) + Expect(sshKey.Id).To(Equal(84386)) + Expect(sshKey.Key).ToNot(Equal("")) + Expect(sshKey.Label).To(Equal("TEST:softlayer-go")) + Expect(sshKey.ModifyDate).To(BeNil()) + Expect(sshKey.Label).To(Equal("TEST:softlayer-go")) + } + }) + }) + + Context("#GetStatus", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getStatus.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Virtual_Guest_Block_Device_Template_Group instance status", func() { + status, err := vgbdtgService.GetStatus(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(status.Description).To(Equal("The Guest Block Device Template Group is available to all accounts")) + Expect(status.KeyName).To(Equal("ACTIVE")) + Expect(status.Name).To(Equal("Active")) + }) + }) + + Context("#GetStorageLocations", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getStorageLocations.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Locations for the Virtual_Guest_Block_Device_Template_Group instance", func() { + locations, err := vgbdtgService.GetStorageLocations(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(locations)).To(Equal(18)) + + found := false + for _, location := range locations { + if location.LongName == "Paris 1" { + Expect(location.Id).To(Equal(449500)) + Expect(location.Name).To(Equal("par01")) + found = true + break + } + } + Expect(found).To(BeTrue()) + }) + }) + + Context("#GetImageType", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getImageType.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves the image type for the instance", func() { + imageType, err := vgbdtgService.GetImageType(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(imageType.Description).To(Equal("a disk that may be replaced on upgrade")) + Expect(imageType.KeyName).To(Equal("SYSTEM")) + Expect(imageType.Name).To(Equal("System")) + }) + }) + + Context("#GetImageTypeKeyName", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_getImageTypeKeyName.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves the image type key name for the instance", func() { + imageTypeKeyName, err := vgbdtgService.GetImageTypeKeyName(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(imageTypeKeyName).To(Equal("SYSTEM")) + }) + }) + + Context("#CreateFromExternalSource", func() { + var configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration + + BeforeEach(func() { + configuration = datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration{ + Name: "fake-configuration-name", + Note: "fake-configuration-note", + OperatingSystemReferenceCode: "fake-operating-system-reference-code", + Uri: "swift://FakeObjectStorageAccountName>@fake-clusterName/fake-containerName/fake-fileName.vhd", + } + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_createFromExternalSource.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully creates a virtual guest device templte group from a configuration from an external VHD image", func() { + vgbdtGroup, err := vgbdtgService.CreateFromExternalSource(configuration) + Expect(err).ToNot(HaveOccurred()) + Expect(vgbdtGroup.AccountId).To(Equal(278444)) + Expect(vgbdtGroup.CreateDate).ToNot(BeNil()) + Expect(vgbdtGroup.Id).To(Equal(211582)) + Expect(vgbdtGroup.Name).To(Equal(" ubuntu-10.04-bosh-2168-IEM-itcs104-dea-stemcell")) + Expect(vgbdtGroup.Note).To(Equal("fake-note")) + Expect(*vgbdtGroup.ParentId).To(Equal(211578)) + Expect(vgbdtGroup.PublicFlag).To(Equal(0)) + Expect(vgbdtGroup.StatusId).To(Equal(1)) + Expect(vgbdtGroup.Summary).To(Equal("fake-summary")) + Expect(vgbdtGroup.TransactionId).To(BeNil()) + Expect(vgbdtGroup.UserRecordId).To(Equal(180816)) + Expect(vgbdtGroup.GlobalIdentifier).To(Equal("fake-global-identifier")) + }) + }) + + Context("#CopyToExternalSource", func() { + var configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration + + BeforeEach(func() { + configuration = datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration{ + Name: "fake-configuration-name", + Note: "fake-configuration-note", + OperatingSystemReferenceCode: "fake-operating-system-reference-code", + Uri: "swift://FakeObjectStorageAccountName>@fake-clusterName/fake-containerName/fake-fileName.vhd", + } + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_copyToExternalSource.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("successfully copies the virtual guest device template group to an external source", func() { + copied, err := vgbdtgService.CopyToExternalSource(configuration) + Expect(err).ToNot(HaveOccurred()) + Expect(copied).To(BeTrue()) + }) + }) + + Context("#GetTransaction", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_deleteObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Provisioning_Version1_Transaction for the Virtual_Guest_Block_Device_Template_Group instance", func() { + transaction, err := vgbdtgService.GetTransaction(vgbdtGroup.Id) + Expect(err).ToNot(HaveOccurred()) + + Expect(transaction.TransactionStatus).ToNot(BeNil()) + }) + }) + + Context("#DenySharingAccess", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_denySharingAccess.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully denies sharing access for VGBDTG instance", func() { + denySharing, err := vgbdtgService.DenySharingAccess(vgbdtGroup.Id, 1234567) + Expect(err).ToNot(HaveOccurred()) + + Expect(denySharing).To(BeTrue()) + }) + }) + + Context("#PermitSharingAccess", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_permitSharingAccess.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully permits sharing access for VGBDTG instance", func() { + permitSharing, err := vgbdtgService.PermitSharingAccess(vgbdtGroup.Id, 1234567) + Expect(err).ToNot(HaveOccurred()) + + Expect(permitSharing).To(BeTrue()) + }) + }) + + Context("#XyzLocations", func() { + BeforeEach(func() { + locations = []datatypes.SoftLayer_Location{ + datatypes.SoftLayer_Location{ + Id: 0, + Name: "0", + LongName: "Location 0", + }, + datatypes.SoftLayer_Location{ + Id: 1, + Name: "1", + LongName: "Location 1", + }, + datatypes.SoftLayer_Location{ + Id: 2, + Name: "2", + LongName: "Location 2", + }, + } + }) + + Context("#AddLocations", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_addLocations.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully adds locations to VGBDTG instance", func() { + result, err := vgbdtgService.AddLocations(vgbdtGroup.Id, locations) + Expect(err).ToNot(HaveOccurred()) + + Expect(result).To(BeTrue()) + }) + }) + + Context("#RemoveLocations", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_removeLocations.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully removes locations to VGBDTG instance", func() { + result, err := vgbdtgService.RemoveLocations(vgbdtGroup.Id, locations) + Expect(err).ToNot(HaveOccurred()) + + Expect(result).To(BeTrue()) + }) + }) + + Context("#SetAvailableLocations", func() { + BeforeEach(func() { + vgbdtGroup.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service_setAvailableLocations.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully sets available locations to VGBDTG instance", func() { + result, err := vgbdtgService.SetAvailableLocations(vgbdtGroup.Id, locations) + Expect(err).ToNot(HaveOccurred()) + + Expect(result).To(BeTrue()) + }) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_account_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_account_test.go new file mode 100644 index 000000000..851ece874 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_account_test.go @@ -0,0 +1,213 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Account_Service", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + accountService softlayer.SoftLayer_Account_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + accountService, err = fakeClient.GetSoftLayer_Account_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(accountService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := accountService.GetName() + Expect(name).To(Equal("SoftLayer_Account")) + }) + }) + + Context("#GetAccountStatus", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getAccountStatus.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Account_Status that is Active", func() { + accountStatus, err := accountService.GetAccountStatus() + Expect(err).ToNot(HaveOccurred()) + Expect(accountStatus.Id).ToNot(Equal(0)) + Expect(accountStatus.Name).To(Equal("Active")) + }) + }) + + Context("#GetVirtualGuests", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getVirtualGuests.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Guest", func() { + virtualGuests, err := accountService.GetVirtualGuests() + Expect(err).ToNot(HaveOccurred()) + Expect(virtualGuests).ToNot(BeNil()) + }) + }) + + Context("#GetNetworkStorage", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getNetworkStorage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Network_Storage", func() { + networkStorage, err := accountService.GetNetworkStorage() + Expect(err).ToNot(HaveOccurred()) + Expect(networkStorage).ToNot(BeNil()) + }) + }) + + Context("#GetIscsiNetworkStorage", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getNetworkStorage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Network_Storage", func() { + iscsiNetworkStorage, err := accountService.GetIscsiNetworkStorage() + Expect(err).ToNot(HaveOccurred()) + Expect(iscsiNetworkStorage).ToNot(BeNil()) + }) + }) + + Context("#GetIscsiNetworkStorageWithFilter", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getNetworkStorage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Network_Storage", func() { + iscsiNetworkStorage, err := accountService.GetIscsiNetworkStorageWithFilter("fake-filter") + Expect(err).ToNot(HaveOccurred()) + Expect(iscsiNetworkStorage).ToNot(BeNil()) + }) + }) + + Context("#GetVirtualDiskImages", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getVirtualDiskImages.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Disk_Image", func() { + virtualDiskImages, err := accountService.GetVirtualDiskImages() + Expect(err).ToNot(HaveOccurred()) + Expect(virtualDiskImages).ToNot(BeNil()) + }) + }) + + Context("#GetVirtualDiskImagesWithFilter", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getVirtualDiskImagesWithFilter.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Disk_Image", func() { + virtualDiskImages, err := accountService.GetVirtualDiskImagesWithFilter(`{"correct-filter":"whatever"}`) + Expect(err).ToNot(HaveOccurred()) + Expect(virtualDiskImages).ToNot(BeNil()) + }) + + It("returns an error due to failed Json validation", func() { + _, err := accountService.GetVirtualDiskImagesWithFilter(`{{"wrong-filter":"whatever"}`) + Expect(err).To(HaveOccurred()) + }) + }) + + Context("#GetSshKeys", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getSshKeys.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Ssh_Key", func() { + sshKeys, err := accountService.GetSshKeys() + Expect(err).ToNot(HaveOccurred()) + Expect(sshKeys).ToNot(BeNil()) + }) + }) + + Context("#GetBlockDeviceTemplateGroups", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getBlockDeviceTemplateGroups.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group", func() { + groups, err := accountService.GetBlockDeviceTemplateGroups() + Expect(err).ToNot(HaveOccurred()) + Expect(groups).ToNot(BeNil()) + }) + }) + + Context("#GetBlockDeviceTemplateGroupsWithFilter", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getBlockDeviceTemplateGroups.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group", func() { + groups, err := accountService.GetBlockDeviceTemplateGroupsWithFilter(`{"correct-filter":"whatever"}`) + Expect(err).ToNot(HaveOccurred()) + Expect(groups).ToNot(BeNil()) + }) + It("returns an error due to failed Json validation", func() { + _, err := accountService.GetBlockDeviceTemplateGroupsWithFilter(`{{"wrong-filter":"whatever"}`) + Expect(err).To(HaveOccurred()) + }) + }) + + Context("#GetDatacentersWithSubnetAllocations", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getDatacentersWithSubnetAllocations.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Virtual_Location", func() { + locations, err := accountService.GetBlockDeviceTemplateGroups() + Expect(err).ToNot(HaveOccurred()) + Expect(locations).ToNot(BeNil()) + Expect(len(locations)).To(BeNumerically(">", 0)) + }) + }) + + Context("#GetHardware", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Account_Service_getHardware.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Hardware", func() { + hardwares, err := accountService.GetHardware() + Expect(err).ToNot(HaveOccurred()) + Expect(hardwares).ToNot(BeNil()) + Expect(len(hardwares)).To(BeNumerically(">", 0)) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request.go new file mode 100644 index 000000000..30cbc2922 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request.go @@ -0,0 +1,50 @@ +package services + +import ( + "bytes" + "encoding/json" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Billing_Item_Cancellation_Request_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Billing_Item_Cancellation_Request_Service(client softlayer.Client) *softLayer_Billing_Item_Cancellation_Request_Service { + return &softLayer_Billing_Item_Cancellation_Request_Service{ + client: client, + } +} + +func (slbicr *softLayer_Billing_Item_Cancellation_Request_Service) GetName() string { + return "SoftLayer_Billing_Item_Cancellation_Request" +} + +func (slbicr *softLayer_Billing_Item_Cancellation_Request_Service) CreateObject(request datatypes.SoftLayer_Billing_Item_Cancellation_Request) (datatypes.SoftLayer_Billing_Item_Cancellation_Request, error) { + parameters := datatypes.SoftLayer_Billing_Item_Cancellation_Request_Parameters{ + Parameters: []datatypes.SoftLayer_Billing_Item_Cancellation_Request{ + request, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Billing_Item_Cancellation_Request{}, err + } + + responseBytes, err := slbicr.client.DoRawHttpRequest(fmt.Sprintf("%s/createObject.json", slbicr.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Billing_Item_Cancellation_Request{}, err + } + + result := datatypes.SoftLayer_Billing_Item_Cancellation_Request{} + err = json.Unmarshal(responseBytes, &result) + if err != nil { + return datatypes.SoftLayer_Billing_Item_Cancellation_Request{}, err + } + + return result, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request_test.go new file mode 100644 index 000000000..467850ecc --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_billing_item_cancellation_request_test.go @@ -0,0 +1,64 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Billing_Item_Cancellation_Request", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + billingItemCancellationRequestService softlayer.SoftLayer_Billing_Item_Cancellation_Request_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + billingItemCancellationRequestService, err = fakeClient.GetSoftLayer_Billing_Item_Cancellation_Request_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(billingItemCancellationRequestService).ToNot(BeNil()) + }) + + Context("#GetNam", func() { + It("returns the name for the service", func() { + name := billingItemCancellationRequestService.GetName() + Expect(name).To(Equal("SoftLayer_Billing_Item_Cancellation_Request")) + }) + }) + + Context("#CreateObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Billing_Item_Cancellation_Request_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Network_Storage", func() { + + request := datatypes.SoftLayer_Billing_Item_Cancellation_Request{} + + result, err := billingItemCancellationRequestService.CreateObject(request) + Expect(err).ToNot(HaveOccurred()) + Expect(result.Id).To(Equal(123)) + Expect(result.AccountId).To(Equal(456)) + Expect(result.TicketId).To(Equal(789)) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain.go new file mode 100644 index 000000000..617b82f08 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain.go @@ -0,0 +1,96 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + datatypes "github.com/maximilien/softlayer-go/data_types" + "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Dns_Domain_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Dns_Domain_Service(client softlayer.Client) *softLayer_Dns_Domain_Service { + return &softLayer_Dns_Domain_Service{ + client: client, + } +} + +func (sldds *softLayer_Dns_Domain_Service) GetName() string { + return "SoftLayer_Dns_Domain" +} + +func (sldds *softLayer_Dns_Domain_Service) CreateObject(template datatypes.SoftLayer_Dns_Domain_Template) (datatypes.SoftLayer_Dns_Domain, error) { + if template.ResourceRecords == nil { + template.ResourceRecords = []datatypes.SoftLayer_Dns_Domain_ResourceRecord{} + } + + parameters := datatypes.SoftLayer_Dns_Domain_Template_Parameters{ + Parameters: []datatypes.SoftLayer_Dns_Domain_Template{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + response, err := sldds.client.DoRawHttpRequest(fmt.Sprintf("%s.json", sldds.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + err = sldds.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + softLayer_Dns_Domain := datatypes.SoftLayer_Dns_Domain{} + err = json.Unmarshal(response, &softLayer_Dns_Domain) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + return softLayer_Dns_Domain, nil +} + +func (sldds *softLayer_Dns_Domain_Service) GetObject(dnsId int) (datatypes.SoftLayer_Dns_Domain, error) { + objectMask := []string{ + "id", + "name", + "serial", + "updateDate", + "account", + "managedResourceFlag", + "resourceRecordCount", + "resourceRecords", + "secondary", + } + + response, err := sldds.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getObject.json", sldds.GetName(), dnsId), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + dns_domain := datatypes.SoftLayer_Dns_Domain{} + err = json.Unmarshal(response, &dns_domain) + if err != nil { + return datatypes.SoftLayer_Dns_Domain{}, err + } + + return dns_domain, nil +} + +func (sldds *softLayer_Dns_Domain_Service) DeleteObject(dnsId int) (bool, error) { + response, err := sldds.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", sldds.GetName(), dnsId), "DELETE", new(bytes.Buffer)) + + if response_value := string(response[:]); response_value != "true" { + return false, errors.New(fmt.Sprintf("Failed to delete dns domain with id '%d', got '%s' as response from the API", dnsId, response_value)) + } + + return true, err +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record.go new file mode 100644 index 000000000..ee53ea64a --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record.go @@ -0,0 +1,141 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type SoftLayer_Dns_Domain_ResourceRecord_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Dns_Domain_ResourceRecord_Service(client softlayer.Client) *SoftLayer_Dns_Domain_ResourceRecord_Service { + return &SoftLayer_Dns_Domain_ResourceRecord_Service{ + client: client, + } +} + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) GetName() string { + return "SoftLayer_Dns_Domain_ResourceRecord" +} + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) CreateObject(template datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template) (datatypes.SoftLayer_Dns_Domain_ResourceRecord, error) { + parameters := datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template_Parameters{ + Parameters: []datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + response, err := sldr.client.DoRawHttpRequest(fmt.Sprintf("%s/createObject", sldr.getNameByType(template.Type)), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + err = sldr.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + dns_record := datatypes.SoftLayer_Dns_Domain_ResourceRecord{} + err = json.Unmarshal(response, &dns_record) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + return dns_record, nil +} + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) GetObject(id int) (datatypes.SoftLayer_Dns_Domain_ResourceRecord, error) { + objectMask := []string{ + "data", + "domainId", + "expire", + "host", + "id", + "minimum", + "mxPriority", + "refresh", + "responsiblePerson", + "retry", + "ttl", + "type", + "service", + "priority", + "protocol", + "port", + "weight", + } + + response, err := sldr.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getObject.json", sldr.GetName(), id), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + err = sldr.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + dns_record := datatypes.SoftLayer_Dns_Domain_ResourceRecord{} + err = json.Unmarshal(response, &dns_record) + if err != nil { + return datatypes.SoftLayer_Dns_Domain_ResourceRecord{}, err + } + + return dns_record, nil +} + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) DeleteObject(recordId int) (bool, error) { + response, err := sldr.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", sldr.GetName(), recordId), "DELETE", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to delete DNS Domain Record with id '%d', got '%s' as response from the API.", recordId, res)) + } + + return true, err +} + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) EditObject(recordId int, template datatypes.SoftLayer_Dns_Domain_ResourceRecord) (bool, error) { + parameters := datatypes.SoftLayer_Dns_Domain_ResourceRecord_Parameters{ + Parameters: []datatypes.SoftLayer_Dns_Domain_ResourceRecord{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := sldr.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/editObject.json", sldr.getNameByType(template.Type), recordId), "POST", bytes.NewBuffer(requestBody)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to edit DNS Domain Record with id: %d, got '%s' as response from the API.", recordId, res)) + } + + return true, err +} + +//Private methods + +func (sldr *SoftLayer_Dns_Domain_ResourceRecord_Service) getNameByType(dnsType string) string { + switch dnsType { + case "srv": + // Currently only SRV record type requires additional fields for Create and Update, while all other record types + // use basic default resource type. Therefore there is no need for now to implement each resource type as separate service + // https://sldn.softlayer.com/reference/datatypes/SoftLayer_Dns_Domain_ResourceRecord_SrvType + return "SoftLayer_Dns_Domain_ResourceRecord_SrvType" + default: + return "SoftLayer_Dns_Domain_ResourceRecord" + } +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record_test.go new file mode 100644 index 000000000..3f8f31f7d --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_resource_record_test.go @@ -0,0 +1,144 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Dns_Domain_Record", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + dnsDomainResourceRecordService softlayer.SoftLayer_Dns_Domain_ResourceRecord_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + dnsDomainResourceRecordService, err = fakeClient.GetSoftLayer_Dns_Domain_ResourceRecord_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(dnsDomainResourceRecordService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := dnsDomainResourceRecordService.GetName() + Expect(name).To(Equal("SoftLayer_Dns_Domain_ResourceRecord")) + }) + }) + + Context("#CreateObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Dns_Domain_ResourceRecord_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("creates a new SoftLayer_Dns_Domain_Record", func() { + template := datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template{ + Data: "testData", + DomainId: 123, + Expire: 99999, + Host: "testHost.com", + Id: 111, + Minimum: 1, + MxPriority: 9, + Refresh: 100, + ResponsiblePerson: "someTestPerson", + Retry: 444, + Ttl: 222, + Type: "someTestType", + } + + result, err := dnsDomainResourceRecordService.CreateObject(template) + Expect(err).ToNot(HaveOccurred()) + Expect(result.Data).To(Equal("testData")) + Expect(result.DomainId).To(Equal(123)) + Expect(result.Expire).To(Equal(99999)) + Expect(result.Host).To(Equal("testHost.com")) + Expect(result.Id).To(Equal(111)) + Expect(result.Minimum).To(Equal(1)) + Expect(result.MxPriority).To(Equal(9)) + Expect(result.Refresh).To(Equal(100)) + Expect(result.ResponsiblePerson).To(Equal("someTestPerson")) + Expect(result.Retry).To(Equal(444)) + Expect(result.Ttl).To(Equal(222)) + Expect(result.Type).To(Equal("someTestType")) + }) + + It("fails to create a resource record without mandatory parameters", func() { + fakeClient.DoRawHttpRequestResponse = []byte("fake") + + template := datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template{ + Data: "testData", + } + + _, err := dnsDomainResourceRecordService.CreateObject(template) + Expect(err).To(HaveOccurred()) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Dns_Domain_ResourceRecord_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Dns_Domain_Record instance", func() { + result, err := dnsDomainResourceRecordService.GetObject(111) + Expect(err).ToNot(HaveOccurred()) + Expect(result.Data).To(Equal("testData")) + Expect(result.DomainId).To(Equal(123)) + Expect(result.Expire).To(Equal(99999)) + Expect(result.Host).To(Equal("testHost.com")) + Expect(result.Id).To(Equal(111)) + Expect(result.Minimum).To(Equal(1)) + Expect(result.MxPriority).To(Equal(9)) + Expect(result.Refresh).To(Equal(100)) + Expect(result.ResponsiblePerson).To(Equal("someTestPerson")) + Expect(result.Retry).To(Equal(444)) + Expect(result.Ttl).To(Equal(222)) + Expect(result.Type).To(Equal("someTestType")) + }) + }) + + Context("#EditObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Dns_Domain_ResourceRecord_Service_editObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("applies changes to the existing SoftLayer_Dns_Domain_Record instance", func() { + result, err := dnsDomainResourceRecordService.GetObject(112) + Expect(err).ToNot(HaveOccurred()) + Expect(result.Data).To(Equal("changedData")) + Expect(result.DomainId).To(Equal(124)) + Expect(result.Expire).To(Equal(99998)) + Expect(result.Host).To(Equal("changedHost.com")) + Expect(result.Id).To(Equal(112)) + Expect(result.Minimum).To(Equal(2)) + Expect(result.MxPriority).To(Equal(8)) + Expect(result.Refresh).To(Equal(101)) + Expect(result.ResponsiblePerson).To(Equal("changedTestPerson")) + Expect(result.Retry).To(Equal(445)) + Expect(result.Ttl).To(Equal(223)) + Expect(result.Type).To(Equal("changedTestType")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_test.go new file mode 100644 index 000000000..317fe1b84 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_dns_domain_test.go @@ -0,0 +1,63 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Dns_Domain", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + dnsDomainService softlayer.SoftLayer_Dns_Domain_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).NotTo(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).NotTo(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).NotTo(BeNil()) + + dnsDomainService, err = fakeClient.GetSoftLayer_Dns_Domain_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(dnsDomainService).NotTo(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := dnsDomainService.GetName() + Expect(name).To(Equal("SoftLayer_Dns_Domain")) + }) + }) + + Context("#CreateDns", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Dns_Domain_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Dns_Domain", func() { + dns, err := dnsDomainService.CreateObject(datatypes.SoftLayer_Dns_Domain_Template{}) + Expect(err).ToNot(HaveOccurred()) + Expect(dns).NotTo(BeNil()) + Expect(dns.Id).NotTo(BeNil()) + Expect(dns.Serial).NotTo(BeNil()) + Expect(dns.UpdateDate).NotTo(BeNil()) + Expect(dns.Name).To(Equal("qwerty123ff.com")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware.go new file mode 100644 index 000000000..3034506f4 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware.go @@ -0,0 +1,89 @@ +package services + +import ( + "bytes" + "encoding/json" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Hardware_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Hardware_Service(client softlayer.Client) *softLayer_Hardware_Service { + return &softLayer_Hardware_Service{ + client: client, + } +} + +func (slhs *softLayer_Hardware_Service) GetName() string { + return "SoftLayer_Hardware" +} + +func (slhs *softLayer_Hardware_Service) CreateObject(template datatypes.SoftLayer_Hardware_Template) (datatypes.SoftLayer_Hardware, error) { + parameters := datatypes.SoftLayer_Hardware_Template_Parameters{ + Parameters: []datatypes.SoftLayer_Hardware_Template{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + response, err := slhs.client.DoRawHttpRequest(fmt.Sprintf("%s.json", slhs.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + err = slhs.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + bare_metal_server := datatypes.SoftLayer_Hardware{} + err = json.Unmarshal(response, &bare_metal_server) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + return bare_metal_server, nil +} + +func (slhs *softLayer_Hardware_Service) GetObject(id string) (datatypes.SoftLayer_Hardware, error) { + + objectMask := []string{ + "bareMetalInstanceFlag", + "domain", + "hostname", + "id", + "hardwareStatusId", + "provisionDate", + "globalIdentifier", + "primaryIpAddress", + "operatingSystem.passwords.password", + "operatingSystem.passwords.username", + } + + response, err := slhs.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%s.json", slhs.GetName(), id), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + err = slhs.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + bare_metal_server := datatypes.SoftLayer_Hardware{} + err = json.Unmarshal(response, &bare_metal_server) + if err != nil { + return datatypes.SoftLayer_Hardware{}, err + } + + return bare_metal_server, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware_test.go new file mode 100644 index 000000000..75a09eae1 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_hardware_test.go @@ -0,0 +1,92 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Hardware", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + hardwareService softlayer.SoftLayer_Hardware_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + hardwareService, err = fakeClient.GetSoftLayer_Hardware_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(hardwareService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := hardwareService.GetName() + Expect(name).To(Equal("SoftLayer_Hardware")) + }) + }) + + Context("#CreateObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Hardware_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("creates a new SoftLayer_Virtual_Guest instance", func() { + template := datatypes.SoftLayer_Hardware_Template{ + Hostname: "softlayer", + Domain: "testing.com", + ProcessorCoreAmount: 2, + MemoryCapacity: 2, + HourlyBillingFlag: true, + OperatingSystemReferenceCode: "UBUNTU_LATEST", + Datacenter: &datatypes.Datacenter{ + Name: "ams01", + }, + } + + hardware, err := hardwareService.CreateObject(template) + Expect(err).ToNot(HaveOccurred()) + Expect(hardware.Id).To(Equal(123)) + Expect(hardware.Hostname).To(Equal("softlayer")) + Expect(hardware.Domain).To(Equal("testing.com")) + Expect(hardware.BareMetalInstanceFlag).To(Equal(1)) + Expect(hardware.GlobalIdentifier).To(Equal("abcdefg")) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Hardware_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Virtual_Guest instance", func() { + hardware, err := hardwareService.GetObject("abcdefg") + Expect(err).ToNot(HaveOccurred()) + Expect(hardware.Id).To(Equal(123)) + Expect(hardware.Hostname).To(Equal("softlayer")) + Expect(hardware.Domain).To(Equal("testing.com")) + Expect(hardware.BareMetalInstanceFlag).To(Equal(1)) + Expect(hardware.GlobalIdentifier).To(Equal("abcdefg")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage.go new file mode 100644 index 000000000..42995f072 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage.go @@ -0,0 +1,324 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + "time" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +const ( + NETWORK_PERFORMANCE_STORAGE_PACKAGE_ID = 222 + BLOCK_ITEM_PRICE_ID = 40678 // file or block item price id + CREATE_ISCSI_VOLUME_MAX_RETRY_TIME = 60 + CREATE_ISCSI_VOLUME_CHECK_INTERVAL = 5 // seconds +) + +type softLayer_Network_Storage_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Network_Storage_Service(client softlayer.Client) *softLayer_Network_Storage_Service { + return &softLayer_Network_Storage_Service{ + client: client, + } +} + +func (slns *softLayer_Network_Storage_Service) GetName() string { + return "SoftLayer_Network_Storage" +} + +func (slns *softLayer_Network_Storage_Service) CreateIscsiVolume(size int, location string) (datatypes.SoftLayer_Network_Storage, error) { + if size < 0 { + return datatypes.SoftLayer_Network_Storage{}, errors.New("Cannot create negative sized volumes") + } + + sizeItemPriceId, err := slns.getIscsiVolumeItemIdBasedOnSize(size) + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + iopsItemPriceId := slns.getPerformanceStorageItemPriceIdByIops(size) + + order := datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi{ + Location: location, + ComplexType: "SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi", + OsFormatType: datatypes.SoftLayer_Network_Storage_Iscsi_OS_Type{ + Id: 12, + KeyName: "LINUX", + }, + Prices: []datatypes.SoftLayer_Product_Item_Price{ + datatypes.SoftLayer_Product_Item_Price{ + Id: sizeItemPriceId, + }, + datatypes.SoftLayer_Product_Item_Price{ + Id: iopsItemPriceId, + }, + datatypes.SoftLayer_Product_Item_Price{ + Id: BLOCK_ITEM_PRICE_ID, + }, + }, + PackageId: NETWORK_PERFORMANCE_STORAGE_PACKAGE_ID, + Quantity: 1, + } + + productOrderService, err := slns.client.GetSoftLayer_Product_Order_Service() + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + receipt, err := productOrderService.PlaceContainerOrderNetworkPerformanceStorageIscsi(order) + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + var iscsiStorage datatypes.SoftLayer_Network_Storage + + for i := 0; i < CREATE_ISCSI_VOLUME_MAX_RETRY_TIME; i++ { + iscsiStorage, err = slns.findIscsiVolumeId(receipt.OrderId) + if err == nil { + break + } else if i == CREATE_ISCSI_VOLUME_MAX_RETRY_TIME-1 { + return datatypes.SoftLayer_Network_Storage{}, err + } + + time.Sleep(CREATE_ISCSI_VOLUME_CHECK_INTERVAL * time.Second) + } + + return iscsiStorage, nil +} + +func (slvgs *softLayer_Network_Storage_Service) DeleteObject(volumeId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", slvgs.GetName(), volumeId), "DELETE", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to delete volume with id '%d', got '%s' as response from the API.", volumeId, res)) + } + + return true, err +} + +func (slns *softLayer_Network_Storage_Service) DeleteIscsiVolume(volumeId int, immediateCancellationFlag bool) error { + ObjectFilter := string(`{"iscsiNetworkStorage":{"id":{"operation":` + strconv.Itoa(volumeId) + `}}}`) + + accountService, err := slns.client.GetSoftLayer_Account_Service() + if err != nil { + return err + } + + iscsiStorages, err := accountService.GetIscsiNetworkStorageWithFilter(ObjectFilter) + if err != nil { + return err + } + + var accountId, billingItemId int + + for i := 0; i < len(iscsiStorages); i++ { + if iscsiStorages[i].Id == volumeId { + accountId = iscsiStorages[i].AccountId + if reflect.ValueOf(iscsiStorages[i].BillingItem).IsNil() { + deleted, err := slns.DeleteObject(volumeId) + if err != nil { + return err + } + if deleted { + return nil + } else { + return errors.New(fmt.Sprintf("Cannot delete volume %d from client at present", volumeId)) + } + } else { + billingItemId = iscsiStorages[i].BillingItem.Id + break + } + } + } + + billingItemCancellationRequest := datatypes.SoftLayer_Billing_Item_Cancellation_Request{ + ComplexType: "SoftLayer_Billing_Item_Cancellation_Request", + AccountId: accountId, + Items: []datatypes.SoftLayer_Billing_Item_Cancellation_Request_Item{ + { + BillingItemId: billingItemId, + ImmediateCancellationFlag: immediateCancellationFlag, + }, + }, + } + + billingItemCancellationRequestService, err := slns.client.GetSoftLayer_Billing_Item_Cancellation_Request_Service() + if err != nil { + return err + } + + _, err = billingItemCancellationRequestService.CreateObject(billingItemCancellationRequest) + if err != nil { + return err + } + + return nil +} + +func (slns *softLayer_Network_Storage_Service) GetIscsiVolume(volumeId int) (datatypes.SoftLayer_Network_Storage, error) { + objectMask := []string{ + "accountId", + "capacityGb", + "createDate", + "guestId", + "hardwareId", + "hostId", + "id", + "nasType", + "notes", + "Password", + "serviceProviderId", + "upgradableFlag", + "username", + "billingItem.id", + "billingItem.orderItem.order.id", + "lunId", + "serviceResourceBackendIpAddress", + } + + response, err := slns.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getObject.json", slns.GetName(), volumeId), objectMask, "GET", new(bytes.Buffer)) + + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + volume := datatypes.SoftLayer_Network_Storage{} + err = json.Unmarshal(response, &volume) + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + return volume, nil +} + +func (slns *softLayer_Network_Storage_Service) HasAllowedVirtualGuest(volumeId int, vmId int) (bool, error) { + filter := string(`{"allowedVirtualGuests":{"id":{"operation":"` + strconv.Itoa(vmId) + `"}}}`) + response, err := slns.client.DoRawHttpRequestWithObjectFilterAndObjectMask(fmt.Sprintf("%s/%d/getAllowedVirtualGuests.json", slns.GetName(), volumeId), []string{"id"}, fmt.Sprintf(string(filter)), "GET", new(bytes.Buffer)) + + if err != nil { + return false, errors.New(fmt.Sprintf("Cannot check authentication for volume %d in vm %d", volumeId, vmId)) + } + + virtualGuest := []datatypes.SoftLayer_Virtual_Guest{} + err = json.Unmarshal(response, &virtualGuest) + if err != nil { + return false, errors.New(fmt.Sprintf("Failed to unmarshal response of checking authentication for volume %d in vm %d", volumeId, vmId)) + } + + if len(virtualGuest) > 0 { + return true, nil + } + + return false, nil +} + +func (slns *softLayer_Network_Storage_Service) AttachIscsiVolume(virtualGuest datatypes.SoftLayer_Virtual_Guest, volumeId int) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Parameters{ + Parameters: []datatypes.SoftLayer_Virtual_Guest{ + virtualGuest, + }, + } + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + resp, err := slns.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/allowAccessFromVirtualGuest.json", slns.GetName(), volumeId), "PUT", bytes.NewBuffer(requestBody)) + + allowable, err := strconv.ParseBool(string(resp[:])) + if err != nil { + return false, nil + } + + return allowable, nil +} + +func (slns *softLayer_Network_Storage_Service) DetachIscsiVolume(virtualGuest datatypes.SoftLayer_Virtual_Guest, volumeId int) error { + parameters := datatypes.SoftLayer_Virtual_Guest_Parameters{ + Parameters: []datatypes.SoftLayer_Virtual_Guest{ + virtualGuest, + }, + } + requestBody, err := json.Marshal(parameters) + if err != nil { + return err + } + + _, err = slns.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/removeAccessFromVirtualGuest.json", slns.GetName(), volumeId), "PUT", bytes.NewBuffer(requestBody)) + if err != nil { + return err + } + + return nil +} + +// Private methods + +func (slns *softLayer_Network_Storage_Service) findIscsiVolumeId(orderId int) (datatypes.SoftLayer_Network_Storage, error) { + ObjectFilter := string(`{"iscsiNetworkStorage":{"billingItem":{"orderItem":{"order":{"id":{"operation":` + strconv.Itoa(orderId) + `}}}}}}`) + + accountService, err := slns.client.GetSoftLayer_Account_Service() + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + iscsiStorages, err := accountService.GetIscsiNetworkStorageWithFilter(ObjectFilter) + if err != nil { + return datatypes.SoftLayer_Network_Storage{}, err + } + + if len(iscsiStorages) == 1 { + return iscsiStorages[0], nil + } + + return datatypes.SoftLayer_Network_Storage{}, errors.New(fmt.Sprintf("Cannot find an performance storage (iSCSI volume) with order id %d", orderId)) +} + +func (slns *softLayer_Network_Storage_Service) getIscsiVolumeItemIdBasedOnSize(size int) (int, error) { + productPackageService, err := slns.client.GetSoftLayer_Product_Package_Service() + if err != nil { + return 0, err + } + + itemPrices, err := productPackageService.GetItemPricesBySize(NETWORK_PERFORMANCE_STORAGE_PACKAGE_ID, size) + if err != nil { + return 0, err + } + + var currentItemId int + + if len(itemPrices) > 0 { + for _, itemPrice := range itemPrices { + if itemPrice.LocationGroupId == 0 { + currentItemId = itemPrice.Id + } + } + } + + if currentItemId == 0 { + return 0, errors.New(fmt.Sprintf("No proper performance storage (iSCSI volume)for size %d", size)) + } + + return currentItemId, nil +} + +func (slns *softLayer_Network_Storage_Service) getPerformanceStorageItemPriceIdByIops(size int) int { + switch size { + case 20: + return 40838 // 500 IOPS + case 40: + return 40988 // 1000 IOPS + case 80: + return 41288 // 2000 IOPS + default: + return 41788 // 3000 IOPS + } +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host.go new file mode 100644 index 000000000..9821b9112 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host.go @@ -0,0 +1,40 @@ +package services + +import ( + "bytes" + "encoding/json" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Network_Storage_Allowed_Host_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Network_Storage_Allowed_Host_Service(client softlayer.Client) *softLayer_Network_Storage_Allowed_Host_Service { + return &softLayer_Network_Storage_Allowed_Host_Service{ + client: client, + } +} + +func (slns *softLayer_Network_Storage_Allowed_Host_Service) GetName() string { + return "SoftLayer_Network_Storage_Allowed_Host" +} + +func (slns *softLayer_Network_Storage_Allowed_Host_Service) GetCredential(allowedHostId int) (datatypes.SoftLayer_Network_Storage_Credential, error) { + + response, err := slns.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getCredential.json", slns.GetName(), allowedHostId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Network_Storage_Credential{}, err + } + + credential := datatypes.SoftLayer_Network_Storage_Credential{} + err = json.Unmarshal(response, &credential) + if err != nil { + return datatypes.SoftLayer_Network_Storage_Credential{}, err + } + + return credential, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host_test.go new file mode 100644 index 000000000..3e710edf4 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_allowed_host_test.go @@ -0,0 +1,60 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Network_Storage_Allowed_Host", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + networkStorageAllowedHostService softlayer.SoftLayer_Network_Storage_Allowed_Host_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + networkStorageAllowedHostService, err = fakeClient.GetSoftLayer_Network_Storage_Allowed_Host_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(networkStorageAllowedHostService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := networkStorageAllowedHostService.GetName() + Expect(name).To(Equal("SoftLayer_Network_Storage_Allowed_Host")) + }) + }) + + Context("#GetCredential", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Network_Storage_Allowed_Host_Service_getCredential.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("return the credential with allowed host id", func() { + credential, err := networkStorageAllowedHostService.GetCredential(123456) + Expect(err).NotTo(HaveOccurred()) + Expect(credential).ToNot(BeNil()) + Expect(credential.Username).To(Equal("fake-username")) + Expect(credential.Password).To(Equal("fake-password")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_test.go new file mode 100644 index 000000000..4d4d84136 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_network_storage_test.go @@ -0,0 +1,159 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Network_Storage", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + volume datatypes.SoftLayer_Network_Storage + networkStorageService softlayer.SoftLayer_Network_Storage_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + networkStorageService, err = fakeClient.GetSoftLayer_Network_Storage_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(networkStorageService).ToNot(BeNil()) + + volume = datatypes.SoftLayer_Network_Storage{} + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := networkStorageService.GetName() + Expect(name).To(Equal("SoftLayer_Network_Storage")) + }) + }) + + Context("#CreateIscsiVolume", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Network_Storage_Service_getIscsiVolume.json") + Expect(err).ToNot(HaveOccurred()) + }) + It("fails with error if the volume size is negative", func() { + volume, err = networkStorageService.CreateIscsiVolume(-1, "fake-location") + Expect(err).To(HaveOccurred()) + }) + }) + + Context("#GetIscsiVolume", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Network_Storage_Service_getIscsiVolume.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns the iSCSI volume object based on volume id", func() { + volume, err = networkStorageService.GetIscsiVolume(1) + Expect(err).ToNot(HaveOccurred()) + Expect(volume.Id).To(Equal(1)) + Expect(volume.Username).To(Equal("test_username")) + Expect(volume.Password).To(Equal("test_password")) + Expect(volume.CapacityGb).To(Equal(20)) + Expect(volume.ServiceResourceBackendIpAddress).To(Equal("1.1.1.1")) + }) + }) + + Context("#HasAllowedVirtualGuest", func() { + It("virtual guest allows to access volume", func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Network_Storage_Service_getAllowedVirtualGuests.json") + Expect(err).ToNot(HaveOccurred()) + _, err := networkStorageService.HasAllowedVirtualGuest(123, 456) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + Context("#AttachIscsiVolume", func() { + It("Allow access to storage from virutal guest", func() { + virtualGuest := datatypes.SoftLayer_Virtual_Guest{ + AccountId: 123456, + DedicatedAccountHostOnlyFlag: false, + Domain: "softlayer.com", + FullyQualifiedDomainName: "fake.softlayer.com", + Hostname: "fake-hostname", + Id: 1234567, + MaxCpu: 2, + MaxCpuUnits: "CORE", + MaxMemory: 1024, + StartCpus: 2, + StatusId: 1001, + Uuid: "fake-uuid", + GlobalIdentifier: "fake-globalIdentifier", + PrimaryBackendIpAddress: "fake-primary-backend-ip", + PrimaryIpAddress: "fake-primary-ip", + } + fakeClient.DoRawHttpRequestResponse = []byte("true") + resp, err := networkStorageService.AttachIscsiVolume(virtualGuest, 123) + Expect(err).ToNot(HaveOccurred()) + Expect(resp).To(Equal(true)) + }) + }) + + Context("#DetachIscsiVolume", func() { + It("Revoke access to storage from virtual guest", func() { + virtualGuest := datatypes.SoftLayer_Virtual_Guest{ + AccountId: 123456, + DedicatedAccountHostOnlyFlag: false, + Domain: "softlayer.com", + FullyQualifiedDomainName: "fake.softlayer.com", + Hostname: "fake-hostname", + Id: 1234567, + MaxCpu: 2, + MaxCpuUnits: "CORE", + MaxMemory: 1024, + StartCpus: 2, + StatusId: 1001, + Uuid: "fake-uuid", + GlobalIdentifier: "fake-globalIdentifier", + PrimaryBackendIpAddress: "fake-primary-backend-ip", + PrimaryIpAddress: "fake-primary-ip", + } + volume.Id = 1234567 + fakeClient.DoRawHttpRequestResponse = []byte("true") + err = networkStorageService.DetachIscsiVolume(virtualGuest, volume.Id) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + Context("#DeleteObject", func() { + BeforeEach(func() { + volume.Id = 1234567 + }) + + It("sucessfully deletes the SoftLayer_Network_Storage volume", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + deleted, err := networkStorageService.DeleteObject(volume.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(deleted).To(BeTrue()) + }) + + It("fails to delete the SoftLayer_Network_Storage volume", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + deleted, err := networkStorageService.DeleteObject(volume.Id) + Expect(err).To(HaveOccurred()) + Expect(deleted).To(BeFalse()) + }) + }) + +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order.go new file mode 100644 index 000000000..21098d26f --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order.go @@ -0,0 +1,102 @@ +package services + +import ( + "bytes" + "encoding/json" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Product_Order_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Product_Order_Service(client softlayer.Client) *softLayer_Product_Order_Service { + return &softLayer_Product_Order_Service{ + client: client, + } +} + +func (slpo *softLayer_Product_Order_Service) GetName() string { + return "SoftLayer_Product_Order" +} + +func (slpo *softLayer_Product_Order_Service) PlaceOrder(order datatypes.SoftLayer_Container_Product_Order) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) { + parameters := datatypes.SoftLayer_Container_Product_Order_Parameters{ + Parameters: []datatypes.SoftLayer_Container_Product_Order{ + order, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + responseBytes, err := slpo.client.DoRawHttpRequest(fmt.Sprintf("%s/placeOrder.json", slpo.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + receipt := datatypes.SoftLayer_Container_Product_Order_Receipt{} + err = json.Unmarshal(responseBytes, &receipt) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + return receipt, nil +} + +func (slpo *softLayer_Product_Order_Service) PlaceContainerOrderNetworkPerformanceStorageIscsi(order datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) { + parameters := datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi_Parameters{ + Parameters: []datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi{ + order, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + responseBytes, err := slpo.client.DoRawHttpRequest(fmt.Sprintf("%s/placeOrder.json", slpo.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + receipt := datatypes.SoftLayer_Container_Product_Order_Receipt{} + err = json.Unmarshal(responseBytes, &receipt) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + return receipt, nil +} + +func (slpo *softLayer_Product_Order_Service) PlaceContainerOrderVirtualGuestUpgrade(order datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) { + parameters := datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade_Parameters{ + Parameters: []datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade{ + order, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + responseBytes, err := slpo.client.DoRawHttpRequest(fmt.Sprintf("%s/placeOrder.json", slpo.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + receipt := datatypes.SoftLayer_Container_Product_Order_Receipt{} + err = json.Unmarshal(responseBytes, &receipt) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + return receipt, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order_test.go new file mode 100644 index 000000000..998d0e108 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_order_test.go @@ -0,0 +1,88 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Product_Order", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + productOrderService softlayer.SoftLayer_Product_Order_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + productOrderService, err = fakeClient.GetSoftLayer_Product_Order_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(productOrderService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := productOrderService.GetName() + Expect(name).To(Equal("SoftLayer_Product_Order")) + }) + }) + + Context("#PlaceOrder", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Container_Product_Order_Receipt", func() { + receipt, err := productOrderService.PlaceOrder(datatypes.SoftLayer_Container_Product_Order{}) + Expect(err).ToNot(HaveOccurred()) + Expect(receipt).ToNot(BeNil()) + Expect(receipt.OrderId).To(Equal(123)) + }) + }) + + Context("#PlaceContainerOrderNetworkPerformanceStorageIscsi", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Container_Product_Order_Receipt", func() { + receipt, err := productOrderService.PlaceContainerOrderNetworkPerformanceStorageIscsi(datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi{}) + Expect(err).ToNot(HaveOccurred()) + Expect(receipt).ToNot(BeNil()) + Expect(receipt.OrderId).To(Equal(123)) + }) + }) + + Context("#PlaceContainerOrderVirtualGuestUpgrade", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an instance of datatypes.SoftLayer_Container_Product_Order_Receipt", func() { + receipt, err := productOrderService.PlaceContainerOrderVirtualGuestUpgrade(datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade{}) + Expect(err).ToNot(HaveOccurred()) + Expect(receipt).ToNot(BeNil()) + Expect(receipt.OrderId).To(Equal(123)) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package.go new file mode 100644 index 000000000..63ca47509 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package.go @@ -0,0 +1,153 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +const ( + OUTLET_PACKAGE = "OUTLET" +) + +type softLayer_Product_Package_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Product_Package_Service(client softlayer.Client) *softLayer_Product_Package_Service { + return &softLayer_Product_Package_Service{ + client: client, + } +} + +func (slpp *softLayer_Product_Package_Service) GetName() string { + return "SoftLayer_Product_Package" +} + +func (slpp *softLayer_Product_Package_Service) GetItemPrices(packageId int) ([]datatypes.SoftLayer_Product_Item_Price, error) { + response, err := slpp.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getItemPrices.json", slpp.GetName(), packageId), []string{"id", "item.id", "item.description", "item.capacity"}, "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + itemPrices := []datatypes.SoftLayer_Product_Item_Price{} + err = json.Unmarshal(response, &itemPrices) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + return itemPrices, nil +} + +func (slpp *softLayer_Product_Package_Service) GetItemPricesBySize(packageId int, size int) ([]datatypes.SoftLayer_Product_Item_Price, error) { + keyName := strconv.Itoa(size) + "_GB_PERFORMANCE_STORAGE_SPACE" + filter := string(`{"itemPrices":{"item":{"keyName":{"operation":"` + keyName + `"}}}}`) + + response, err := slpp.client.DoRawHttpRequestWithObjectFilterAndObjectMask(fmt.Sprintf("%s/%d/getItemPrices.json", slpp.GetName(), packageId), []string{"id", "locationGroupId", "item.id", "item.keyName", "item.units", "item.description", "item.capacity"}, fmt.Sprintf(string(filter)), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + itemPrices := []datatypes.SoftLayer_Product_Item_Price{} + err = json.Unmarshal(response, &itemPrices) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + return itemPrices, nil +} + +func (slpp *softLayer_Product_Package_Service) GetItemsByType(packageType string) ([]datatypes.SoftLayer_Product_Item, error) { + productPackage, err := slpp.GetOnePackageByType(packageType) + if err != nil { + return []datatypes.SoftLayer_Product_Item{}, err + } + + return slpp.GetItems(productPackage.Id) +} + +func (slpp *softLayer_Product_Package_Service) GetItems(packageId int) ([]datatypes.SoftLayer_Product_Item, error) { + objectMasks := []string{ + "id", + "capacity", + "description", + "prices.id", + "prices.categories.id", + "prices.categories.name", + } + + response, err := slpp.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getItems.json", slpp.GetName(), packageId), objectMasks, "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Product_Item{}, err + } + + productItems := []datatypes.SoftLayer_Product_Item{} + err = json.Unmarshal(response, &productItems) + if err != nil { + return []datatypes.SoftLayer_Product_Item{}, err + } + + return productItems, nil +} + +func (slpp *softLayer_Product_Package_Service) GetOnePackageByType(packageType string) (datatypes.Softlayer_Product_Package, error) { + productPackages, err := slpp.GetPackagesByType(packageType) + if err != nil { + return datatypes.Softlayer_Product_Package{}, err + } + + if len(productPackages) == 0 { + return datatypes.Softlayer_Product_Package{}, errors.New(fmt.Sprintf("No packages available for type '%s'.", packageType)) + } + + return productPackages[0], nil +} + +func (slpp *softLayer_Product_Package_Service) GetPackagesByType(packageType string) ([]datatypes.Softlayer_Product_Package, error) { + objectMasks := []string{ + "id", + "name", + "description", + "isActive", + "type.keyName", + } + + filterObject := string(`{"type":{"keyName":{"operation":"` + packageType + `"}}}`) + + response, err := slpp.client.DoRawHttpRequestWithObjectFilterAndObjectMask(fmt.Sprintf("%s/getAllObjects.json", slpp.GetName()), objectMasks, filterObject, "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.Softlayer_Product_Package{}, err + } + + productPackages := []*datatypes.Softlayer_Product_Package{} + err = json.Unmarshal(response, &productPackages) + if err != nil { + return []datatypes.Softlayer_Product_Package{}, err + } + + // Remove packages designated as OUTLET + // See method "#get_packages_of_type" in SoftLayer Python client for details: https://github.com/softlayer/softlayer-python/blob/master/SoftLayer/managers/ordering.py + nonOutletPackages := slpp.filterProducts(productPackages, func(productPackage *datatypes.Softlayer_Product_Package) bool { + return !strings.Contains(productPackage.Description, OUTLET_PACKAGE) && !strings.Contains(productPackage.Name, OUTLET_PACKAGE) + }) + + return nonOutletPackages, nil +} + +//Private methods + +func (slpp *softLayer_Product_Package_Service) filterProducts(array []*datatypes.Softlayer_Product_Package, predicate func(*datatypes.Softlayer_Product_Package) bool) []datatypes.Softlayer_Product_Package { + filtered := make([]datatypes.Softlayer_Product_Package, 0) + for _, element := range array { + if predicate(element) { + filtered = append(filtered, *element) + } + } + return filtered +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package_test.go new file mode 100644 index 000000000..b8a5ad5ef --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_product_package_test.go @@ -0,0 +1,161 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Product_Package", func() { + var ( + username, apiKey string + + fakeClient *slclientfakes.FakeSoftLayerClient + + productPackageService softlayer.SoftLayer_Product_Package_Service + err error + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + productPackageService, err = fakeClient.GetSoftLayer_Product_Package_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(productPackageService).ToNot(BeNil()) + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := productPackageService.GetName() + Expect(name).To(Equal("SoftLayer_Product_Package")) + }) + }) + + Context("#GetItemPrices", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getItemPrices.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Product_Item_Price", func() { + itemPrices, err := productPackageService.GetItemPrices(0) + Expect(err).ToNot(HaveOccurred()) + Expect(len(itemPrices)).To(Equal(1)) + Expect(itemPrices[0].Id).To(Equal(123)) + Expect(itemPrices[0].Item.Id).To(Equal(456)) + }) + }) + + Context("#GetItemPricesBySize", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getItemPrices.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Product_Item_Price", func() { + itemPrices, err := productPackageService.GetItemPricesBySize(222, 20) + Expect(err).ToNot(HaveOccurred()) + Expect(len(itemPrices)).To(Equal(1)) + Expect(itemPrices[0].Id).To(Equal(123)) + Expect(itemPrices[0].Item.Id).To(Equal(456)) + }) + }) + + Context("#GetItems", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getItems.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Product_Item", func() { + productItems, err := productPackageService.GetItems(222) + Expect(err).ToNot(HaveOccurred()) + Expect(len(productItems)).To(Equal(2)) + Expect(productItems[0].Id).To(Equal(123)) + Expect(productItems[0].Prices[0].Id).To(Equal(456)) + }) + }) + + Context("#GetItemsByType", func() { + + BeforeEach(func() { + response, err := testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server.json") + fakeClient.DoRawHttpRequestResponses = append(fakeClient.DoRawHttpRequestResponses, response) + + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.SoftLayer_Product_Item", func() { + response, err := testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getItems.json") + fakeClient.DoRawHttpRequestResponses = append(fakeClient.DoRawHttpRequestResponses, response) + + productItems, err := productPackageService.GetItemsByType("VIRTUAL_SERVER_INSTANCE") + Expect(err).ToNot(HaveOccurred()) + Expect(len(productItems)).To(Equal(2)) + Expect(productItems[0].Id).To(Equal(123)) + Expect(productItems[0].Prices[0].Id).To(Equal(456)) + }) + }) + + Context("#GetPackagesByType", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("returns an array of datatypes.Softlayer_Product_Package", func() { + productPackages, err := productPackageService.GetPackagesByType("VIRTUAL_SERVER_INSTANCE") + Expect(err).ToNot(HaveOccurred()) + Expect(len(productPackages)).To(Equal(4)) + Expect(productPackages[0].Id).To(Equal(200)) + Expect(productPackages[0].Name).To(Equal("Cloud Server 1")) + }) + + It("skips packaged marked OUTLET", func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server_with_OUTLET.json") + productPackages, err := productPackageService.GetPackagesByType("VIRTUAL_SERVER_INSTANCE") + Expect(err).ToNot(HaveOccurred()) + Expect(len(productPackages)).To(Equal(3)) // OUTLET should be skipped + Expect(productPackages[0].Id).To(Equal(202)) + Expect(productPackages[0].Name).To(Equal("Cloud Server 2")) + }) + }) + + Context("#GetOnePackageByType", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("reports error when NO product packages are found", func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server_empty.json") + + GinkgoWriter.Write(fakeClient.DoRawHttpRequestResponse) + + _, err := productPackageService.GetOnePackageByType("SOME_TYPE") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("No packages available for type 'SOME_TYPE'.")) + }) + + It("returns datatypes.Softlayer_Product_Package", func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Package_getAllObjects_virtual_server.json") + productPackage, err := productPackageService.GetOnePackageByType("VIRTUAL_SERVER_INSTANCE") + Expect(err).ToNot(HaveOccurred()) + Expect(productPackage.Id).To(Equal(200)) + Expect(productPackage.Name).To(Equal("Cloud Server 1")) + }) + }) + +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key.go new file mode 100644 index 000000000..0f144b559 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key.go @@ -0,0 +1,127 @@ +package services + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Security_Ssh_Key_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Security_Ssh_Key_Service(client softlayer.Client) *softLayer_Security_Ssh_Key_Service { + return &softLayer_Security_Ssh_Key_Service{ + client: client, + } +} + +func (slssks *softLayer_Security_Ssh_Key_Service) GetName() string { + return "SoftLayer_Security_Ssh_Key" +} + +func (slssks *softLayer_Security_Ssh_Key_Service) CreateObject(template datatypes.SoftLayer_Security_Ssh_Key) (datatypes.SoftLayer_Security_Ssh_Key, error) { + parameters := datatypes.SoftLayer_Shh_Key_Parameters{ + Parameters: []datatypes.SoftLayer_Security_Ssh_Key{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + data, err := slssks.client.DoRawHttpRequest(fmt.Sprintf("%s/createObject", slssks.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + err = slssks.client.CheckForHttpResponseErrors(data) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + softLayer_Ssh_Key := datatypes.SoftLayer_Security_Ssh_Key{} + err = json.Unmarshal(data, &softLayer_Ssh_Key) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + return softLayer_Ssh_Key, nil +} + +func (slssks *softLayer_Security_Ssh_Key_Service) GetObject(sshKeyId int) (datatypes.SoftLayer_Security_Ssh_Key, error) { + objectMask := []string{ + "createDate", + "fingerprint", + "id", + "key", + "label", + "modifyDate", + "notes", + } + + response, err := slssks.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getObject.json", slssks.GetName(), sshKeyId), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + sshKey := datatypes.SoftLayer_Security_Ssh_Key{} + err = json.Unmarshal(response, &sshKey) + if err != nil { + return datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + return sshKey, nil +} + +func (slssks *softLayer_Security_Ssh_Key_Service) EditObject(sshKeyId int, template datatypes.SoftLayer_Security_Ssh_Key) (bool, error) { + parameters := datatypes.SoftLayer_Shh_Key_Parameters{ + Parameters: []datatypes.SoftLayer_Security_Ssh_Key{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slssks.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/editObject.json", slssks.GetName(), sshKeyId), "POST", bytes.NewBuffer(requestBody)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to edit SSH key with id: %d, got '%s' as response from the API.", sshKeyId, res)) + } + + return true, err +} + +func (slssks *softLayer_Security_Ssh_Key_Service) DeleteObject(sshKeyId int) (bool, error) { + response, err := slssks.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", slssks.GetName(), sshKeyId), "DELETE", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to destroy ssh key with id '%d', got '%s' as response from the API.", sshKeyId, res)) + } + + return true, err +} + +func (slssks *softLayer_Security_Ssh_Key_Service) GetSoftwarePasswords(sshKeyId int) ([]datatypes.SoftLayer_Software_Component_Password, error) { + response, err := slssks.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getSoftwarePasswords.json", slssks.GetName(), sshKeyId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Software_Component_Password{}, err + } + + passwords := []datatypes.SoftLayer_Software_Component_Password{} + err = json.Unmarshal(response, &passwords) + if err != nil { + return []datatypes.SoftLayer_Software_Component_Password{}, err + } + + return passwords, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key_test.go new file mode 100644 index 000000000..1cbe7f5c3 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_security_ssh_key_test.go @@ -0,0 +1,158 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Ssh_Key_Service", func() { + var ( + username, apiKey string + err error + + fakeClient *slclientfakes.FakeSoftLayerClient + + sshKeyService softlayer.SoftLayer_Security_Ssh_Key_Service + + sshKey datatypes.SoftLayer_Security_Ssh_Key + sshKeyTemplate datatypes.SoftLayer_Security_Ssh_Key + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + sshKeyService, err = fakeClient.GetSoftLayer_Security_Ssh_Key_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(sshKeyService).ToNot(BeNil()) + + sshKey = datatypes.SoftLayer_Security_Ssh_Key{} + sshKeyTemplate = datatypes.SoftLayer_Security_Ssh_Key{} + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := sshKeyService.GetName() + Expect(name).To(Equal("SoftLayer_Security_Ssh_Key")) + }) + }) + + Context("#CreateObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Security_Ssh_Key_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("creates a new SoftLayer_Ssh_Key instance", func() { + sshKeyTemplate = datatypes.SoftLayer_Security_Ssh_Key{ + Fingerprint: "fake-fingerprint", + Key: "fake-key", + Label: "fake-label", + Notes: "fake-notes", + } + sshKey, err = sshKeyService.CreateObject(sshKeyTemplate) + Expect(err).ToNot(HaveOccurred()) + Expect(sshKey.Fingerprint).To(Equal("fake-fingerprint")) + Expect(sshKey.Key).To(Equal("fake-key")) + Expect(sshKey.Label).To(Equal("fake-label")) + Expect(sshKey.Notes).To(Equal("fake-notes")) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + sshKey.Id = 1337 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Security_Ssh_Key_Service_getObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("gets an SSH key", func() { + key, err := sshKeyService.GetObject(sshKey.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(key.Id).To(Equal(1337)) + Expect(key.Fingerprint).To(Equal("e9:56:6d:b1:f3:8b:f1:2a:dd:a3:24:73:4f:d3:1b:3c")) + Expect(key.Key).To(Equal("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAA/DczU7Wj4hgAgy14LfjOvVKtDBOfwFgHFwsXQ7Efp0pQRBOIwWoQfQ3hHMWw1X5Q7Mhwl9Gbat9V7tu985Hf5h9BOrq9D/ZIFQ1yhsvt6klZYoHHbM5kHFUegx9lgn3mHcfLNcvahDHpQAFXCPknc1VNpn0VP0RPhqZ8pubP7r9/Uczmit1ipy43SGzlxM46cyyqNPgDDRJepDla6coJJGuWVZMZaTXc3fNNFTSIi1ODDQgXxaYWcz5ThcQ1CT/MLSzAz7IDNNjAr5W40ZUmxxHzA5nPmLcKKqqXrxbnCyw+SrVjhIsKSoz41caYdSz2Bpw00ZxzVO9dCnHsEw==")) + Expect(key.Label).To(Equal("packer-53ead4c1-df11-9023-1173-eef40a291b7e")) + Expect(key.Notes).To(Equal("My test key")) + }) + }) + + Context("#EditObject", func() { + BeforeEach(func() { + sshKey.Id = 1338 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Security_Ssh_Key_Service_editObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("edits an existing SSH key", func() { + edited := datatypes.SoftLayer_Security_Ssh_Key{ + Label: "edited-label", + } + result, err := sshKeyService.EditObject(sshKey.Id, edited) + Expect(err).ToNot(HaveOccurred()) + Expect(result).To(BeTrue()) + }) + }) + + Context("#DeleteObject", func() { + BeforeEach(func() { + sshKey.Id = 1234567 + }) + + It("sucessfully deletes the SoftLayer_Ssh_Key instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + deleted, err := sshKeyService.DeleteObject(sshKey.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(deleted).To(BeTrue()) + }) + + It("fails to delete the SoftLayer_Ssh_Key instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + deleted, err := sshKeyService.DeleteObject(sshKey.Id) + Expect(err).To(HaveOccurred()) + Expect(deleted).To(BeFalse()) + }) + }) + + Context("#GetSoftwarePasswords", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Security_Ssh_Key_Service_getSoftwarePasswords.json") + Expect(err).ToNot(HaveOccurred()) + + sshKey.Id = 1234567 + }) + + It("retrieves the software passwords associated with this virtual guest", func() { + passwords, err := sshKeyService.GetSoftwarePasswords(sshKey.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(passwords)).To(Equal(1)) + + password := passwords[0] + Expect(password.CreateDate).ToNot(BeNil()) + Expect(password.Id).To(Equal(4244148)) + Expect(password.ModifyDate).ToNot(BeNil()) + Expect(password.Notes).To(Equal("")) + Expect(password.Password).To(Equal("QJ95Gznz")) + Expect(password.Port).To(Equal(0)) + Expect(password.SoftwareId).To(Equal(4181746)) + Expect(password.Username).To(Equal("root")) + + Expect(password.Software.HardwareId).To(Equal(0)) + Expect(password.Software.Id).To(Equal(4181746)) + Expect(password.Software.ManufacturerLicenseInstance).To(Equal("")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image.go new file mode 100644 index 000000000..f4a1dbfd9 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image.go @@ -0,0 +1,39 @@ +package services + +import ( + "bytes" + "encoding/json" + "fmt" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +type softLayer_Virtual_Disk_Image_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Virtual_Disk_Image_Service(client softlayer.Client) *softLayer_Virtual_Disk_Image_Service { + return &softLayer_Virtual_Disk_Image_Service{ + client: client, + } +} + +func (slvdi *softLayer_Virtual_Disk_Image_Service) GetName() string { + return "SoftLayer_Virtual_Disk_Image" +} + +func (slvdi *softLayer_Virtual_Disk_Image_Service) GetObject(vdImageId int) (datatypes.SoftLayer_Virtual_Disk_Image, error) { + response, err := slvdi.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getObject.json", slvdi.GetName(), vdImageId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Virtual_Disk_Image{}, err + } + + vdImage := datatypes.SoftLayer_Virtual_Disk_Image{} + err = json.Unmarshal(response, &vdImage) + if err != nil { + return datatypes.SoftLayer_Virtual_Disk_Image{}, err + } + + return vdImage, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image_test.go new file mode 100644 index 000000000..a29c179a8 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_disk_image_test.go @@ -0,0 +1,73 @@ +package services_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Virtual_Disk_Image_Service", func() { + var ( + username, apiKey string + err error + + fakeClient *slclientfakes.FakeSoftLayerClient + + virtualDiskImageService softlayer.SoftLayer_Virtual_Disk_Image_Service + + virtualDiskImage datatypes.SoftLayer_Virtual_Disk_Image + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + virtualDiskImageService, err = fakeClient.GetSoftLayer_Virtual_Disk_Image_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(virtualDiskImageService).ToNot(BeNil()) + + virtualDiskImage = datatypes.SoftLayer_Virtual_Disk_Image{} + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := virtualDiskImageService.GetName() + Expect(name).To(Equal("SoftLayer_Virtual_Disk_Image")) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Disk_Image_Service_getObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("gets the SoftLayer_Virtual_Disk_Image instance", func() { + virtualDiskImage, err = virtualDiskImageService.GetObject(4868344) + Expect(err).ToNot(HaveOccurred()) + Expect(virtualDiskImage.Capacity).To(Equal(25)) + Expect(virtualDiskImage.CreateDate).ToNot(BeNil()) + Expect(virtualDiskImage.Description).To(Equal("yz-fabric-node-20140407-133340-856.softlayer.com")) + Expect(virtualDiskImage.Id).To(Equal(4868344)) + Expect(virtualDiskImage.ModifyDate).To(BeNil()) + Expect(virtualDiskImage.Name).To(Equal("yz-fabric-node-20140407-133340-856.softlayer.com")) + Expect(virtualDiskImage.ParentId).To(Equal(0)) + Expect(virtualDiskImage.StorageRepositoryId).To(Equal(1105002)) + Expect(virtualDiskImage.TypeId).To(Equal(241)) + Expect(virtualDiskImage.Units).To(Equal("GB")) + Expect(virtualDiskImage.Uuid).To(Equal("8c7a8358-d9a9-4e4d-9345-6f637e10ccb7")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest.go new file mode 100644 index 000000000..1f2f59eb3 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest.go @@ -0,0 +1,948 @@ +package services + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + "time" + + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" +) + +const ( + EPHEMERAL_DISK_CATEGORY_CODE = "guest_disk1" + // Package type for virtual servers: http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/placeOrder + VIRTUAL_SERVER_PACKAGE_TYPE = "VIRTUAL_SERVER_INSTANCE" + MAINTENANCE_WINDOW_PROPERTY = "MAINTENANCE_WINDOW" + // Described in the following link: http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade + UPGRADE_VIRTUAL_SERVER_ORDER_TYPE = "SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade" +) + +type softLayer_Virtual_Guest_Service struct { + client softlayer.Client +} + +func NewSoftLayer_Virtual_Guest_Service(client softlayer.Client) *softLayer_Virtual_Guest_Service { + return &softLayer_Virtual_Guest_Service{ + client: client, + } +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetName() string { + return "SoftLayer_Virtual_Guest" +} + +func (slvgs *softLayer_Virtual_Guest_Service) CreateObject(template datatypes.SoftLayer_Virtual_Guest_Template) (datatypes.SoftLayer_Virtual_Guest, error) { + err := slvgs.checkCreateObjectRequiredValues(template) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + parameters := datatypes.SoftLayer_Virtual_Guest_Template_Parameters{ + Parameters: []datatypes.SoftLayer_Virtual_Guest_Template{ + template, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s.json", slvgs.GetName()), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + err = slvgs.client.CheckForHttpResponseErrors(response) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + softLayer_Virtual_Guest := datatypes.SoftLayer_Virtual_Guest{} + err = json.Unmarshal(response, &softLayer_Virtual_Guest) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + return softLayer_Virtual_Guest, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) ReloadOperatingSystem(instanceId int, template datatypes.Image_Template_Config) error { + parameter := [2]interface{}{"FORCE", template} + parameters := map[string]interface{}{ + "parameters": parameter, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/reloadOperatingSystem.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return err + } + + if res := string(response[:]); res != `"1"` { + return errors.New(fmt.Sprintf("Failed to reload OS on instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetObject(instanceId int) (datatypes.SoftLayer_Virtual_Guest, error) { + + objectMask := []string{ + "accountId", + "createDate", + "dedicatedAccountHostOnlyFlag", + "domain", + "fullyQualifiedDomainName", + "hostname", + "hourlyBillingFlag", + "id", + "lastPowerStateId", + "lastVerifiedDate", + "maxCpu", + "maxCpuUnits", + "maxMemory", + "metricPollDate", + "modifyDate", + "notes", + "postInstallScriptUri", + "privateNetworkOnlyFlag", + "startCpus", + "statusId", + "uuid", + "userData.value", + "localDiskFlag", + + "globalIdentifier", + "managedResourceFlag", + "primaryBackendIpAddress", + "primaryIpAddress", + + "location.name", + "location.longName", + "location.id", + "datacenter.name", + "datacenter.longName", + "datacenter.id", + "networkComponents.maxSpeed", + "operatingSystem.passwords.password", + "operatingSystem.passwords.username", + + "blockDeviceTemplateGroup.globalIdentifier", + "primaryNetworkComponent.networkVlan.id", + "primaryBackendNetworkComponent.networkVlan.id", + } + + response, err := slvgs.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getObject.json", slvgs.GetName(), instanceId), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + virtualGuest := datatypes.SoftLayer_Virtual_Guest{} + err = json.Unmarshal(response, &virtualGuest) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest{}, err + } + + return virtualGuest, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) EditObject(instanceId int, template datatypes.SoftLayer_Virtual_Guest) (bool, error) { + parameters := datatypes.SoftLayer_Virtual_Guest_Parameters{ + Parameters: []datatypes.SoftLayer_Virtual_Guest{template}, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/editObject.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to edit virtual guest with id: %d, got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) DeleteObject(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d.json", slvgs.GetName(), instanceId), "DELETE", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to delete instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetPowerState(instanceId int) (datatypes.SoftLayer_Virtual_Guest_Power_State, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getPowerState.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Power_State{}, err + } + + vgPowerState := datatypes.SoftLayer_Virtual_Guest_Power_State{} + err = json.Unmarshal(response, &vgPowerState) + if err != nil { + return datatypes.SoftLayer_Virtual_Guest_Power_State{}, err + } + + return vgPowerState, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetPrimaryIpAddress(instanceId int) (string, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getPrimaryIpAddress.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return "", err + } + + vgPrimaryIpAddress := strings.TrimSpace(string(response)) + if vgPrimaryIpAddress == "" { + return "", errors.New(fmt.Sprintf("Failed to get primary IP address for instance with id '%d', got '%s' as response from the API.", instanceId, response)) + } + + return vgPrimaryIpAddress, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetActiveTransaction(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getActiveTransaction.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + activeTransaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &activeTransaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return activeTransaction, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetLastTransaction(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + objectMask := []string{ + "transactionGroup", + } + response, err := slvgs.client.DoRawHttpRequestWithObjectMask(fmt.Sprintf("%s/%d/getLastTransaction.json", slvgs.GetName(), instanceId), objectMask, "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + lastTransaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &lastTransaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return lastTransaction, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetActiveTransactions(instanceId int) ([]datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getActiveTransactions.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + activeTransactions := []datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &activeTransactions) + if err != nil { + return []datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return activeTransactions, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetSshKeys(instanceId int) ([]datatypes.SoftLayer_Security_Ssh_Key, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getSshKeys.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + sshKeys := []datatypes.SoftLayer_Security_Ssh_Key{} + err = json.Unmarshal(response, &sshKeys) + if err != nil { + return []datatypes.SoftLayer_Security_Ssh_Key{}, err + } + + return sshKeys, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) PowerCycle(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/powerCycle.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to power cycle instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) PowerOff(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/powerOff.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to power off instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) PowerOffSoft(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/powerOffSoft.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to power off soft instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) PowerOn(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/powerOn.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to power on instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) RebootDefault(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/rebootDefault.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to default reboot instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) RebootSoft(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/rebootSoft.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to soft reboot instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) RebootHard(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/rebootHard.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to hard reboot instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) SetMetadata(instanceId int, metadata string) (bool, error) { + dataBytes := []byte(metadata) + base64EncodedMetadata := base64.StdEncoding.EncodeToString(dataBytes) + + parameters := datatypes.SoftLayer_SetUserMetadata_Parameters{ + Parameters: []datatypes.UserMetadataArray{ + []datatypes.UserMetadata{datatypes.UserMetadata(base64EncodedMetadata)}, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return false, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/setUserMetadata.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to setUserMetadata for instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, err +} + +func (slvgs *softLayer_Virtual_Guest_Service) ConfigureMetadataDisk(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/configureMetadataDisk.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + transaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &transaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return transaction, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetUserData(instanceId int) ([]datatypes.SoftLayer_Virtual_Guest_Attribute, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getUserData.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Virtual_Guest_Attribute{}, err + } + + attributes := []datatypes.SoftLayer_Virtual_Guest_Attribute{} + err = json.Unmarshal(response, &attributes) + if err != nil { + return []datatypes.SoftLayer_Virtual_Guest_Attribute{}, err + } + + return attributes, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) IsPingable(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/isPingable.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to checking that virtual guest is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) IsBackendPingable(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/isBackendPingable.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to checking that virtual guest backend is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) AttachEphemeralDisk(instanceId int, diskSize int) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) { + diskItemPrice, err := slvgs.findUpgradeItemPriceForEphemeralDisk(instanceId, diskSize) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + orderService, err := slvgs.client.GetSoftLayer_Product_Order_Service() + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + + order := datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade{ + VirtualGuests: []datatypes.VirtualGuest{ + datatypes.VirtualGuest{ + Id: instanceId, + }, + }, + Prices: []datatypes.SoftLayer_Product_Item_Price{ + datatypes.SoftLayer_Product_Item_Price{ + Id: diskItemPrice.Id, + Categories: []datatypes.Category{ + datatypes.Category{ + CategoryCode: EPHEMERAL_DISK_CATEGORY_CODE, + }, + }, + }, + }, + ComplexType: UPGRADE_VIRTUAL_SERVER_ORDER_TYPE, + Properties: []datatypes.Property{ + datatypes.Property{ + Name: MAINTENANCE_WINDOW_PROPERTY, + Value: time.Now().UTC().Format(time.RFC3339), + }, + datatypes.Property{ + Name: "NOTE_GENERAL", + Value: "addingdisks", + }, + }, + } + + receipt, err := orderService.PlaceContainerOrderVirtualGuestUpgrade(order) + if err != nil { + return datatypes.SoftLayer_Container_Product_Order_Receipt{}, err + } + return receipt, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) UpgradeObject(instanceId int, options *softlayer.UpgradeOptions) (bool, error) { + + prices, err := slvgs.GetAvailableUpgradeItemPrices(options) + if err != nil { + return false, err + } + + if len(prices) == 0 { + // Nothing to order, as all the values are up to date + return false, nil + } + + orderService, err := slvgs.client.GetSoftLayer_Product_Order_Service() + if err != nil { + return false, err + } + + order := datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade{ + VirtualGuests: []datatypes.VirtualGuest{ + datatypes.VirtualGuest{ + Id: instanceId, + }, + }, + Prices: prices, + ComplexType: UPGRADE_VIRTUAL_SERVER_ORDER_TYPE, + Properties: []datatypes.Property{ + datatypes.Property{ + Name: MAINTENANCE_WINDOW_PROPERTY, + Value: time.Now().UTC().Format(time.RFC3339), + }, + }, + } + + _, err = orderService.PlaceContainerOrderVirtualGuestUpgrade(order) + if err != nil { + return false, err + } + + return true, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetAvailableUpgradeItemPrices(upgradeOptions *softlayer.UpgradeOptions) ([]datatypes.SoftLayer_Product_Item_Price, error) { + + itemsCapacity := make(map[string]int) + if upgradeOptions.Cpus > 0 { + itemsCapacity["cpus"] = upgradeOptions.Cpus + } + if upgradeOptions.MemoryInGB > 0 { + itemsCapacity["memory"] = upgradeOptions.MemoryInGB + } + if upgradeOptions.NicSpeed > 0 { + itemsCapacity["nic_speed"] = upgradeOptions.NicSpeed + } + + virtualServerPackageItems, err := slvgs.getVirtualServerItems() + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + prices := make([]datatypes.SoftLayer_Product_Item_Price, 0) + + for item, amount := range itemsCapacity { + price, err := slvgs.filterProductItemPrice(virtualServerPackageItems, item, amount) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + prices = append(prices, price) + } + + return prices, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetUpgradeItemPrices(instanceId int) ([]datatypes.SoftLayer_Product_Item_Price, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getUpgradeItemPrices.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + itemPrices := []datatypes.SoftLayer_Product_Item_Price{} + err = json.Unmarshal(response, &itemPrices) + if err != nil { + return []datatypes.SoftLayer_Product_Item_Price{}, err + } + + return itemPrices, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) SetTags(instanceId int, tags []string) (bool, error) { + var tagStringBuffer bytes.Buffer + for i, tag := range tags { + tagStringBuffer.WriteString(tag) + if i != len(tags)-1 { + tagStringBuffer.WriteString(", ") + } + } + + setTagsParameters := datatypes.SoftLayer_Virtual_Guest_SetTags_Parameters{ + Parameters: []string{tagStringBuffer.String()}, + } + + requestBody, err := json.Marshal(setTagsParameters) + if err != nil { + return false, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/setTags.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return false, err + } + + if res := string(response[:]); res != "true" { + return false, errors.New(fmt.Sprintf("Failed to setTags for instance with id '%d', got '%s' as response from the API.", instanceId, res)) + } + + return true, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetTagReferences(instanceId int) ([]datatypes.SoftLayer_Tag_Reference, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getTagReferences.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Tag_Reference{}, err + } + + tagReferences := []datatypes.SoftLayer_Tag_Reference{} + err = json.Unmarshal(response, &tagReferences) + if err != nil { + return []datatypes.SoftLayer_Tag_Reference{}, err + } + + return tagReferences, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) AttachDiskImage(instanceId int, imageId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + parameters := datatypes.SoftLayer_Virtual_GuestInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_GuestInitParameter{ + ImageId: imageId, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/attachDiskImage.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + transaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &transaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return transaction, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) DetachDiskImage(instanceId int, imageId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) { + parameters := datatypes.SoftLayer_Virtual_GuestInitParameters{ + Parameters: datatypes.SoftLayer_Virtual_GuestInitParameter{ + ImageId: imageId, + }, + } + + requestBody, err := json.Marshal(parameters) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/detachDiskImage.json", slvgs.GetName(), instanceId), "POST", bytes.NewBuffer(requestBody)) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + transaction := datatypes.SoftLayer_Provisioning_Version1_Transaction{} + err = json.Unmarshal(response, &transaction) + if err != nil { + return datatypes.SoftLayer_Provisioning_Version1_Transaction{}, err + } + + return transaction, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) ActivatePrivatePort(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/activatePrivatePort.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to activate private port for virtual guest is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) ActivatePublicPort(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/activatePublicPort.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to activate public port for virtual guest is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) ShutdownPrivatePort(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/shutdownPrivatePort.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to shutdown private port for virtual guest is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) ShutdownPublicPort(instanceId int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/shutdownPublicPort.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to shutdown public port for virtual guest is pingable for instance with id '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetAllowedHost(instanceId int) (datatypes.SoftLayer_Network_Storage_Allowed_Host, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getAllowedHost.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Network_Storage_Allowed_Host{}, err + } + + allowedHost := datatypes.SoftLayer_Network_Storage_Allowed_Host{} + err = json.Unmarshal(response, &allowedHost) + if err != nil { + return datatypes.SoftLayer_Network_Storage_Allowed_Host{}, err + } + + return allowedHost, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) GetNetworkVlans(instanceId int) ([]datatypes.SoftLayer_Network_Vlan, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/getNetworkVlans.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return []datatypes.SoftLayer_Network_Vlan{}, err + } + + networkVlans := []datatypes.SoftLayer_Network_Vlan{} + err = json.Unmarshal(response, &networkVlans) + if err != nil { + return []datatypes.SoftLayer_Network_Vlan{}, err + } + + return networkVlans, nil +} + +func (slvgs *softLayer_Virtual_Guest_Service) CheckHostDiskAvailability(instanceId int, diskCapacity int) (bool, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/checkHostDiskAvailability/%d", slvgs.GetName(), instanceId, diskCapacity), "GET", new(bytes.Buffer)) + if err != nil { + return false, err + } + + res := string(response) + + if res == "true" { + return true, nil + } + + if res == "false" { + return false, nil + } + + return false, errors.New(fmt.Sprintf("Failed to check host disk availability for instance '%d', got '%s' as response from the API.", instanceId, res)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) CaptureImage(instanceId int) (datatypes.SoftLayer_Container_Disk_Image_Capture_Template, error) { + response, err := slvgs.client.DoRawHttpRequest(fmt.Sprintf("%s/%d/captureImage.json", slvgs.GetName(), instanceId), "GET", new(bytes.Buffer)) + if err != nil { + return datatypes.SoftLayer_Container_Disk_Image_Capture_Template{}, err + } + + diskImageTemplate := datatypes.SoftLayer_Container_Disk_Image_Capture_Template{} + err = json.Unmarshal(response, &diskImageTemplate) + if err != nil { + return datatypes.SoftLayer_Container_Disk_Image_Capture_Template{}, err + } + + return diskImageTemplate, nil +} + +//Private methods + +func (slvgs *softLayer_Virtual_Guest_Service) getVirtualServerItems() ([]datatypes.SoftLayer_Product_Item, error) { + service, err := slvgs.client.GetSoftLayer_Product_Package_Service() + if err != nil { + return []datatypes.SoftLayer_Product_Item{}, err + } + + return service.GetItemsByType(VIRTUAL_SERVER_PACKAGE_TYPE) +} + +func (slvgs *softLayer_Virtual_Guest_Service) filterProductItemPrice(packageItems []datatypes.SoftLayer_Product_Item, option string, amount int) (datatypes.SoftLayer_Product_Item_Price, error) { + // for now use hardcoded values in the same "style" as Python client does + // refer to corresponding Python method #_get_item_id_for_upgrade: https://github.com/softlayer/softlayer-python/blob/master/SoftLayer/managers/vs.py + vsId := map[string]int{ + "memory": 3, + "cpus": 80, + "nic_speed": 26, + } + + for _, packageItem := range packageItems { + categories := packageItem.Prices[0].Categories + for _, category := range categories { + + if packageItem.Capacity == "" { + continue + } + + capacity, err := strconv.Atoi(packageItem.Capacity) + if err != nil { + return datatypes.SoftLayer_Product_Item_Price{}, err + } + + if category.Id != vsId[option] || capacity != amount { + continue + } + + switch option { + case "cpus": + if !strings.Contains(packageItem.Description, "Private") { + return packageItem.Prices[0], nil + } + case "nic_speed": + if strings.Contains(packageItem.Description, "Public") { + return packageItem.Prices[0], nil + } + default: + return packageItem.Prices[0], nil + } + } + } + + return datatypes.SoftLayer_Product_Item_Price{}, errors.New(fmt.Sprintf("Failed to find price for '%s' (of size %d)", option, amount)) +} + +func (slvgs *softLayer_Virtual_Guest_Service) checkCreateObjectRequiredValues(template datatypes.SoftLayer_Virtual_Guest_Template) error { + var err error + errorMessage, errorTemplate := "", "* %s is required and cannot be empty\n" + + if template.Hostname == "" { + errorMessage += fmt.Sprintf(errorTemplate, "Hostname for the computing instance") + } + + if template.Domain == "" { + errorMessage += fmt.Sprintf(errorTemplate, "Domain for the computing instance") + } + + if template.StartCpus <= 0 { + errorMessage += fmt.Sprintf(errorTemplate, "StartCpus: the number of CPU cores to allocate") + } + + if template.MaxMemory <= 0 { + errorMessage += fmt.Sprintf(errorTemplate, "MaxMemory: the amount of memory to allocate in megabytes") + } + + for _, device := range template.BlockDevices { + if device.DiskImage.Capacity <= 0 { + errorMessage += fmt.Sprintf("Disk size must be positive number, the size of block device %s is set to be %dGB.", device.Device, device.DiskImage.Capacity) + } + } + + if template.Datacenter.Name == "" { + errorMessage += fmt.Sprintf(errorTemplate, "Datacenter.Name: specifies which datacenter the instance is to be provisioned in") + } + + if errorMessage != "" { + err = errors.New(errorMessage) + } + + return err +} + +func (slvgs *softLayer_Virtual_Guest_Service) findUpgradeItemPriceForEphemeralDisk(instanceId int, ephemeralDiskSize int) (datatypes.SoftLayer_Product_Item_Price, error) { + if ephemeralDiskSize <= 0 { + return datatypes.SoftLayer_Product_Item_Price{}, errors.New(fmt.Sprintf("Ephemeral disk size can not be negative: %d", ephemeralDiskSize)) + } + + itemPrices, err := slvgs.GetUpgradeItemPrices(instanceId) + if err != nil { + return datatypes.SoftLayer_Product_Item_Price{}, nil + } + + var currentDiskCapacity int + var currentItemPrice datatypes.SoftLayer_Product_Item_Price + + for _, itemPrice := range itemPrices { + + flag := false + for _, category := range itemPrice.Categories { + if category.CategoryCode == EPHEMERAL_DISK_CATEGORY_CODE { + flag = true + break + } + } + + if flag && strings.Contains(itemPrice.Item.Description, "(LOCAL)") { + + capacity, _ := strconv.Atoi(itemPrice.Item.Capacity) + + if capacity >= ephemeralDiskSize { + if currentItemPrice.Id == 0 || currentDiskCapacity >= capacity { + currentItemPrice = itemPrice + currentDiskCapacity = capacity + } + } + } + } + + if currentItemPrice.Id == 0 { + return datatypes.SoftLayer_Product_Item_Price{}, errors.New(fmt.Sprintf("No proper local disk for size %d", ephemeralDiskSize)) + } + + return currentItemPrice, nil +} diff --git a/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest_test.go b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest_test.go new file mode 100644 index 000000000..232972563 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/services/softlayer_virtual_guest_test.go @@ -0,0 +1,982 @@ +package services_test + +import ( + "errors" + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + slclientfakes "github.com/maximilien/softlayer-go/client/fakes" + datatypes "github.com/maximilien/softlayer-go/data_types" + softlayer "github.com/maximilien/softlayer-go/softlayer" + testhelpers "github.com/maximilien/softlayer-go/test_helpers" +) + +var _ = Describe("SoftLayer_Virtual_Guest_Service", func() { + + var ( + username, apiKey string + err error + + fakeClient *slclientfakes.FakeSoftLayerClient + + virtualGuestService softlayer.SoftLayer_Virtual_Guest_Service + + virtualGuest datatypes.SoftLayer_Virtual_Guest + virtualGuestTemplate datatypes.SoftLayer_Virtual_Guest_Template + reload_OS_Config datatypes.Image_Template_Config + ) + + BeforeEach(func() { + username = os.Getenv("SL_USERNAME") + Expect(username).ToNot(Equal("")) + + apiKey = os.Getenv("SL_API_KEY") + Expect(apiKey).ToNot(Equal("")) + + fakeClient = slclientfakes.NewFakeSoftLayerClient(username, apiKey) + Expect(fakeClient).ToNot(BeNil()) + + fakeClient.SoftLayerServices["SoftLayer_Product_Package"] = &testhelpers.MockProductPackageService{} + + virtualGuestService, err = fakeClient.GetSoftLayer_Virtual_Guest_Service() + Expect(err).ToNot(HaveOccurred()) + Expect(virtualGuestService).ToNot(BeNil()) + + virtualGuest = datatypes.SoftLayer_Virtual_Guest{} + virtualGuestTemplate = datatypes.SoftLayer_Virtual_Guest_Template{} + }) + + Context("#GetName", func() { + It("returns the name for the service", func() { + name := virtualGuestService.GetName() + Expect(name).To(Equal("SoftLayer_Virtual_Guest")) + }) + }) + + Context("#CreateObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_createObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("creates a new SoftLayer_Virtual_Guest instance", func() { + virtualGuestTemplate = datatypes.SoftLayer_Virtual_Guest_Template{ + Hostname: "fake-hostname", + Domain: "fake.domain.com", + StartCpus: 2, + MaxMemory: 1024, + Datacenter: datatypes.Datacenter{ + Name: "fake-datacenter-name", + }, + HourlyBillingFlag: true, + LocalDiskFlag: false, + DedicatedAccountHostOnlyFlag: false, + NetworkComponents: []datatypes.NetworkComponents{datatypes.NetworkComponents{ + MaxSpeed: 10, + }}, + UserData: []datatypes.UserData{ + datatypes.UserData{ + Value: "some user data $_/<| with special characters", + }, + }, + } + virtualGuest, err = virtualGuestService.CreateObject(virtualGuestTemplate) + Expect(err).ToNot(HaveOccurred()) + Expect(virtualGuest.Hostname).To(Equal("fake-hostname")) + Expect(virtualGuest.Domain).To(Equal("fake.domain.com")) + Expect(virtualGuest.StartCpus).To(Equal(2)) + Expect(virtualGuest.MaxMemory).To(Equal(1024)) + Expect(virtualGuest.DedicatedAccountHostOnlyFlag).To(BeFalse()) + }) + + It("flags all missing required parameters for SoftLayer_Virtual_Guest/createObject.json POST call", func() { + virtualGuestTemplate = datatypes.SoftLayer_Virtual_Guest_Template{} + _, err := virtualGuestService.CreateObject(virtualGuestTemplate) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Hostname")) + Expect(err.Error()).To(ContainSubstring("Domain")) + Expect(err.Error()).To(ContainSubstring("StartCpus")) + Expect(err.Error()).To(ContainSubstring("MaxMemory")) + Expect(err.Error()).To(ContainSubstring("Datacenter")) + }) + }) + + Context("#GetObject", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Virtual_Guest instance", func() { + vg, err := virtualGuestService.GetObject(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(vg.Id).To(Equal(virtualGuest.Id)) + Expect(vg.AccountId).To(Equal(278444)) + Expect(vg.CreateDate).ToNot(BeNil()) + Expect(vg.DedicatedAccountHostOnlyFlag).To(BeFalse()) + Expect(vg.Domain).To(Equal("softlayer.com")) + Expect(vg.FullyQualifiedDomainName).To(Equal("bosh-ecpi1.softlayer.com")) + Expect(vg.Hostname).To(Equal("bosh-ecpi1")) + Expect(vg.Id).To(Equal(1234567)) + Expect(vg.LastPowerStateId).To(Equal(0)) + Expect(vg.LastVerifiedDate).To(BeNil()) + Expect(vg.MaxCpu).To(Equal(1)) + Expect(vg.MaxCpuUnits).To(Equal("CORE")) + Expect(vg.MaxMemory).To(Equal(1024)) + Expect(vg.MetricPollDate).To(BeNil()) + Expect(vg.ModifyDate).ToNot(BeNil()) + Expect(vg.StartCpus).To(Equal(1)) + Expect(vg.StatusId).To(Equal(1001)) + Expect(vg.Uuid).To(Equal("85d444ce-55a0-39c0-e17a-f697f223cd8a")) + Expect(vg.GlobalIdentifier).To(Equal("52145e01-97b6-4312-9c15-dac7f24b6c2a")) + Expect(vg.UserData[0].Value).To(Equal("some user data $_/<| with special characters")) + Expect(vg.PrimaryBackendIpAddress).To(Equal("10.106.192.42")) + Expect(vg.PrimaryIpAddress).To(Equal("23.246.234.32")) + Expect(vg.Location.Id).To(Equal(1234567)) + Expect(vg.Location.Name).To(Equal("R5")) + Expect(vg.Location.LongName).To(Equal("Room 5")) + Expect(vg.Datacenter.Id).To(Equal(456)) + Expect(vg.Datacenter.Name).To(Equal("bej2")) + Expect(vg.Datacenter.LongName).To(Equal("Beijing 2")) + Expect(vg.NetworkComponents[0].MaxSpeed).To(Equal(100)) + Expect(len(vg.OperatingSystem.Passwords)).To(BeNumerically(">=", 1)) + Expect(vg.OperatingSystem.Passwords[0].Password).To(Equal("test_password")) + Expect(vg.OperatingSystem.Passwords[0].Username).To(Equal("test_username")) + }) + }) + + Context("#EditObject", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_editObject.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("edits an existing SoftLayer_Virtual_Guest instance", func() { + virtualGuest := datatypes.SoftLayer_Virtual_Guest{ + Notes: "fake-notes", + } + edited, err := virtualGuestService.EditObject(virtualGuest.Id, virtualGuest) + Expect(err).ToNot(HaveOccurred()) + Expect(edited).To(BeTrue()) + }) + }) + + Context("#ReloadOperatingSystem", func() { + BeforeEach(func() { + reload_OS_Config = datatypes.Image_Template_Config{ + ImageTemplateId: "5b7bc66a-72c6-447a-94a1-967803fcd76b", + } + virtualGuest.Id = 1234567 + }) + + It("sucessfully reload OS on the virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte(`"1"`) + + err = virtualGuestService.ReloadOperatingSystem(virtualGuest.Id, reload_OS_Config) + Expect(err).ToNot(HaveOccurred()) + }) + + It("fails to reload OS on the virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte(`"99"`) + + err = virtualGuestService.ReloadOperatingSystem(virtualGuest.Id, reload_OS_Config) + Expect(err).To(HaveOccurred()) + }) + }) + + Context("#DeleteObject", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully deletes the SoftLayer_Virtual_Guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + deleted, err := virtualGuestService.DeleteObject(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(deleted).To(BeTrue()) + }) + + It("fails to delete the SoftLayer_Virtual_Guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + deleted, err := virtualGuestService.DeleteObject(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(deleted).To(BeFalse()) + }) + }) + + Context("#AttachEphemeralDisk", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("reports error when providing a wrong disk size", func() { + _, err := virtualGuestService.AttachEphemeralDisk(123, -1) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("Ephemeral disk size can not be negative: -1")) + }) + + It("can attach a local disk without error", func() { + receipt, err := virtualGuestService.AttachEphemeralDisk(123, 25) + Expect(err).ToNot(HaveOccurred()) + Expect(receipt.OrderId).NotTo(Equal(0)) + }) + + }) + + Context("#UpgradeObject", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("can upgrade object without any error", func() { + _, err := virtualGuestService.UpgradeObject(123, &softlayer.UpgradeOptions{ + Cpus: 2, + MemoryInGB: 2, + NicSpeed: 1000, + }) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + Context("#GetAvailableUpgradeItemPrices", func() { + BeforeEach(func() { + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Product_Order_placeOrder.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("reports error when pricing item for provided CPUs is not available", func() { + _, err := virtualGuestService.GetAvailableUpgradeItemPrices(&softlayer.UpgradeOptions{Cpus: 3}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("Failed to find price for 'cpus' (of size 3)")) + }) + + It("reports error when pricing item for provided RAM is not available", func() { + _, err := virtualGuestService.GetAvailableUpgradeItemPrices(&softlayer.UpgradeOptions{MemoryInGB: 1500}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("Failed to find price for 'memory' (of size 1500)")) + }) + + It("reports error when pricing item for provided network speed is not available", func() { + _, err := virtualGuestService.GetAvailableUpgradeItemPrices(&softlayer.UpgradeOptions{NicSpeed: 999}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("Failed to find price for 'nic_speed' (of size 999)")) + }) + }) + + Context("#GetPowerState", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getPowerState.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Virtual_Guest_State for RUNNING instance", func() { + vgPowerState, err := virtualGuestService.GetPowerState(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(vgPowerState.KeyName).To(Equal("RUNNING")) + }) + }) + + Context("#GetPrimaryIpAddress", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse = []byte("159.99.99.99") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer virtual guest's primary IP address instance", func() { + vgPrimaryIpAddress, err := virtualGuestService.GetPrimaryIpAddress(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(vgPrimaryIpAddress).To(Equal("159.99.99.99")) + }) + }) + + Context("#GetActiveTransaction", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getActiveTransaction.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves SoftLayer_Provisioning_Version1_Transaction for virtual guest", func() { + activeTransaction, err := virtualGuestService.GetActiveTransaction(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(activeTransaction.CreateDate).ToNot(BeNil()) + Expect(activeTransaction.ElapsedSeconds).To(BeNumerically(">", 0)) + Expect(activeTransaction.GuestId).To(Equal(virtualGuest.Id)) + Expect(activeTransaction.Id).To(BeNumerically(">", 0)) + }) + }) + + Context("#GetLastTransaction", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getLastTransaction.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves last SoftLayer_Provisioning_Version1_Transaction for virtual guest", func() { + lastTransaction, err := virtualGuestService.GetLastTransaction(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(lastTransaction.CreateDate).ToNot(BeNil()) + Expect(lastTransaction.ElapsedSeconds).To(BeNumerically(">", 0)) + Expect(lastTransaction.GuestId).To(Equal(virtualGuest.Id)) + Expect(lastTransaction.Id).To(BeNumerically(">", 0)) + }) + }) + + Context("#GetActiveTransactions", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getActiveTransactions.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves an array of SoftLayer_Provisioning_Version1_Transaction for virtual guest", func() { + activeTransactions, err := virtualGuestService.GetActiveTransactions(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(activeTransactions)).To(BeNumerically(">", 0)) + + for _, activeTransaction := range activeTransactions { + Expect(activeTransaction.CreateDate).ToNot(BeNil()) + Expect(activeTransaction.ElapsedSeconds).To(BeNumerically(">", 0)) + Expect(activeTransaction.GuestId).To(Equal(virtualGuest.Id)) + Expect(activeTransaction.Id).To(BeNumerically(">", 0)) + } + }) + }) + + Context("#GetSshKeys", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getSshKeys.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully retrieves an array of SoftLayer_Security_Ssh_Key for virtual guest", func() { + sshKeys, err := virtualGuestService.GetSshKeys(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(len(sshKeys)).To(BeNumerically(">", 0)) + + for _, sshKey := range sshKeys { + Expect(sshKey.CreateDate).ToNot(BeNil()) + Expect(sshKey.Fingerprint).To(Equal("f6:c2:9d:57:2f:74:be:a1:db:71:f2:e5:8e:0f:84:7e")) + Expect(sshKey.Id).To(Equal(84386)) + Expect(sshKey.Key).ToNot(Equal("")) + Expect(sshKey.Label).To(Equal("TEST:softlayer-go")) + Expect(sshKey.ModifyDate).To(BeNil()) + Expect(sshKey.Label).To(Equal("TEST:softlayer-go")) + } + }) + }) + + Context("#PowerCycle", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully power cycle virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.PowerCycle(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to power cycle virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.PowerCycle(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#PowerOff", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully power off virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.PowerOff(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to power off virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.PowerOff(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#PowerOffSoft", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully power off soft virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.PowerOffSoft(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to power off soft virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.PowerOffSoft(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#PowerOn", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully power on virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.PowerOn(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to power on virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.PowerOn(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#RebootDefault", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully default reboots virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.RebootDefault(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to default reboot virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.RebootDefault(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#RebootSoft", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully soft reboots virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.RebootSoft(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to soft reboot virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.RebootSoft(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#RebootHard", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + It("sucessfully hard reboot virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + rebooted, err := virtualGuestService.RebootHard(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(rebooted).To(BeTrue()) + }) + + It("fails to hard reboot virtual guest instance", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + rebooted, err := virtualGuestService.RebootHard(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(rebooted).To(BeFalse()) + }) + }) + + Context("#SetUserMetadata", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_setMetadata.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully adds metadata strings as a dile to virtual guest's metadata disk", func() { + retBool, err := virtualGuestService.SetMetadata(virtualGuest.Id, "fake-metadata") + Expect(err).ToNot(HaveOccurred()) + + Expect(retBool).To(BeTrue()) + }) + }) + + Context("#GetUserData", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getUserData.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully returns user data for the virtual guest", func() { + attributes, err := virtualGuestService.GetUserData(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + + Expect(len(attributes)).To(BeNumerically("==", 2)) + + Expect(attributes[0].Value).To(Equal("V2hvJ3Mgc21hcnRlcj8gRG1pdHJ5aSBvciBkci5tYXguLi4gIHRoZSBkb2MsIGFueSBkYXkgOik=")) + Expect(attributes[0].Type.Name).To(Equal("User Data")) + Expect(attributes[0].Type.Keyname).To(Equal("USER_DATA")) + + Expect(attributes[1].Value).To(Equal("ZmFrZS1iYXNlNjQtZGF0YQo=")) + Expect(attributes[1].Type.Name).To(Equal("Fake Data")) + Expect(attributes[1].Type.Keyname).To(Equal("FAKE_DATA")) + }) + }) + + Context("#IsPingable", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + Context("when there are no API errors", func() { + It("checks that the virtual guest instance is pigable", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + pingable, err := virtualGuestService.IsPingable(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(pingable).To(BeTrue()) + }) + + It("checks that the virtual guest instance is NOT pigable", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + pingable, err := virtualGuestService.IsPingable(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(pingable).To(BeFalse()) + }) + }) + + Context("when there are API errors", func() { + It("returns false and error", func() { + fakeClient.DoRawHttpRequestError = errors.New("fake-error") + + pingable, err := virtualGuestService.IsPingable(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(pingable).To(BeFalse()) + }) + }) + + Context("when the API returns invalid or empty result", func() { + It("returns false and error", func() { + fakeClient.DoRawHttpRequestResponse = []byte("fake") + + pingable, err := virtualGuestService.IsPingable(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Failed to checking that virtual guest is pingable")) + Expect(pingable).To(BeFalse()) + }) + }) + }) + + Context("#IsBackendPingeable", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + }) + + Context("when there are no API errors", func() { + It("checks that the virtual guest instance backend is pigable", func() { + fakeClient.DoRawHttpRequestResponse = []byte("true") + + pingable, err := virtualGuestService.IsBackendPingable(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(pingable).To(BeTrue()) + }) + + It("checks that the virtual guest instance backend is NOT pigable", func() { + fakeClient.DoRawHttpRequestResponse = []byte("false") + + pingable, err := virtualGuestService.IsBackendPingable(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + Expect(pingable).To(BeFalse()) + }) + }) + + Context("when there are API errors", func() { + It("returns false and error", func() { + fakeClient.DoRawHttpRequestError = errors.New("fake-error") + + pingable, err := virtualGuestService.IsBackendPingable(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(pingable).To(BeFalse()) + }) + }) + + Context("when the API returns invalid or empty result", func() { + It("returns false and error", func() { + fakeClient.DoRawHttpRequestResponse = []byte("fake") + + pingable, err := virtualGuestService.IsBackendPingable(virtualGuest.Id) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Failed to checking that virtual guest backend is pingable")) + Expect(pingable).To(BeFalse()) + }) + }) + }) + + Context("#ConfigureMetadataDisk", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_configureMetadataDisk.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully configures a metadata disk for a virtual guest", func() { + transaction, err := virtualGuestService.ConfigureMetadataDisk(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + + Expect(transaction.CreateDate).ToNot(BeNil()) + Expect(transaction.ElapsedSeconds).To(Equal(0)) + Expect(transaction.GuestId).To(Equal(virtualGuest.Id)) + Expect(transaction.HardwareId).To(Equal(0)) + Expect(transaction.Id).To(Equal(12476326)) + Expect(transaction.ModifyDate).ToNot(BeNil()) + Expect(transaction.StatusChangeDate).ToNot(BeNil()) + + Expect(transaction.TransactionGroup.AverageTimeToComplete).To(Equal("1.62")) + Expect(transaction.TransactionGroup.Name).To(Equal("Configure Cloud Metadata Disk")) + + Expect(transaction.TransactionStatus.AverageDuration).To(Equal(".32")) + Expect(transaction.TransactionStatus.FriendlyName).To(Equal("Configure Cloud Metadata Disk")) + Expect(transaction.TransactionStatus.Name).To(Equal("CLOUD_CONFIGURE_METADATA_DISK")) + }) + }) + + Context("#GetUpgradeItemPrices", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getUpgradeItemPrices.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sucessfully get the upgrade item prices for a virtual guest", func() { + itemPrices, err := virtualGuestService.GetUpgradeItemPrices(virtualGuest.Id) + Expect(err).ToNot(HaveOccurred()) + + Expect(len(itemPrices)).To(Equal(1)) + Expect(itemPrices[0].Id).To(Equal(12345)) + Expect(itemPrices[0].Categories[0].CategoryCode).To(Equal("guest_disk1")) + }) + }) + + Context("#SetTags", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_setTags.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("sets tags: tag0, tag1, tag2 to virtual guest instance", func() { + tags := []string{"tag0", "tag1", "tag2"} + tagsWasSet, err := virtualGuestService.SetTags(virtualGuest.Id, tags) + + Expect(err).ToNot(HaveOccurred()) + Expect(tagsWasSet).To(BeTrue()) + }) + }) + + Context("#GetReferenceTags", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getReferenceTags.json") + Expect(err).ToNot(HaveOccurred()) + }) + + itVerifiesATagReference := func(tagReference1 datatypes.SoftLayer_Tag_Reference, tagReference2 datatypes.SoftLayer_Tag_Reference) { + Expect(tagReference1.EmpRecordId).To(Equal(tagReference2.EmpRecordId)) + Expect(tagReference1.Id).To(Equal(tagReference2.Id)) + Expect(tagReference1.ResourceTableId).To(Equal(tagReference2.ResourceTableId)) + + Expect(tagReference1.Tag.AccountId).To(Equal(tagReference2.Tag.AccountId)) + Expect(tagReference1.Tag.Id).To(Equal(tagReference2.Tag.Id)) + Expect(tagReference1.Tag.Internal).To(Equal(tagReference2.Tag.Internal)) + Expect(tagReference1.Tag.Name).To(Equal(tagReference2.Tag.Name)) + + Expect(tagReference1.TagId).To(Equal(tagReference2.TagId)) + + Expect(tagReference1.TagType.Description).To(Equal(tagReference2.TagType.Description)) + Expect(tagReference1.TagType.KeyName).To(Equal(tagReference2.TagType.KeyName)) + + Expect(tagReference1.TagTypeId).To(Equal(tagReference2.TagTypeId)) + Expect(tagReference1.UsrRecordId).To(Equal(tagReference2.UsrRecordId)) + } + + It("gets the reference tags: tag0, tag1, tag2 from the virtual guest instance", func() { + tagReferences, err := virtualGuestService.GetTagReferences(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(len(tagReferences)).To(Equal(3)) + + expectedTagReferences := []datatypes.SoftLayer_Tag_Reference{ + datatypes.SoftLayer_Tag_Reference{ + EmpRecordId: nil, + Id: 1855150, + ResourceTableId: 7967498, + Tag: datatypes.TagReference{ + AccountId: 278444, + Id: 91128, + Internal: 0, + Name: "tag1", + }, + TagId: 91128, + TagType: datatypes.TagType{ + Description: "CCI", + KeyName: "GUEST", + }, + TagTypeId: 2, + UsrRecordId: 239954, + }, + datatypes.SoftLayer_Tag_Reference{ + EmpRecordId: nil, + Id: 1855152, + ResourceTableId: 7967498, + Tag: datatypes.TagReference{ + AccountId: 278444, + Id: 91130, + Internal: 0, + Name: "tag2", + }, + TagId: 91130, + TagType: datatypes.TagType{ + Description: "CCI", + KeyName: "GUEST", + }, + TagTypeId: 2, + UsrRecordId: 239954, + }, + datatypes.SoftLayer_Tag_Reference{ + EmpRecordId: nil, + Id: 1855154, + ResourceTableId: 7967498, + Tag: datatypes.TagReference{ + AccountId: 278444, + Id: 91132, + Internal: 0, + Name: "tag3", + }, + TagId: 91132, + TagType: datatypes.TagType{ + Description: "CCI", + KeyName: "GUEST", + }, + TagTypeId: 2, + UsrRecordId: 239954, + }, + } + for i, expectedTagReference := range expectedTagReferences { + itVerifiesATagReference(tagReferences[i], expectedTagReference) + } + }) + }) + + Context("#AttachDiskImage", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_attachDiskImage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("attaches disk image with ID `1234567` to virtual guest instance", func() { + imageId := 1234567 + transaction, err := virtualGuestService.AttachDiskImage(virtualGuest.Id, imageId) + + Expect(err).ToNot(HaveOccurred()) + Expect(transaction).ToNot(Equal(datatypes.SoftLayer_Provisioning_Version1_Transaction{})) + }) + }) + + Context("#DetachDiskImage", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_detachDiskImage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("detaches disk image with ID `1234567` to virtual guest instance", func() { + imageId := 1234567 + transaction, err := virtualGuestService.DetachDiskImage(virtualGuest.Id, imageId) + + Expect(err).ToNot(HaveOccurred()) + Expect(transaction).ToNot(Equal(datatypes.SoftLayer_Provisioning_Version1_Transaction{})) + }) + }) + + Context("#ActivatePrivatePort", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_activatePrivatePort.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("activates private port for virtual guest instance", func() { + activated, err := virtualGuestService.ActivatePrivatePort(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(activated).To(BeTrue()) + }) + }) + + Context("#ActivatePublicPort", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_activatePublicPort.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("activates public port for virtual guest instance", func() { + activated, err := virtualGuestService.ActivatePublicPort(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(activated).To(BeTrue()) + }) + }) + + Context("#ShutdownPrivatePort", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_shutdownPrivatePort.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("shutdown private port for virtual guest instance", func() { + shutdowned, err := virtualGuestService.ShutdownPrivatePort(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(shutdowned).To(BeTrue()) + }) + }) + + Context("#ShutdownPublicPort", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_shutdownPublicPort.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("shuts down public port for virtual guest instance", func() { + shutdowned, err := virtualGuestService.ShutdownPublicPort(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(shutdowned).To(BeTrue()) + }) + }) + + Context("#GetAllowedHost", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getAllowedHost.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("gets allowed host for virtual guest", func() { + allowedHost, err := virtualGuestService.GetAllowedHost(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(allowedHost).NotTo(BeNil()) + Expect(allowedHost.Name).To(Equal("fake-iqn")) + }) + }) + + Context("#GetNetworkVlans", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_getNetworkVlans.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("gets network vlans for virtual guest", func() { + networkVlans, err := virtualGuestService.GetNetworkVlans(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(len(networkVlans)).To(Equal(2)) + Expect(networkVlans[0].AccountId).To(Equal(278444)) + Expect(networkVlans[0].Id).To(Equal(293731)) + Expect(networkVlans[0].ModifyDate).ToNot(BeNil()) + Expect(networkVlans[0].Name).To(Equal("AMS CLMS Pub")) + Expect(networkVlans[0].NetworkVrfId).To(Equal(0)) + Expect(networkVlans[0].Note).To(Equal("")) + Expect(networkVlans[0].PrimarySubnetId).To(Equal(517311)) + Expect(networkVlans[0].VlanNumber).To(Equal(809)) + }) + }) + + Context("#CheckHostDiskAvailability", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_checkHostDiskAvailability.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("checks for host disk availability", func() { + available, err := virtualGuestService.CheckHostDiskAvailability(virtualGuest.Id, 10*1024) + + Expect(err).ToNot(HaveOccurred()) + Expect(available).To(BeTrue()) + }) + }) + + Context("#CaptureImage", func() { + BeforeEach(func() { + virtualGuest.Id = 1234567 + fakeClient.DoRawHttpRequestResponse, err = testhelpers.ReadJsonTestFixtures("services", "SoftLayer_Virtual_Guest_Service_captureImage.json") + Expect(err).ToNot(HaveOccurred()) + }) + + It("captures the virtual guest as a container disk image template", func() { + diskImageTemplate, err := virtualGuestService.CaptureImage(virtualGuest.Id) + + Expect(err).ToNot(HaveOccurred()) + Expect(diskImageTemplate.Description).To(Equal("fake-description")) + Expect(diskImageTemplate.Name).To(Equal("fake-name")) + Expect(diskImageTemplate.Summary).To(Equal("fake-summary")) + Expect(len(diskImageTemplate.Volumes)).To(BeNumerically(">=", 1)) + Expect(diskImageTemplate.Volumes[0].Name).To(Equal("fake-volume-name")) + Expect(len(diskImageTemplate.Volumes[0].Partitions)).To(BeNumerically(">=", 1)) + Expect(diskImageTemplate.Volumes[0].Partitions[0].Name).To(Equal("fake-partition-name")) + }) + }) +}) diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/client.go b/vendor/github.com/maximilien/softlayer-go/softlayer/client.go new file mode 100644 index 000000000..115097c87 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/client.go @@ -0,0 +1,32 @@ +package softlayer + +import ( + "bytes" +) + +type Client interface { + GetService(name string) (Service, error) + + GetSoftLayer_Account_Service() (SoftLayer_Account_Service, error) + GetSoftLayer_Virtual_Guest_Service() (SoftLayer_Virtual_Guest_Service, error) + GetSoftLayer_Virtual_Disk_Image_Service() (SoftLayer_Virtual_Disk_Image_Service, error) + GetSoftLayer_Security_Ssh_Key_Service() (SoftLayer_Security_Ssh_Key_Service, error) + GetSoftLayer_Product_Order_Service() (SoftLayer_Product_Order_Service, error) + GetSoftLayer_Product_Package_Service() (SoftLayer_Product_Package_Service, error) + GetSoftLayer_Network_Storage_Service() (SoftLayer_Network_Storage_Service, error) + GetSoftLayer_Network_Storage_Allowed_Host_Service() (SoftLayer_Network_Storage_Allowed_Host_Service, error) + GetSoftLayer_Billing_Item_Cancellation_Request_Service() (SoftLayer_Billing_Item_Cancellation_Request_Service, error) + GetSoftLayer_Virtual_Guest_Block_Device_Template_Group_Service() (SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service, error) + GetSoftLayer_Hardware_Service() (SoftLayer_Hardware_Service, error) + GetSoftLayer_Dns_Domain_Service() (SoftLayer_Dns_Domain_Service, error) + GetSoftLayer_Dns_Domain_ResourceRecord_Service() (SoftLayer_Dns_Domain_ResourceRecord_Service, error) + + DoRawHttpRequest(path string, requestType string, requestBody *bytes.Buffer) ([]byte, error) + DoRawHttpRequestWithObjectMask(path string, masks []string, requestType string, requestBody *bytes.Buffer) ([]byte, error) + DoRawHttpRequestWithObjectFilter(path string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) + DoRawHttpRequestWithObjectFilterAndObjectMask(path string, masks []string, filters string, requestType string, requestBody *bytes.Buffer) ([]byte, error) + GenerateRequestBody(templateData interface{}) (*bytes.Buffer, error) + HasErrors(body map[string]interface{}) error + + CheckForHttpResponseErrors(data []byte) error +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/service.go new file mode 100644 index 000000000..fcae7572e --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/service.go @@ -0,0 +1,5 @@ +package softlayer + +type Service interface { + GetName() string +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_account_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_account_service.go new file mode 100644 index 000000000..9912cc46b --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_account_service.go @@ -0,0 +1,22 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Account_Service interface { + Service + + GetAccountStatus() (datatypes.SoftLayer_Account_Status, error) + GetVirtualGuests() ([]datatypes.SoftLayer_Virtual_Guest, error) + GetNetworkStorage() ([]datatypes.SoftLayer_Network_Storage, error) + GetIscsiNetworkStorage() ([]datatypes.SoftLayer_Network_Storage, error) + GetIscsiNetworkStorageWithFilter(filter string) ([]datatypes.SoftLayer_Network_Storage, error) + GetVirtualDiskImages() ([]datatypes.SoftLayer_Virtual_Disk_Image, error) + GetVirtualDiskImagesWithFilter(filters string) ([]datatypes.SoftLayer_Virtual_Disk_Image, error) + GetSshKeys() ([]datatypes.SoftLayer_Security_Ssh_Key, error) + GetBlockDeviceTemplateGroups() ([]datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) + GetBlockDeviceTemplateGroupsWithFilter(filters string) ([]datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) + GetDatacentersWithSubnetAllocations() ([]datatypes.SoftLayer_Location, error) + GetHardware() ([]datatypes.SoftLayer_Hardware, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_billing_item_cancellation_request_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_billing_item_cancellation_request_service.go new file mode 100644 index 000000000..f33fe9ff6 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_billing_item_cancellation_request_service.go @@ -0,0 +1,11 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Billing_Item_Cancellation_Request_Service interface { + Service + + CreateObject(request datatypes.SoftLayer_Billing_Item_Cancellation_Request) (datatypes.SoftLayer_Billing_Item_Cancellation_Request, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_resource_record_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_resource_record_service.go new file mode 100644 index 000000000..ae0a1592a --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_resource_record_service.go @@ -0,0 +1,14 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Dns_Domain_ResourceRecord_Service interface { + Service + + CreateObject(template datatypes.SoftLayer_Dns_Domain_ResourceRecord_Template) (datatypes.SoftLayer_Dns_Domain_ResourceRecord, error) + GetObject(recordId int) (datatypes.SoftLayer_Dns_Domain_ResourceRecord, error) + DeleteObject(recordId int) (bool, error) + EditObject(recordId int, template datatypes.SoftLayer_Dns_Domain_ResourceRecord) (bool, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_service.go new file mode 100644 index 000000000..e3a31cb80 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_dns_domain_service.go @@ -0,0 +1,15 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +// Modifying existing SoftLayer_Dns_Domain entries is not possible. Changes to zone names should be refactored to creation of new zones. +// https://sldn.softlayer.com/blog/phil/Getting-started-DNS +type SoftLayer_Dns_Domain_Service interface { + Service + + CreateObject(template datatypes.SoftLayer_Dns_Domain_Template) (datatypes.SoftLayer_Dns_Domain, error) + DeleteObject(dnsId int) (bool, error) + GetObject(dnsId int) (datatypes.SoftLayer_Dns_Domain, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_hardware_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_hardware_service.go new file mode 100644 index 000000000..a6e1ab1d4 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_hardware_service.go @@ -0,0 +1,12 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Hardware_Service interface { + Service + + CreateObject(template datatypes.SoftLayer_Hardware_Template) (datatypes.SoftLayer_Hardware, error) + GetObject(id string) (datatypes.SoftLayer_Hardware, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_allowed_host_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_allowed_host_service.go new file mode 100644 index 000000000..b89a069b7 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_allowed_host_service.go @@ -0,0 +1,11 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Network_Storage_Allowed_Host_Service interface { + Service + + GetCredential(allowedHostId int) (datatypes.SoftLayer_Network_Storage_Credential, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_service.go new file mode 100644 index 000000000..70a9ee526 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_network_storage_service.go @@ -0,0 +1,18 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Network_Storage_Service interface { + Service + + DeleteObject(volumeId int) (bool, error) + + CreateIscsiVolume(size int, location string) (datatypes.SoftLayer_Network_Storage, error) + DeleteIscsiVolume(volumeId int, immediateCancellationFlag bool) error + GetIscsiVolume(volumeId int) (datatypes.SoftLayer_Network_Storage, error) + HasAllowedVirtualGuest(volumeId int, vmId int) (bool, error) + AttachIscsiVolume(virtualGuest datatypes.SoftLayer_Virtual_Guest, volumeId int) (bool, error) + DetachIscsiVolume(virtualGuest datatypes.SoftLayer_Virtual_Guest, volumeId int) error +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_order_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_order_service.go new file mode 100644 index 000000000..993fcc6f3 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_order_service.go @@ -0,0 +1,13 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Product_Order_Service interface { + Service + + PlaceOrder(order datatypes.SoftLayer_Container_Product_Order) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) + PlaceContainerOrderNetworkPerformanceStorageIscsi(order datatypes.SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) + PlaceContainerOrderVirtualGuestUpgrade(order datatypes.SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_package_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_package_service.go new file mode 100644 index 000000000..7b1e6a7ae --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_product_package_service.go @@ -0,0 +1,17 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Product_Package_Service interface { + Service + + GetItemPrices(packageId int) ([]datatypes.SoftLayer_Product_Item_Price, error) + GetItemPricesBySize(packageId int, size int) ([]datatypes.SoftLayer_Product_Item_Price, error) + GetItems(packageId int) ([]datatypes.SoftLayer_Product_Item, error) + GetItemsByType(packageType string) ([]datatypes.SoftLayer_Product_Item, error) + + GetPackagesByType(packageType string) ([]datatypes.Softlayer_Product_Package, error) + GetOnePackageByType(packageType string) (datatypes.Softlayer_Product_Package, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_security_ssh_key_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_security_ssh_key_service.go new file mode 100644 index 000000000..e42cc4c4c --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_security_ssh_key_service.go @@ -0,0 +1,16 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Security_Ssh_Key_Service interface { + Service + + CreateObject(template datatypes.SoftLayer_Security_Ssh_Key) (datatypes.SoftLayer_Security_Ssh_Key, error) + GetObject(sshkeyId int) (datatypes.SoftLayer_Security_Ssh_Key, error) + EditObject(sshkeyId int, template datatypes.SoftLayer_Security_Ssh_Key) (bool, error) + DeleteObject(sshKeyId int) (bool, error) + + GetSoftwarePasswords(sshKeyId int) ([]datatypes.SoftLayer_Software_Component_Password, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_disk_image_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_disk_image_service.go new file mode 100644 index 000000000..72f4d03e7 --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_disk_image_service.go @@ -0,0 +1,11 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Virtual_Disk_Image_Service interface { + Service + + GetObject(id int) (datatypes.SoftLayer_Virtual_Disk_Image, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_block_device_template_group.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_block_device_template_group.go new file mode 100644 index 000000000..aa118d77a --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_block_device_template_group.go @@ -0,0 +1,35 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type SoftLayer_Virtual_Guest_Block_Device_Template_Group_Service interface { + Service + + AddLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) + + CreateFromExternalSource(configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) + CopyToExternalSource(configuration datatypes.SoftLayer_Container_Virtual_Guest_Block_Device_Template_Configuration) (bool, error) + + DeleteObject(id int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + DenySharingAccess(id int, accountId int) (bool, error) + + GetObject(id int) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group, error) + GetDatacenters(id int) ([]datatypes.SoftLayer_Location, error) + GetSshKeys(id int) ([]datatypes.SoftLayer_Security_Ssh_Key, error) + GetStatus(id int) (datatypes.SoftLayer_Virtual_Guest_Block_Device_Template_Group_Status, error) + + GetStorageLocations(id int) ([]datatypes.SoftLayer_Location, error) + + GetImageType(id int) (datatypes.SoftLayer_Image_Type, error) + GetImageTypeKeyName(id int) (string, error) + + GetTransaction(id int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + + PermitSharingAccess(id int, accountId int) (bool, error) + + RemoveLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) + + SetAvailableLocations(id int, locations []datatypes.SoftLayer_Location) (bool, error) +} diff --git a/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_service.go b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_service.go new file mode 100644 index 000000000..4b4ca0dbf --- /dev/null +++ b/vendor/github.com/maximilien/softlayer-go/softlayer/softlayer_virtual_guest_service.go @@ -0,0 +1,64 @@ +package softlayer + +import ( + datatypes "github.com/maximilien/softlayer-go/data_types" +) + +type UpgradeOptions struct { + Cpus int + MemoryInGB int // Softlayer allows to upgrade Memory only in GB + NicSpeed int +} + +type SoftLayer_Virtual_Guest_Service interface { + Service + + ActivatePrivatePort(instanceId int) (bool, error) + ActivatePublicPort(instanceId int) (bool, error) + AttachDiskImage(instanceId int, imageId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + AttachEphemeralDisk(instanceId int, diskSize int) (datatypes.SoftLayer_Container_Product_Order_Receipt, error) + + CaptureImage(instanceId int) (datatypes.SoftLayer_Container_Disk_Image_Capture_Template, error) + CheckHostDiskAvailability(instanceId int, diskCapacity int) (bool, error) + ConfigureMetadataDisk(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + CreateObject(template datatypes.SoftLayer_Virtual_Guest_Template) (datatypes.SoftLayer_Virtual_Guest, error) + + DeleteObject(instanceId int) (bool, error) + DetachDiskImage(instanceId int, imageId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + + EditObject(instanceId int, template datatypes.SoftLayer_Virtual_Guest) (bool, error) + + IsPingable(instanceId int) (bool, error) + IsBackendPingable(instanceId int) (bool, error) + + GetActiveTransaction(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + GetLastTransaction(instanceId int) (datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + GetActiveTransactions(instanceId int) ([]datatypes.SoftLayer_Provisioning_Version1_Transaction, error) + GetAllowedHost(instanceId int) (datatypes.SoftLayer_Network_Storage_Allowed_Host, error) + GetNetworkVlans(instanceId int) ([]datatypes.SoftLayer_Network_Vlan, error) + GetObject(instanceId int) (datatypes.SoftLayer_Virtual_Guest, error) + GetPrimaryIpAddress(instanceId int) (string, error) + GetPowerState(instanceId int) (datatypes.SoftLayer_Virtual_Guest_Power_State, error) + GetSshKeys(instanceId int) ([]datatypes.SoftLayer_Security_Ssh_Key, error) + GetTagReferences(instanceId int) ([]datatypes.SoftLayer_Tag_Reference, error) + GetUpgradeItemPrices(instanceId int) ([]datatypes.SoftLayer_Product_Item_Price, error) + GetUserData(instanceId int) ([]datatypes.SoftLayer_Virtual_Guest_Attribute, error) + + PowerCycle(instanceId int) (bool, error) + PowerOff(instanceId int) (bool, error) + PowerOffSoft(instanceId int) (bool, error) + PowerOn(instanceId int) (bool, error) + + RebootDefault(instanceId int) (bool, error) + RebootSoft(instanceId int) (bool, error) + RebootHard(instanceId int) (bool, error) + + SetMetadata(instanceId int, metadata string) (bool, error) + SetTags(instanceId int, tags []string) (bool, error) + ShutdownPrivatePort(instanceId int) (bool, error) + ShutdownPublicPort(instanceId int) (bool, error) + ReloadOperatingSystem(instanceId int, template datatypes.Image_Template_Config) error + + UpgradeObject(instanceId int, upgradeOptions *UpgradeOptions) (bool, error) + GetAvailableUpgradeItemPrices(upgradeOptions *UpgradeOptions) ([]datatypes.SoftLayer_Product_Item_Price, error) +} diff --git a/website/source/assets/stylesheets/_docs.scss b/website/source/assets/stylesheets/_docs.scss index a238b1c5c..37c7f1816 100755 --- a/website/source/assets/stylesheets/_docs.scss +++ b/website/source/assets/stylesheets/_docs.scss @@ -36,6 +36,7 @@ body.layout-postgresql, body.layout-powerdns, body.layout-rundeck, body.layout-statuscake, +body.layout-softlayer, body.layout-template, body.layout-tls, body.layout-ultradns, diff --git a/website/source/docs/providers/softlayer/index.html.markdown b/website/source/docs/providers/softlayer/index.html.markdown new file mode 100644 index 000000000..efb5254a8 --- /dev/null +++ b/website/source/docs/providers/softlayer/index.html.markdown @@ -0,0 +1,84 @@ +--- +layout: "softlayer" +page_title: "Provider: SoftLayer" +sidebar_current: "docs-softlayer-index" +description: |- + The Docker provider is used to interact with Docker containers and images. +--- + +# SoftLayer Provider + +The SoftLayer provider is used to manage SoftLayer resources. + +Use the navigation to the left to read about the available resources. + +
+Note: The SoftLayer provider is new as of Terraform 0.X. +It is ready to be used but many features are still being added. If there +is a SoftLayer feature missing, please report it in the GitHub repo. +
+ +## Example Usage + +Here is an example that will setup the following: ++ An SSH key resource. ++ A virtual server resource that uses an existing SSH key. ++ A virtual server resource using an existing SSH key and a Terraform managed SSH key (created as "test_key_1" in the example below). + +(create this as sl.tf and run terraform commands from this directory): + +```hcl +provider "softlayer" { + username = "" + api_key = "" +} + +# This will create a new SSH key that will show up under the \ +# Devices>Manage>SSH Keys in the SoftLayer console. +resource "softlayer_ssh_key" "test_key_1" { + name = "test_key_1" + public_key = "${file(\"~/.ssh/id_rsa_test_key_1.pub\")}" + # Windows Example: + # public_key = "${file(\"C:\ssh\keys\path\id_rsa_test_key_1.pub\")}" +} + +# Virtual Server created with existing SSH Key already in SoftLayer \ +# inventory and not created using this Terraform template. +resource "softlayer_virtual_guest" "my_server_1" { + name = "my_server_1" + domain = "example.com" + ssh_keys = ["123456"] + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 10 + cpu = 1 + ram = 1024 +} + +# Virtual Server created with a mix of previously existing and \ +# Terraform created/managed resources. +resource "softlayer_virtual_guest" "my_server_2" { + name = "my_server_2" + domain = "example.com" + ssh_keys = ["123456", "${softlayer_ssh_key.test_key_1.id}"] + image = "CENTOS_6_64" + region = "ams01" + public_network_speed = 10 + cpu = 1 + ram = 1024 +} +``` + +You'll need to provide your SoftLayer username and API key, +so that Terraform can connect. If you don't want to put +credentials in your configuration file, you can leave them +out: + +``` +provider "softlayer" {} +``` + +...and instead set these environment variables: + +- **SOFTLAYER_USERNAME**: Your SoftLayer username +- **SOFTLAYER_API_KEY**: Your API key diff --git a/website/source/docs/providers/softlayer/r/ssh_key.html.markdown b/website/source/docs/providers/softlayer/r/ssh_key.html.markdown new file mode 100644 index 000000000..3906620c3 --- /dev/null +++ b/website/source/docs/providers/softlayer/r/ssh_key.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "softlayer" +page_title: "SoftLayer: ssh_key" +sidebar_current: "docs-softlayer-resource-ssh-key" +description: |- + Manages SoftLayer SSH Keys. +--- + +# softlayer\ssh_key + +Provides SSK keys. This allows SSH keys to be created, updated and deleted. +For additional details please refer to [API documentation](http://sldn.softlayer.com/reference/datatypes/SoftLayer_Security_Ssh_Key). + +## Example Usage + +``` +resource "softlayer_ssh_key" "test_ssh_key" { + name = "test_ssh_key_name" + notes = "test_ssh_key_notes" + public_key = "ssh-rsa " +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) A descriptive name used to identify a ssh key. +* `public_key` - (Required) The public ssh key. +* `notes` - (Optional) A small note about a ssh key to use at your discretion. + +Fields `name` and `notes` are editable. + +## Attributes Reference + +The following attributes are exported: + +* `id` - id of the new ssh key +* `fingerprint` - sequence of bytes to authenticate or lookup a longer ssh key. diff --git a/website/source/docs/providers/softlayer/r/virtual_guest.html.markdown b/website/source/docs/providers/softlayer/r/virtual_guest.html.markdown new file mode 100644 index 000000000..54d8f0edb --- /dev/null +++ b/website/source/docs/providers/softlayer/r/virtual_guest.html.markdown @@ -0,0 +1,134 @@ +--- +layout: "softlayer" +page_title: "SoftLayer: virtual_guest" +sidebar_current: "docs-softlayer-resource-virtual-guest" +description: |- + Manages SoftLayer Virtual Guests. +--- + +# softlayer\virtual_guest + +Provides virtual guest resource. This allows virtual guests to be created, updated +and deleted. For additional details please refer to [API documentation](http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest). + +## Example Usage + +``` +# Create a new virtual guest using image "Debian" +resource "softlayer_virtual_guest" "twc_terraform_sample" { + name = "twc-terraform-sample-name" + domain = "bar.example.com" + image = "DEBIAN_7_64" + region = "ams01" + public_network_speed = 10 + hourly_billing = true + private_network_only = false + cpu = 1 + ram = 1024 + disks = [25, 10, 20] + user_data = "{\"value\":\"newvalue\"}" + dedicated_acct_host_only = true + local_disk = false + frontend_vlan_id = 1085155 + backend_vlan_id = 1085157 +} +``` + +``` +# Create a new virtual guest using block device template +resource "softlayer_virtual_guest" "terraform-sample-BDTGroup" { + name = "terraform-sample-blockDeviceTemplateGroup" + domain = "bar.example.com" + region = "ams01" + public_network_speed = 10 + hourly_billing = false + cpu = 1 + ram = 1024 + local_disk = false + block_device_template_group_gid = "****-****-****-****-****" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` | *string* + * Hostname for the computing instance. + * **Required** +* `domain` | *string* + * Domain for the computing instance. + * **Required** +* `cpu` | *int* + * The number of CPU cores to allocate. + * **Required** +* `ram` | *int* + * The amount of memory to allocate in megabytes. + * **Required** +* `region` | *string* + * Specifies which datacenter the instance is to be provisioned in. + * **Required** +* `hourly_billing` | *boolean* + * Specifies the billing type for the instance. When true the computing instance will be billed on hourly usage, otherwise it will be billed on a monthly basis. + * **Required** +* `local_disk` | *boolean* + * Specifies the disk type for the instance. When true the disks for the computing instance will be provisioned on the host which it runs, otherwise SAN disks will be provisioned. + * **Required** +* `dedicated_acct_host_only` | *boolean* + * Specifies whether or not the instance must only run on hosts with instances from the same account + * *Default*: nil + * *Optional* +* `image` | *string* + * An identifier for the operating system to provision the computing instance with. + * **Conditionally required** - Disallowed when blockDeviceTemplateGroup.globalIdentifier is provided, as the template will specify the operating system. +* `block_device_template_group_gid` | *string* + * A global identifier for the template to be used to provision the computing instance. + * **Conditionally required** - Disallowed when operatingSystemReferenceCode is provided, as the template will specify the operating system. +* `public_network_speed` | *int* + * Specifies the connection speed for the instance's network components. + * *Default*: 10 + * *Optional* +* `private_network_only` | *boolean* + * Specifies whether or not the instance only has access to the private network. When true this flag specifies that a compute instance is to only have access to the private network. + * *Default*: False + * *Optional* +* `frontend_vlan_id` | *int* + * Specifies the network vlan which is to be used for the frontend interface of the computing instance. + * *Default*: nil + * *Optional* +* `backend_vlan_id` | *int* + * Specifies the network vlan which is to be used for the backend interface of the computing instance. + * *Default*: nil + * *Optional* +* `disks` | *array* + * Block device and disk image settings for the computing instance + * *Optional* + * *Default*: The smallest available capacity for the primary disk will be used. If an image template is specified the disk capacity will be be provided by the template. +* `user_data` | *string* + * Arbitrary data to be made available to the computing instance. + * *Default*: nil + * *Optional* +* `ssh_keys` | *array* + * SSH keys to install on the computing instance upon provisioning. + * *Default*: nil + * *Optional* +* `ipv4_address` | *string* + * Uses editObject call, template data [defined here](https://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest). + * *Default*: nil + * *Optional* +* `ipv4_address_private` | *string* + * Uses editObject call, template data [defined here](https://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest). + * *Default*: nil + * *Optional* +* `post_install_script_uri` | *string* + * As defined in the [SoftLayer_Virtual_Guest_SupplementalCreateObjectOptions](https://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest_SupplementalCreateObjectOptions). + * *Default*: nil + * *Optional* + +## Attributes Reference + +The following attributes are exported: + +* `id` - id of the virtual guest. + + diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 462fcc34f..d357c6d53 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -253,6 +253,10 @@ StatusCake + > + SoftLayer + + > Template diff --git a/website/source/layouts/softlayer.erb b/website/source/layouts/softlayer.erb new file mode 100644 index 000000000..16d3ec13f --- /dev/null +++ b/website/source/layouts/softlayer.erb @@ -0,0 +1,29 @@ +<% wrap_layout :inner do %> + <% content_for :sidebar do %> + + <% end %> + + <%= yield %> +<% end %>