diff --git a/CHANGELOG.md b/CHANGELOG.md index a20d1aefc..9be92c79e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FEATURES: * **New Resource:** `aws_lightsail_static_ip` [GH-13175] * **New Resource:** `aws_lightsail_static_ip_attachment` [GH-13207] * **New Resource:** `aws_ses_domain_identity` [GH-13098] + * **New Resource**: `azurerm_managed_disk` [GH-12455] * **New Resource:** `kubernetes_secret` [GH-12960] * **New Data Source:** `aws_iam_role` [GH-13213] @@ -35,16 +36,18 @@ IMPROVEMENTS: * provider/aws: Add support for treat_missing_data to cloudwatch_metric_alarm [GH-13358] * provider/aws: Add support for evaluate_low_sample_count_percentiles to cloudwatch_metric_alarm [GH-13371] * provider/aws: Fix `aws_s3_bucket` drift detection of logging options [GH-13281] + * provider/bitbucket: Improved error handling [GH-13390] * provider/cloudstack: Do not force a new resource when updating `cloudstack_loadbalancer_rule` members [GH-11786] * provider/github: Handle the case when issue labels already exist [GH-13182] * provider/google: Mark `google_container_cluster`'s `client_key` & `password` inside `master_auth` as sensitive [GH-13148] * provider/triton: Move to joyent/triton-go [GH-13225] - + BUG FIXES: * core: Escaped interpolation-like sequences (like `$${foo}`) now permitted in variable defaults [GH-13137] * core: Fix strange issues with computed values in provider configuration that were worked around with `-input=false` [GH-11264], [GH-13264] * core: Fix crash when providing nested maps as variable values in a `module` block [GH-13343] + * core: `connection` block attributes are now subject to basic validation of attribute names during validate walk [GH-13400] * provider/aws: Add Support for maintenance_window and back_window to rds_cluster_instance [GH-13134] * provider/aws: Increase timeout for AMI registration [GH-13159] * provider/aws: Increase timeouts for ELB [GH-13161] @@ -67,6 +70,7 @@ BUG FIXES: * provider/aws: Fix KMS Key reading with Exists method [GH-13348] * provider/azurerm: Network Security Group - ignoring protocol casing at Import time [GH-13153] * provider/azurerm: Fix crash when importing Local Network Gateways [GH-13261] + * provider/bitbucket: Fixed issue where provider would fail with an "EOF" error on some operations [GH-13390] * provider/openstack: Refresh volume_attachment from state if NotFound [GH-13342] * provider/profitbricks: Changed output type of ips variable of ip_block ProfitBricks resource [GH-13290] diff --git a/backend/remote-state/consul/client.go b/backend/remote-state/consul/client.go index cd5971163..b11f31ba1 100644 --- a/backend/remote-state/consul/client.go +++ b/backend/remote-state/consul/client.go @@ -121,16 +121,15 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { default: if c.lockCh != nil { // we have an active lock already - return "", nil + return "", fmt.Errorf("state %q already locked", c.Path) } } if c.consulLock == nil { opts := &consulapi.LockOptions{ Key: c.Path + lockSuffix, - // We currently don't procide any options to block terraform and - // retry lock acquisition, but we can wait briefly in case the - // lock is about to be freed. + // only wait briefly, so terraform has the choice to fail fast or + // retry as needed. LockWaitTime: time.Second, LockTryOnce: true, } @@ -191,6 +190,10 @@ func (c *RemoteClient) Unlock(id string) error { err := c.consulLock.Unlock() c.lockCh = nil + // This is only cleanup, and will fail if the lock was immediately taken by + // another client, so we don't report an error to the user here. + c.consulLock.Destroy() + kv := c.Client.KV() _, delErr := kv.Delete(c.Path+lockInfoSuffix, nil) if delErr != nil { diff --git a/backend/remote-state/consul/client_test.go b/backend/remote-state/consul/client_test.go index 57b7c452e..dc7988135 100644 --- a/backend/remote-state/consul/client_test.go +++ b/backend/remote-state/consul/client_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/state/remote" ) @@ -98,3 +99,43 @@ func TestConsul_stateLock(t *testing.T) { remote.TestRemoteLocks(t, sA.(*remote.State).Client, sB.(*remote.State).Client) } + +func TestConsul_destroyLock(t *testing.T) { + srv := newConsulTestServer(t) + defer srv.Stop() + + // Get the backend + b := backend.TestBackendConfig(t, New(), map[string]interface{}{ + "address": srv.HTTPAddr, + "path": fmt.Sprintf("tf-unit/%s", time.Now().String()), + }) + + // Grab the client + s, err := b.State(backend.DefaultStateName) + if err != nil { + t.Fatalf("err: %s", err) + } + + c := s.(*remote.State).Client.(*RemoteClient) + + info := state.NewLockInfo() + id, err := c.Lock(info) + if err != nil { + t.Fatal(err) + } + + lockPath := c.Path + lockSuffix + + if err := c.Unlock(id); err != nil { + t.Fatal(err) + } + + // get the lock val + pair, _, err := c.Client.KV().Get(lockPath, nil) + if err != nil { + t.Fatal(err) + } + if pair != nil { + t.Fatalf("lock key not cleaned up at: %s", pair.Key) + } +} diff --git a/builtin/providers/aws/data_source_aws_ecs_task_definition_test.go b/builtin/providers/aws/data_source_aws_ecs_task_definition_test.go index 545da0714..6d6ffa35a 100644 --- a/builtin/providers/aws/data_source_aws_ecs_task_definition_test.go +++ b/builtin/providers/aws/data_source_aws_ecs_task_definition_test.go @@ -15,10 +15,10 @@ func TestAccAWSEcsDataSource_ecsTaskDefinition(t *testing.T) { resource.TestStep{ Config: testAccCheckAwsEcsTaskDefinitionDataSourceConfig, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr("data.aws_ecs_task_definition.mongo", "id", regexp.MustCompile("^arn:aws:ecs:us-west-2:[0-9]{12}:task-definition/mongodb:[1-9]*[0-9]$")), + resource.TestMatchResourceAttr("data.aws_ecs_task_definition.mongo", "id", regexp.MustCompile("^arn:aws:ecs:us-west-2:[0-9]{12}:task-definition/mongodb:[1-9][0-9]*$")), resource.TestCheckResourceAttr("data.aws_ecs_task_definition.mongo", "family", "mongodb"), resource.TestCheckResourceAttr("data.aws_ecs_task_definition.mongo", "network_mode", "bridge"), - resource.TestMatchResourceAttr("data.aws_ecs_task_definition.mongo", "revision", regexp.MustCompile("^[1-9]*[0-9]$")), + resource.TestMatchResourceAttr("data.aws_ecs_task_definition.mongo", "revision", regexp.MustCompile("^[1-9][0-9]*$")), resource.TestCheckResourceAttr("data.aws_ecs_task_definition.mongo", "status", "ACTIVE"), resource.TestMatchResourceAttr("data.aws_ecs_task_definition.mongo", "task_role_arn", regexp.MustCompile("^arn:aws:iam::[0-9]{12}:role/mongo_role$")), ), diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index a5e10e034..ef21f2492 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -446,7 +446,6 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e d.Set("health_check_type", g.HealthCheckType) d.Set("launch_configuration", g.LaunchConfigurationName) d.Set("load_balancers", flattenStringList(g.LoadBalancerNames)) - d.Set("target_group_arns", flattenStringList(g.TargetGroupARNs)) if err := d.Set("suspended_processes", flattenAsgSuspendedProcesses(g.SuspendedProcesses)); err != nil { log.Printf("[WARN] Error setting suspended_processes for %q: %s", d.Id(), err) diff --git a/builtin/providers/aws/resource_aws_autoscaling_group_test.go b/builtin/providers/aws/resource_aws_autoscaling_group_test.go index 1c310433f..ee17f8844 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group_test.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group_test.go @@ -445,15 +445,6 @@ func TestAccAWSAutoScalingGroup_ALB_TargetGroups(t *testing.T) { "aws_autoscaling_group.bar", "target_group_arns.#", "1"), ), }, - - resource.TestStep{ - Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre, - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), - resource.TestCheckResourceAttr( - "aws_autoscaling_group.bar", "target_group_arns.#", "0"), - ), - }, }, }) } diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index bbf15712f..8535b67c7 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -11,6 +11,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/containerregistry" "github.com/Azure/azure-sdk-for-go/arm/containerservice" + "github.com/Azure/azure-sdk-for-go/arm/disk" "github.com/Azure/azure-sdk-for-go/arm/eventhub" "github.com/Azure/azure-sdk-for-go/arm/keyvault" "github.com/Azure/azure-sdk-for-go/arm/network" @@ -47,6 +48,8 @@ type ArmClient struct { vmImageClient compute.VirtualMachineImagesClient vmClient compute.VirtualMachinesClient + diskClient disk.DisksClient + appGatewayClient network.ApplicationGatewaysClient ifaceClient network.InterfacesClient loadBalancerClient network.LoadBalancersClient @@ -245,6 +248,12 @@ func (c *Config) getArmClient() (*ArmClient, error) { csc.Sender = autorest.CreateSender(withRequestLogging()) client.containerServicesClient = csc + dkc := disk.NewDisksClientWithBaseURI(endpoint, c.SubscriptionID) + setUserAgent(&dkc.Client) + dkc.Authorizer = spt + dkc.Sender = autorest.CreateSender(withRequestLogging()) + client.diskClient = dkc + ehc := eventhub.NewEventHubsClientWithBaseURI(endpoint, c.SubscriptionID) setUserAgent(&ehc.Client) ehc.Authorizer = spt diff --git a/builtin/providers/azurerm/import_arm_managed_disk_test.go b/builtin/providers/azurerm/import_arm_managed_disk_test.go new file mode 100644 index 000000000..51eaa6abd --- /dev/null +++ b/builtin/providers/azurerm/import_arm_managed_disk_test.go @@ -0,0 +1,30 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAzureRMManagedDisk_importEmpty(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMManagedDisk_empty, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMManagedDiskDestroy, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: "azurerm_managed_disk.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/azurerm/import_arm_virtual_machine_test.go b/builtin/providers/azurerm/import_arm_virtual_machine_test.go index 806d44987..f6b72e208 100644 --- a/builtin/providers/azurerm/import_arm_virtual_machine_test.go +++ b/builtin/providers/azurerm/import_arm_virtual_machine_test.go @@ -19,11 +19,39 @@ func TestAccAzureRMVirtualMachine_importBasic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMVirtualMachineDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: config, }, - resource.TestStep{ + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "delete_data_disks_on_termination", + "delete_os_disk_on_termination", + }, + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_importBasic_managedDisk(t *testing.T) { + resourceName := "azurerm_virtual_machine.test" + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_explicit, ri, ri, ri, ri, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + }, + + { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 8364fe4cf..c57aae2c2 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -85,6 +85,8 @@ func Provider() terraform.ResourceProvider { "azurerm_lb_probe": resourceArmLoadBalancerProbe(), "azurerm_lb_rule": resourceArmLoadBalancerRule(), + "azurerm_managed_disk": resourceArmManagedDisk(), + "azurerm_key_vault": resourceArmKeyVault(), "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), "azurerm_network_interface": resourceArmNetworkInterface(), diff --git a/builtin/providers/azurerm/resource_arm_managed_disk.go b/builtin/providers/azurerm/resource_arm_managed_disk.go new file mode 100644 index 000000000..9f3fdc4c5 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_managed_disk.go @@ -0,0 +1,238 @@ +package azurerm + +import ( + "fmt" + "github.com/Azure/azure-sdk-for-go/arm/disk" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "log" + "net/http" + "strings" +) + +func resourceArmManagedDisk() *schema.Resource { + return &schema.Resource{ + Create: resourceArmManagedDiskCreate, + Read: resourceArmManagedDiskRead, + Update: resourceArmManagedDiskCreate, + Delete: resourceArmManagedDiskDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": locationSchema(), + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "storage_account_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(disk.PremiumLRS), + string(disk.StandardLRS), + }, true), + }, + + "create_option": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(disk.Import), + string(disk.Empty), + string(disk.Copy), + }, true), + }, + + "source_uri": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "source_resource_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "os_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(disk.Windows), + string(disk.Linux), + }, true), + }, + + "disk_size_gb": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validateDiskSizeGB, + }, + + "tags": tagsSchema(), + }, + } +} + +func validateDiskSizeGB(v interface{}, k string) (ws []string, errors []error) { + value := v.(int) + if value < 1 || value > 1023 { + errors = append(errors, fmt.Errorf( + "The `disk_size_gb` can only be between 1 and 1023")) + } + return +} + +func resourceArmManagedDiskCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + diskClient := client.diskClient + + log.Printf("[INFO] preparing arguments for Azure ARM Managed Disk creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + tags := d.Get("tags").(map[string]interface{}) + expandedTags := expandTags(tags) + + createDisk := disk.Model{ + Name: &name, + Location: &location, + Tags: expandedTags, + } + + storageAccountType := d.Get("storage_account_type").(string) + osType := d.Get("os_type").(string) + + createDisk.Properties = &disk.Properties{ + AccountType: disk.StorageAccountTypes(storageAccountType), + OsType: disk.OperatingSystemTypes(osType), + } + + if v := d.Get("disk_size_gb"); v != 0 { + diskSize := int32(v.(int)) + createDisk.Properties.DiskSizeGB = &diskSize + } + createOption := d.Get("create_option").(string) + + creationData := &disk.CreationData{ + CreateOption: disk.CreateOption(createOption), + } + + if strings.EqualFold(createOption, string(disk.Import)) { + if sourceUri := d.Get("source_uri").(string); sourceUri != "" { + creationData.SourceURI = &sourceUri + } else { + return fmt.Errorf("[ERROR] source_uri must be specified when create_option is `%s`", disk.Import) + } + } else if strings.EqualFold(createOption, string(disk.Copy)) { + if sourceResourceId := d.Get("source_resource_id").(string); sourceResourceId != "" { + creationData.SourceResourceID = &sourceResourceId + } else { + return fmt.Errorf("[ERROR] source_resource_id must be specified when create_option is `%s`", disk.Copy) + } + } + + createDisk.CreationData = creationData + + _, diskErr := diskClient.CreateOrUpdate(resGroup, name, createDisk, make(chan struct{})) + if diskErr != nil { + return diskErr + } + + read, err := diskClient.Get(resGroup, name) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("[ERROR] Cannot read Managed Disk %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmManagedDiskRead(d, meta) +} + +func resourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error { + diskClient := meta.(*ArmClient).diskClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["disks"] + + resp, err := diskClient.Get(resGroup, name) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + return fmt.Errorf("[ERROR] Error making Read request on Azure Managed Disk %s (resource group %s): %s", name, resGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("location", resp.Location) + + if resp.Properties != nil { + flattenAzureRmManagedDiskProperties(d, resp.Properties) + } + + if resp.CreationData != nil { + flattenAzureRmManagedDiskCreationData(d, resp.CreationData) + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmManagedDiskDelete(d *schema.ResourceData, meta interface{}) error { + diskClient := meta.(*ArmClient).diskClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["disks"] + + if _, err = diskClient.Delete(resGroup, name, make(chan struct{})); err != nil { + return err + } + + return nil +} + +func flattenAzureRmManagedDiskProperties(d *schema.ResourceData, properties *disk.Properties) { + d.Set("storage_account_type", string(properties.AccountType)) + if properties.DiskSizeGB != nil { + d.Set("disk_size_gb", *properties.DiskSizeGB) + } + if properties.OsType != "" { + d.Set("os_type", string(properties.OsType)) + } +} + +func flattenAzureRmManagedDiskCreationData(d *schema.ResourceData, creationData *disk.CreationData) { + d.Set("create_option", string(creationData.CreateOption)) + if creationData.SourceURI != nil { + d.Set("source_uri", *creationData.SourceURI) + } +} diff --git a/builtin/providers/azurerm/resource_arm_managed_disk_test.go b/builtin/providers/azurerm/resource_arm_managed_disk_test.go new file mode 100644 index 000000000..b7512e2a7 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_managed_disk_test.go @@ -0,0 +1,321 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/disk" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMManagedDisk_empty(t *testing.T) { + var d disk.Model + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMManagedDisk_empty, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMManagedDiskDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMManagedDiskExists("azurerm_managed_disk.test", &d, true), + ), + }, + }, + }) +} + +func TestAccAzureRMManagedDisk_import(t *testing.T) { + var d disk.Model + var vm compute.VirtualMachine + ri := acctest.RandInt() + vmConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine, ri, ri, ri, ri, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMManagedDisk_import, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMManagedDiskDestroy, + Steps: []resource.TestStep{ + { + //need to create a vm and then delete it so we can use the vhd to test import + Config: vmConfig, + Destroy: false, + ExpectNonEmptyPlan: true, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + testDeleteAzureRMVirtualMachine("azurerm_virtual_machine.test"), + ), + }, + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMManagedDiskExists("azurerm_managed_disk.test", &d, true), + ), + }, + }, + }) +} + +func TestAccAzureRMManagedDisk_copy(t *testing.T) { + var d disk.Model + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMManagedDisk_copy, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMManagedDiskDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMManagedDiskExists("azurerm_managed_disk.test", &d, true), + ), + }, + }, + }) +} + +func TestAccAzureRMManagedDisk_update(t *testing.T) { + var d disk.Model + + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMManagedDisk_empty, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMManagedDisk_empty_updated, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMManagedDiskDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMManagedDiskExists("azurerm_managed_disk.test", &d, true), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "tags.%", "2"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "tags.environment", "acctest"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "tags.cost-center", "ops"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "disk_size_gb", "1"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "storage_account_type", string(disk.StandardLRS)), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMManagedDiskExists("azurerm_managed_disk.test", &d, true), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "tags.%", "1"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "tags.environment", "acctest"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "disk_size_gb", "2"), + resource.TestCheckResourceAttr( + "azurerm_managed_disk.test", "storage_account_type", string(disk.PremiumLRS)), + ), + }, + }, + }) +} + +func testCheckAzureRMManagedDiskExists(name string, d *disk.Model, shouldExist bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + dName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for disk: %s", dName) + } + + conn := testAccProvider.Meta().(*ArmClient).diskClient + + resp, err := conn.Get(resourceGroup, dName) + if err != nil { + return fmt.Errorf("Bad: Get on diskClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound && shouldExist { + return fmt.Errorf("Bad: ManagedDisk %q (resource group %q) does not exist", dName, resourceGroup) + } + if resp.StatusCode != http.StatusNotFound && !shouldExist { + return fmt.Errorf("Bad: ManagedDisk %q (resource group %q) still exists", dName, resourceGroup) + } + + *d = resp + + return nil + } +} + +func testCheckAzureRMManagedDiskDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).diskClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_managed_disk" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Managed Disk still exists: \n%#v", resp.Properties) + } + } + + return nil +} + +func testDeleteAzureRMVirtualMachine(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + vmName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for virtual machine: %s", vmName) + } + + conn := testAccProvider.Meta().(*ArmClient).vmClient + + _, err := conn.Delete(resourceGroup, vmName, make(chan struct{})) + if err != nil { + return fmt.Errorf("Bad: Delete on vmClient: %s", err) + } + + return nil + } +} + +var testAccAzureRMManagedDisk_empty = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_managed_disk" "test" { + name = "acctestd-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "1" + + tags { + environment = "acctest" + cost-center = "ops" + } +}` + +var testAccAzureRMManagedDisk_import = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_storage_account" "test" { + name = "accsa%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "West US 2" + account_type = "Standard_LRS" + + tags { + environment = "staging" + } +} + +resource "azurerm_storage_container" "test" { + name = "vhds" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} + +resource "azurerm_managed_disk" "test" { + name = "acctestd-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Import" + source_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/myosdisk1.vhd" + disk_size_gb = "45" + + tags { + environment = "acctest" + } +}` + +var testAccAzureRMManagedDisk_copy = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_managed_disk" "source" { + name = "acctestd1-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "1" + + tags { + environment = "acctest" + cost-center = "ops" + } +} + +resource "azurerm_managed_disk" "test" { + name = "acctestd2-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Copy" + source_resource_id = "${azurerm_managed_disk.source.id}" + disk_size_gb = "1" + + tags { + environment = "acctest" + cost-center = "ops" + } +}` + +var testAccAzureRMManagedDisk_empty_updated = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_managed_disk" "test" { + name = "acctestd-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Premium_LRS" + create_option = "Empty" + disk_size_gb = "2" + + tags { + environment = "acctest" + } +}` diff --git a/builtin/providers/azurerm/resource_arm_storage_account.go b/builtin/providers/azurerm/resource_arm_storage_account.go index d47b089f4..721ab8097 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account.go +++ b/builtin/providers/azurerm/resource_arm_storage_account.go @@ -1,7 +1,6 @@ package azurerm import ( - "context" "fmt" "log" "net/http" @@ -188,10 +187,8 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e } // Create - cancelCtx, cancelFunc := context.WithTimeout(client.StopContext, 1*time.Hour) _, createErr := storageClient.Create( - resourceGroupName, storageAccountName, opts, cancelCtx.Done()) - cancelFunc() + resourceGroupName, storageAccountName, opts, make(chan struct{})) // The only way to get the ID back apparently is to read the resource again read, err := storageClient.GetProperties(resourceGroupName, storageAccountName) diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine.go b/builtin/providers/azurerm/resource_arm_virtual_machine.go index 9a1607472..e3fe29808 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine.go @@ -11,6 +11,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" riviera "github.com/jen20/riviera/azure" ) @@ -141,10 +142,29 @@ func resourceArmVirtualMachine() *schema.Resource { "vhd_uri": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, }, + "managed_disk_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ConflictsWith: []string{"storage_os_disk.vhd_uri"}, + }, + + "managed_disk_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"storage_os_disk.vhd_uri"}, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.PremiumLRS), + string(compute.StandardLRS), + }, true), + }, + "image_uri": { Type: schema.TypeString, Optional: true, @@ -189,7 +209,26 @@ func resourceArmVirtualMachine() *schema.Resource { "vhd_uri": { Type: schema.TypeString, - Required: true, + Optional: true, + }, + + "managed_disk_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ConflictsWith: []string{"storage_data_disk.vhd_uri"}, + }, + + "managed_disk_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"storage_data_disk.vhd_uri"}, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.PremiumLRS), + string(compute.StandardLRS), + }, true), }, "create_option": { @@ -204,9 +243,10 @@ func resourceArmVirtualMachine() *schema.Resource { }, "disk_size_gb": { - Type: schema.TypeInt, - Optional: true, - Computed: true, + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validateDiskSizeGB, }, "lun": { @@ -453,15 +493,6 @@ func validateLicenseType(v interface{}, k string) (ws []string, errors []error) return } -func validateDiskSizeGB(v interface{}, k string) (ws []string, errors []error) { - value := v.(int) - if value < 1 || value > 1023 { - errors = append(errors, fmt.Errorf( - "The `disk_size_gb` can only be between 1 and 1023")) - } - return -} - func resourceArmVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) vmClient := client.vmClient @@ -685,21 +716,29 @@ func resourceArmVirtualMachineDelete(d *schema.ResourceData, meta interface{}) e // delete OS Disk if opted in if deleteOsDisk := d.Get("delete_os_disk_on_termination").(bool); deleteOsDisk { - log.Printf("[INFO] delete_os_disk_on_termination is enabled, deleting") + log.Printf("[INFO] delete_os_disk_on_termination is enabled, deleting disk from %s", name) osDisk, err := expandAzureRmVirtualMachineOsDisk(d) if err != nil { return fmt.Errorf("Error expanding OS Disk: %s", err) } - if err = resourceArmVirtualMachineDeleteVhd(*osDisk.Vhd.URI, meta); err != nil { - return fmt.Errorf("Error deleting OS Disk VHD: %s", err) + if osDisk.Vhd != nil { + if err = resourceArmVirtualMachineDeleteVhd(*osDisk.Vhd.URI, meta); err != nil { + return fmt.Errorf("Error deleting OS Disk VHD: %s", err) + } + } else if osDisk.ManagedDisk != nil { + if err = resourceArmVirtualMachineDeleteManagedDisk(*osDisk.ManagedDisk.ID, meta); err != nil { + return fmt.Errorf("Error deleting OS Managed Disk: %s", err) + } + } else { + return fmt.Errorf("Unable to locate OS managed disk properties from %s", name) } } // delete Data disks if opted in if deleteDataDisks := d.Get("delete_data_disks_on_termination").(bool); deleteDataDisks { - log.Printf("[INFO] delete_data_disks_on_termination is enabled, deleting each data disk") + log.Printf("[INFO] delete_data_disks_on_termination is enabled, deleting each data disk from %s", name) disks, err := expandAzureRmVirtualMachineDataDisk(d) if err != nil { @@ -707,8 +746,16 @@ func resourceArmVirtualMachineDelete(d *schema.ResourceData, meta interface{}) e } for _, disk := range disks { - if err = resourceArmVirtualMachineDeleteVhd(*disk.Vhd.URI, meta); err != nil { - return fmt.Errorf("Error deleting Data Disk VHD: %s", err) + if disk.Vhd != nil { + if err = resourceArmVirtualMachineDeleteVhd(*disk.Vhd.URI, meta); err != nil { + return fmt.Errorf("Error deleting Data Disk VHD: %s", err) + } + } else if disk.ManagedDisk != nil { + if err = resourceArmVirtualMachineDeleteManagedDisk(*disk.ManagedDisk.ID, meta); err != nil { + return fmt.Errorf("Error deleting Data Managed Disk: %s", err) + } + } else { + return fmt.Errorf("Unable to locate data managed disk properties from %s", name) } } } @@ -752,6 +799,24 @@ func resourceArmVirtualMachineDeleteVhd(uri string, meta interface{}) error { return nil } +func resourceArmVirtualMachineDeleteManagedDisk(managedDiskID string, meta interface{}) error { + diskClient := meta.(*ArmClient).diskClient + + id, err := parseAzureResourceID(managedDiskID) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["disks"] + + _, err = diskClient.Delete(resGroup, name, make(chan struct{})) + if err != nil { + return fmt.Errorf("Error deleting Managed Disk (%s %s) %s", name, resGroup, err) + } + + return nil +} + func resourceArmVirtualMachinePlanHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) @@ -784,8 +849,9 @@ func resourceArmVirtualMachineStorageOsDiskHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) - buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string))) - + if m["vhd_uri"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string))) + } return hashcode.String(buf.String()) } @@ -883,7 +949,13 @@ func flattenAzureRmVirtualMachineDataDisk(disks *[]compute.DataDisk) interface{} for i, disk := range *disks { l := make(map[string]interface{}) l["name"] = *disk.Name - l["vhd_uri"] = *disk.Vhd.URI + if disk.Vhd != nil { + l["vhd_uri"] = *disk.Vhd.URI + } + if disk.ManagedDisk != nil { + l["managed_disk_type"] = string(disk.ManagedDisk.StorageAccountType) + l["managed_disk_id"] = *disk.ManagedDisk.ID + } l["create_option"] = disk.CreateOption l["caching"] = string(disk.Caching) if disk.DiskSizeGB != nil { @@ -982,7 +1054,13 @@ func flattenAzureRmVirtualMachineOsProfileLinuxConfiguration(config *compute.Lin func flattenAzureRmVirtualMachineOsDisk(disk *compute.OSDisk) []interface{} { result := make(map[string]interface{}) result["name"] = *disk.Name - result["vhd_uri"] = *disk.Vhd.URI + if disk.Vhd != nil { + result["vhd_uri"] = *disk.Vhd.URI + } + if disk.ManagedDisk != nil { + result["managed_disk_type"] = string(disk.ManagedDisk.StorageAccountType) + result["managed_disk_id"] = *disk.ManagedDisk.ID + } result["create_option"] = disk.CreateOption result["caching"] = disk.Caching if disk.DiskSizeGB != nil { @@ -1157,22 +1235,22 @@ func expandAzureRmVirtualMachineOsProfileWindowsConfig(d *schema.ResourceData) ( if v := osProfileConfig["winrm"]; v != nil { winRm := v.([]interface{}) if len(winRm) > 0 { - winRmListners := make([]compute.WinRMListener, 0, len(winRm)) + winRmListeners := make([]compute.WinRMListener, 0, len(winRm)) for _, winRmConfig := range winRm { config := winRmConfig.(map[string]interface{}) protocol := config["protocol"].(string) - winRmListner := compute.WinRMListener{ + winRmListener := compute.WinRMListener{ Protocol: compute.ProtocolTypes(protocol), } if v := config["certificate_url"].(string); v != "" { - winRmListner.CertificateURL = &v + winRmListener.CertificateURL = &v } - winRmListners = append(winRmListners, winRmListner) + winRmListeners = append(winRmListeners, winRmListener) } config.WinRM = &compute.WinRMConfiguration{ - Listeners: &winRmListners, + Listeners: &winRmListeners, } } } @@ -1209,19 +1287,48 @@ func expandAzureRmVirtualMachineDataDisk(d *schema.ResourceData) ([]compute.Data config := disk_config.(map[string]interface{}) name := config["name"].(string) - vhd := config["vhd_uri"].(string) createOption := config["create_option"].(string) + vhdURI := config["vhd_uri"].(string) + managedDiskType := config["managed_disk_type"].(string) + managedDiskID := config["managed_disk_id"].(string) lun := int32(config["lun"].(int)) data_disk := compute.DataDisk{ - Name: &name, - Vhd: &compute.VirtualHardDisk{ - URI: &vhd, - }, + Name: &name, Lun: &lun, CreateOption: compute.DiskCreateOptionTypes(createOption), } + if vhdURI != "" { + data_disk.Vhd = &compute.VirtualHardDisk{ + URI: &vhdURI, + } + } + + managedDisk := &compute.ManagedDiskParameters{} + + if managedDiskType != "" { + managedDisk.StorageAccountType = compute.StorageAccountTypes(managedDiskType) + data_disk.ManagedDisk = managedDisk + } + + if managedDiskID != "" { + managedDisk.ID = &managedDiskID + data_disk.ManagedDisk = managedDisk + } + + //BEGIN: code to be removed after GH-13016 is merged + if vhdURI != "" && managedDiskID != "" { + return nil, fmt.Errorf("[ERROR] Conflict between `vhd_uri` and `managed_disk_id` (only one or the other can be used)") + } + if vhdURI != "" && managedDiskType != "" { + return nil, fmt.Errorf("[ERROR] Conflict between `vhd_uri` and `managed_disk_type` (only one or the other can be used)") + } + //END: code to be removed after GH-13016 is merged + if managedDiskID == "" && strings.EqualFold(string(data_disk.CreateOption), string(compute.Attach)) { + return nil, fmt.Errorf("[ERROR] Must specify which disk to attach") + } + if v := config["caching"].(string); v != "" { data_disk.Caching = compute.CachingTypes(v) } @@ -1303,28 +1410,57 @@ func expandAzureRmVirtualMachineNetworkProfile(d *schema.ResourceData) compute.N func expandAzureRmVirtualMachineOsDisk(d *schema.ResourceData) (*compute.OSDisk, error) { disks := d.Get("storage_os_disk").(*schema.Set).List() - disk := disks[0].(map[string]interface{}) + config := disks[0].(map[string]interface{}) - name := disk["name"].(string) - vhdURI := disk["vhd_uri"].(string) - imageURI := disk["image_uri"].(string) - createOption := disk["create_option"].(string) + name := config["name"].(string) + imageURI := config["image_uri"].(string) + createOption := config["create_option"].(string) + vhdURI := config["vhd_uri"].(string) + managedDiskType := config["managed_disk_type"].(string) + managedDiskID := config["managed_disk_id"].(string) osDisk := &compute.OSDisk{ - Name: &name, - Vhd: &compute.VirtualHardDisk{ - URI: &vhdURI, - }, + Name: &name, CreateOption: compute.DiskCreateOptionTypes(createOption), } - if v := disk["image_uri"].(string); v != "" { + if vhdURI != "" { + osDisk.Vhd = &compute.VirtualHardDisk{ + URI: &vhdURI, + } + } + + managedDisk := &compute.ManagedDiskParameters{} + + if managedDiskType != "" { + managedDisk.StorageAccountType = compute.StorageAccountTypes(managedDiskType) + osDisk.ManagedDisk = managedDisk + } + + if managedDiskID != "" { + managedDisk.ID = &managedDiskID + osDisk.ManagedDisk = managedDisk + } + + //BEGIN: code to be removed after GH-13016 is merged + if vhdURI != "" && managedDiskID != "" { + return nil, fmt.Errorf("[ERROR] Conflict between `vhd_uri` and `managed_disk_id` (only one or the other can be used)") + } + if vhdURI != "" && managedDiskType != "" { + return nil, fmt.Errorf("[ERROR] Conflict between `vhd_uri` and `managed_disk_type` (only one or the other can be used)") + } + //END: code to be removed after GH-13016 is merged + if managedDiskID == "" && strings.EqualFold(string(osDisk.CreateOption), string(compute.Attach)) { + return nil, fmt.Errorf("[ERROR] Must specify which disk to attach") + } + + if v := config["image_uri"].(string); v != "" { osDisk.Image = &compute.VirtualHardDisk{ URI: &imageURI, } } - if v := disk["os_type"].(string); v != "" { + if v := config["os_type"].(string); v != "" { if v == "linux" { osDisk.OsType = compute.Linux } else if v == "windows" { @@ -1334,11 +1470,11 @@ func expandAzureRmVirtualMachineOsDisk(d *schema.ResourceData) (*compute.OSDisk, } } - if v := disk["caching"].(string); v != "" { + if v := config["caching"].(string); v != "" { osDisk.Caching = compute.CachingTypes(v) } - if v := disk["disk_size_gb"].(int); v != 0 { + if v := config["disk_size_gb"].(int); v != 0 { diskSize := int32(v) osDisk.DiskSizeGB = &diskSize } diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine_test.go b/builtin/providers/azurerm/resource_arm_virtual_machine_test.go index b3a42728a..71552b8cf 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine_test.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine_test.go @@ -7,9 +7,11 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/disk" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "regexp" ) func TestAccAzureRMVirtualMachine_basicLinuxMachine(t *testing.T) { @@ -31,6 +33,63 @@ func TestAccAzureRMVirtualMachine_basicLinuxMachine(t *testing.T) { }) } +func TestAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_explicit(t *testing.T) { + var vm compute.VirtualMachine + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_explicit, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_implicit(t *testing.T) { + var vm compute.VirtualMachine + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_implicit, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_attach(t *testing.T) { + var vm compute.VirtualMachine + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_attach, ri, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + func TestAccAzureRMVirtualMachine_basicLinuxMachine_disappears(t *testing.T) { var vm compute.VirtualMachine ri := acctest.RandInt() @@ -44,7 +103,7 @@ func TestAccAzureRMVirtualMachine_basicLinuxMachine_disappears(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), - testCheckAzureRMVirtualMachineDisappears("azurerm_virtual_machine.test", &vm), + testCheckAzureRMVirtualMachineDisappears("azurerm_virtual_machine.test"), ), ExpectNonEmptyPlan: true, }, @@ -72,6 +131,46 @@ func TestAccAzureRMVirtualMachine_withDataDisk(t *testing.T) { }) } +func TestAccAzureRMVirtualMachine_withDataDisk_managedDisk_explicit(t *testing.T) { + var vm compute.VirtualMachine + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_withDataDisk_managedDisk_explicit, ri, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_withDataDisk_managedDisk_implicit(t *testing.T) { + var vm compute.VirtualMachine + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_withDataDisk_managedDisk_implicit, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + ), + }, + }, + }) +} + func TestAccAzureRMVirtualMachine_tags(t *testing.T) { var vm compute.VirtualMachine @@ -128,7 +227,7 @@ func TestAccAzureRMVirtualMachine_updateMachineSize(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), resource.TestCheckResourceAttr( - "azurerm_virtual_machine.test", "vm_size", "Standard_A0"), + "azurerm_virtual_machine.test", "vm_size", "Standard_D1_v2"), ), }, { @@ -136,7 +235,7 @@ func TestAccAzureRMVirtualMachine_updateMachineSize(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), resource.TestCheckResourceAttr( - "azurerm_virtual_machine.test", "vm_size", "Standard_A1"), + "azurerm_virtual_machine.test", "vm_size", "Standard_D2_v2"), ), }, }, @@ -238,8 +337,40 @@ func TestAccAzureRMVirtualMachine_deleteVHDOptOut(t *testing.T) { { Config: postConfig, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMVirtualMachineVHDExistance("myosdisk1.vhd", true), - testCheckAzureRMVirtualMachineVHDExistance("mydatadisk1.vhd", true), + testCheckAzureRMVirtualMachineVHDExistence("myosdisk1.vhd", true), + testCheckAzureRMVirtualMachineVHDExistence("mydatadisk1.vhd", true), + ), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_deleteManagedDiskOptOut(t *testing.T) { + var vm compute.VirtualMachine + var osd string + var dtd string + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_withDataDisk_managedDisk_implicit, ri, ri, ri, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachineDeleteVM_managedDisk, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Destroy: false, + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + testLookupAzureRMVirtualMachineManagedDiskID(&vm, "myosdisk1", &osd), + testLookupAzureRMVirtualMachineManagedDiskID(&vm, "mydatadisk1", &dtd), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineManagedDiskExists(&osd, true), + testCheckAzureRMVirtualMachineManagedDiskExists(&dtd, true), ), }, }, @@ -265,8 +396,40 @@ func TestAccAzureRMVirtualMachine_deleteVHDOptIn(t *testing.T) { { Config: postConfig, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMVirtualMachineVHDExistance("myosdisk1.vhd", false), - testCheckAzureRMVirtualMachineVHDExistance("mydatadisk1.vhd", false), + testCheckAzureRMVirtualMachineVHDExistence("myosdisk1.vhd", false), + testCheckAzureRMVirtualMachineVHDExistence("mydatadisk1.vhd", false), + ), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_deleteManagedDiskOptIn(t *testing.T) { + var vm compute.VirtualMachine + var osd string + var dtd string + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_DestroyDisksBefore, ri, ri, ri, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_DestroyDisksAfter, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Destroy: false, + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &vm), + testLookupAzureRMVirtualMachineManagedDiskID(&vm, "myosdisk1", &osd), + testLookupAzureRMVirtualMachineManagedDiskID(&vm, "mydatadisk1", &dtd), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualMachineManagedDiskExists(&osd, false), + testCheckAzureRMVirtualMachineManagedDiskExists(&dtd, false), ), }, }, @@ -284,14 +447,14 @@ func TestAccAzureRMVirtualMachine_ChangeComputerName(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMVirtualMachineDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterCreate), ), }, - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterUpdate), @@ -303,7 +466,7 @@ func TestAccAzureRMVirtualMachine_ChangeComputerName(t *testing.T) { }) } -func TestAccAzureRMVirtualMachine_ChangeAvailbilitySet(t *testing.T) { +func TestAccAzureRMVirtualMachine_ChangeAvailabilitySet(t *testing.T) { var afterCreate, afterUpdate compute.VirtualMachine ri := acctest.RandInt() @@ -314,14 +477,14 @@ func TestAccAzureRMVirtualMachine_ChangeAvailbilitySet(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMVirtualMachineDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterCreate), ), }, - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterUpdate), @@ -344,14 +507,14 @@ func TestAccAzureRMVirtualMachine_changeStorageImageReference(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMVirtualMachineDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterCreate), ), }, - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterUpdate), @@ -374,14 +537,14 @@ func TestAccAzureRMVirtualMachine_changeOSDiskVhdUri(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMVirtualMachineDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterCreate), ), }, - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMVirtualMachineExists("azurerm_virtual_machine.test", &afterUpdate), @@ -438,6 +601,42 @@ func TestAccAzureRMVirtualMachine_changeSSHKey(t *testing.T) { }) } +func TestAccAzureRMVirtualMachine_osDiskTypeConflict(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_osDiskTypeConflict, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("Conflict between `vhd_uri`"), + //Use below code instead once GH-13019 has been merged + //ExpectError: regexp.MustCompile("conflicts with storage_os_disk.0.vhd_uri"), + }, + }, + }) +} + +func TestAccAzureRMVirtualMachine_dataDiskTypeConflict(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMVirtualMachine_dataDiskTypeConflict, ri, ri, ri, ri, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("Conflict between `vhd_uri`"), + //Use below code instead once GH-13019 has been merged + //ExpectError: regexp.MustCompile("conflicts with storage_data_disk.1.vhd_uri"), + }, + }, + }) +} + func testCheckAzureRMVirtualMachineExists(name string, vm *compute.VirtualMachine) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -469,6 +668,23 @@ func testCheckAzureRMVirtualMachineExists(name string, vm *compute.VirtualMachin } } +func testCheckAzureRMVirtualMachineManagedDiskExists(managedDiskID *string, shouldExist bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + d, err := testGetAzureRMVirtualMachineManagedDisk(managedDiskID) + if err != nil { + return fmt.Errorf("Error trying to retrieve Managed Disk %s, %s", *managedDiskID, err) + } + if d.StatusCode == http.StatusNotFound && shouldExist { + return fmt.Errorf("Unable to find Managed Disk %s", *managedDiskID) + } + if d.StatusCode != http.StatusNotFound && !shouldExist { + return fmt.Errorf("Found unexpected Managed Disk %s", *managedDiskID) + } + + return nil + } +} + func testAccCheckVirtualMachineRecreated(t *testing.T, before, after *compute.VirtualMachine) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -504,7 +720,7 @@ func testCheckAzureRMVirtualMachineDestroy(s *terraform.State) error { return nil } -func testCheckAzureRMVirtualMachineVHDExistance(name string, shouldExist bool) resource.TestCheckFunc { +func testCheckAzureRMVirtualMachineVHDExistence(name string, shouldExist bool) resource.TestCheckFunc { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_storage_container" { @@ -526,9 +742,9 @@ func testCheckAzureRMVirtualMachineVHDExistance(name string, shouldExist bool) r } if exists && !shouldExist { - return fmt.Errorf("Disk VHD Blob still exists") + return fmt.Errorf("Disk VHD Blob still exists %s %s", containerName, name) } else if !exists && shouldExist { - return fmt.Errorf("Disk VHD Blob should exist") + return fmt.Errorf("Disk VHD Blob should exist %s %s", containerName, name) } } @@ -536,7 +752,7 @@ func testCheckAzureRMVirtualMachineVHDExistance(name string, shouldExist bool) r } } -func testCheckAzureRMVirtualMachineDisappears(name string, vm *compute.VirtualMachine) resource.TestCheckFunc { +func testCheckAzureRMVirtualMachineDisappears(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API rs, ok := s.RootModule().Resources[name] @@ -599,16 +815,76 @@ func TestAccAzureRMVirtualMachine_primaryNetworkInterfaceId(t *testing.T) { }) } +func testLookupAzureRMVirtualMachineManagedDiskID(vm *compute.VirtualMachine, diskName string, managedDiskID *string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if osd := vm.StorageProfile.OsDisk; osd != nil { + if strings.EqualFold(*osd.Name, diskName) { + if osd.ManagedDisk != nil { + id, err := findAzureRMVirtualMachineManagedDiskID(osd.ManagedDisk) + if err != nil { + return fmt.Errorf("Unable to parse Managed Disk ID for OS Disk %s, %s", diskName, err) + } + *managedDiskID = id + return nil + } + } + } + + for _, dataDisk := range *vm.StorageProfile.DataDisks { + if strings.EqualFold(*dataDisk.Name, diskName) { + if dataDisk.ManagedDisk != nil { + id, err := findAzureRMVirtualMachineManagedDiskID(dataDisk.ManagedDisk) + if err != nil { + return fmt.Errorf("Unable to parse Managed Disk ID for Data Disk %s, %s", diskName, err) + } + *managedDiskID = id + return nil + } + } + } + + return fmt.Errorf("Unable to locate disk %s on vm %s", diskName, *vm.Name) + } +} + +func findAzureRMVirtualMachineManagedDiskID(md *compute.ManagedDiskParameters) (string, error) { + _, err := parseAzureResourceID(*md.ID) + if err != nil { + return "", err + } + return *md.ID, nil +} + +func testGetAzureRMVirtualMachineManagedDisk(managedDiskID *string) (*disk.Model, error) { + armID, err := parseAzureResourceID(*managedDiskID) + if err != nil { + return nil, fmt.Errorf("Unable to parse Managed Disk ID %s, %s", *managedDiskID, err) + } + name := armID.Path["disks"] + resourceGroup := armID.ResourceGroup + conn := testAccProvider.Meta().(*ArmClient).diskClient + d, err := conn.Get(resourceGroup, name) + //check status first since sdk client returns error if not 200 + if d.Response.StatusCode == http.StatusNotFound { + return &d, nil + } + if err != nil { + return nil, err + } + + return &d, nil +} + var testAccAzureRMVirtualMachine_basicLinuxMachine = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -621,7 +897,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -634,7 +910,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -651,10 +927,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -672,7 +948,236 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_explicit = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + disk_size_gb = "10" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_implicit = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + disk_size_gb = "10" + } + + os_profile { + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_attach = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_managed_disk" "test" { + name = "acctmd-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "1" +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + disk_size_gb = "10" + managed_disk_type = "Standard_LRS" + } + + storage_data_disk { + name = "${azurerm_managed_disk.test.name}" + create_option = "Attach" + disk_size_gb = "1" + lun = 0 + managed_disk_id = "${azurerm_managed_disk.test.id}" + } + + os_profile { + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -691,13 +1196,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_machineNameBeforeUpdate = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -710,7 +1215,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -723,7 +1228,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -740,10 +1245,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" delete_os_disk_on_termination = true storage_image_reference { @@ -761,7 +1266,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -780,18 +1285,18 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicLinuxMachineDestroyDisksBefore = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_resource_group" "test-sa" { name = "acctestRG-sa-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -804,7 +1309,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -817,7 +1322,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test-sa.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -834,10 +1339,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -858,7 +1363,7 @@ resource "azurerm_virtual_machine" "test" { storage_data_disk { name = "mydatadisk1" vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/mydatadisk1.vhd" - disk_size_gb = "1023" + disk_size_gb = "1" create_option = "Empty" lun = 0 } @@ -866,7 +1371,87 @@ resource "azurerm_virtual_machine" "test" { delete_data_disks_on_termination = true os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_DestroyDisksBefore = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "myosdisk1" + caching = "ReadWrite" + create_option = "FromImage" + } + + delete_os_disk_on_termination = true + + storage_data_disk { + name = "mydatadisk1" + disk_size_gb = "1" + create_option = "Empty" + lun = 0 + } + + delete_data_disks_on_termination = true + + os_profile { + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -885,18 +1470,18 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicLinuxMachineDestroyDisksAfter = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_resource_group" "test-sa" { name = "acctestRG-sa-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -909,7 +1494,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -922,7 +1507,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test-sa.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -938,16 +1523,49 @@ resource "azurerm_storage_container" "test" { } ` +var testAccAzureRMVirtualMachine_basicLinuxMachine_managedDisk_DestroyDisksAfter = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} +` + var testAccAzureRMVirtualMachine_basicLinuxMachineDeleteVM = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -960,7 +1578,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -973,7 +1591,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -989,16 +1607,16 @@ resource "azurerm_storage_container" "test" { } ` -var testAccAzureRMVirtualMachine_withDataDisk = ` +var testAccAzureRMVirtualMachine_basicLinuxMachineDeleteVM_managedDisk = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1011,7 +1629,40 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} +` + +var testAccAzureRMVirtualMachine_withDataDisk = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1024,7 +1675,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1041,10 +1692,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -1063,14 +1714,170 @@ resource "azurerm_virtual_machine" "test" { storage_data_disk { name = "mydatadisk1" vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/mydatadisk1.vhd" - disk_size_gb = "1023" + disk_size_gb = "1" create_option = "Empty" caching = "ReadWrite" lun = 0 } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_withDataDisk_managedDisk_explicit = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + storage_data_disk { + name = "dtd-%d" + disk_size_gb = "1" + create_option = "Empty" + caching = "ReadWrite" + lun = 0 + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_withDataDisk_managedDisk_implicit = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "myosdisk1" + caching = "ReadWrite" + create_option = "FromImage" + } + + storage_data_disk { + name = "mydatadisk1" + disk_size_gb = "1" + create_option = "Empty" + caching = "ReadWrite" + lun = 0 + } + + os_profile { + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1089,13 +1896,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicLinuxMachineUpdated = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1108,7 +1915,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1121,7 +1928,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1138,10 +1945,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -1158,7 +1965,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1176,13 +1983,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_updatedLinuxMachine = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1195,7 +2002,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1208,7 +2015,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1225,10 +2032,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A1" + vm_size = "Standard_D2_v2" storage_image_reference { publisher = "Canonical" @@ -1245,7 +2052,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1259,13 +2066,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicWindowsMachine = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1278,7 +2085,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1291,7 +2098,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1308,10 +2115,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "MicrosoftWindowsServer" @@ -1343,13 +2150,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_windowsUnattendedConfig = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1362,7 +2169,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1375,7 +2182,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1392,10 +2199,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "MicrosoftWindowsServer" @@ -1433,13 +2240,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_diagnosticsProfile = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1452,7 +2259,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1465,7 +2272,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1482,10 +2289,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "MicrosoftWindowsServer" @@ -1524,13 +2331,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_winRMConfig = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1543,7 +2350,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1556,7 +2363,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1573,10 +2380,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "MicrosoftWindowsServer" @@ -1609,13 +2416,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_withAvailabilitySet = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1628,7 +2435,7 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1641,7 +2448,7 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1651,7 +2458,7 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` resource "azurerm_availability_set" "test" { name = "availabilityset%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1664,10 +2471,10 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" availability_set_id = "${azurerm_availability_set.test.id}" delete_os_disk_on_termination = true @@ -1686,7 +2493,7 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1700,13 +2507,13 @@ var testAccAzureRMVirtualMachine_withAvailabilitySet = ` var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1719,7 +2526,7 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1732,7 +2539,7 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1742,7 +2549,7 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` resource "azurerm_availability_set" "test" { name = "updatedAvailabilitySet%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1755,10 +2562,10 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" availability_set_id = "${azurerm_availability_set.test.id}" delete_os_disk_on_termination = true @@ -1777,7 +2584,7 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1791,13 +2598,13 @@ var testAccAzureRMVirtualMachine_updateAvailabilitySet = ` var testAccAzureRMVirtualMachine_updateMachineName = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1810,7 +2617,7 @@ var testAccAzureRMVirtualMachine_updateMachineName = ` resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1823,7 +2630,7 @@ var testAccAzureRMVirtualMachine_updateMachineName = ` resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1840,10 +2647,10 @@ var testAccAzureRMVirtualMachine_updateMachineName = ` resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" delete_os_disk_on_termination = true storage_image_reference { @@ -1875,13 +2682,13 @@ var testAccAzureRMVirtualMachine_updateMachineName = ` var testAccAzureRMVirtualMachine_basicLinuxMachineStorageImageBefore = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1894,7 +2701,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1907,7 +2714,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -1924,10 +2731,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" delete_os_disk_on_termination = true storage_image_reference { @@ -1946,7 +2753,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -1965,13 +2772,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicLinuxMachineStorageImageAfter = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -1984,7 +2791,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -1997,7 +2804,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -2014,10 +2821,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" delete_os_disk_on_termination = true storage_image_reference { @@ -2036,7 +2843,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -2055,13 +2862,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_basicLinuxMachineWithOSDiskVhdUriChanged = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -2074,7 +2881,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -2087,7 +2894,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -2104,10 +2911,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -2125,7 +2932,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -2144,13 +2951,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_windowsLicenseType = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -2163,7 +2970,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -2176,7 +2983,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -2193,10 +3000,10 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" license_type = "Windows_Server" storage_image_reference { @@ -2229,13 +3036,13 @@ resource "azurerm_virtual_machine" "test" { var testAccAzureRMVirtualMachine_plan = ` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" - location = "West US" + location = "West US 2" } resource "azurerm_virtual_network" "test" { name = "acctvn-%d" address_space = ["10.0.0.0/16"] - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" } @@ -2248,7 +3055,7 @@ resource "azurerm_subnet" "test" { resource "azurerm_network_interface" "test" { name = "acctni-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { @@ -2261,7 +3068,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_storage_account" "test" { name = "accsa%d" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "West US 2" account_type = "Standard_LRS" tags { @@ -2278,7 +3085,7 @@ resource "azurerm_storage_container" "test" { resource "azurerm_virtual_machine" "test" { name = "acctvm-%d" - location = "West US" + location = "West US 2" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] vm_size = "Standard_DS1_v2" @@ -2299,7 +3106,7 @@ resource "azurerm_virtual_machine" "test" { } os_profile { - computer_name = "hostname%d" + computer_name = "hn%d" admin_username = "testadmin" admin_password = "Password1234!" } @@ -2372,7 +3179,7 @@ resource "azurerm_virtual_machine" "test" { location = "southcentralus" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -2456,7 +3263,7 @@ resource "azurerm_virtual_machine" "test" { location = "southcentralus" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.test.id}"] - vm_size = "Standard_A0" + vm_size = "Standard_D1_v2" storage_image_reference { publisher = "Canonical" @@ -2484,6 +3291,176 @@ resource "azurerm_virtual_machine" "test" { } } ` +var testAccAzureRMVirtualMachine_osDiskTypeConflict = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + disk_size_gb = "10" + managed_disk_type = "Standard_LRS" + vhd_uri = "should_cause_conflict" + } + + storage_data_disk { + name = "mydatadisk1" + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = "45" + managed_disk_type = "Standard_LRS" + lun = "0" + } + + os_profile { + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` + +var testAccAzureRMVirtualMachine_dataDiskTypeConflict = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US 2" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "West US 2" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "14.04.2-LTS" + version = "latest" + } + + storage_os_disk { + name = "osd-%d" + caching = "ReadWrite" + create_option = "FromImage" + disk_size_gb = "10" + managed_disk_type = "Standard_LRS" + } + + storage_data_disk { + name = "mydatadisk1" + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = "45" + managed_disk_type = "Standard_LRS" + lun = "0" + } + + storage_data_disk { + name = "mydatadisk1" + vhd_uri = "should_cause_conflict" + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = "45" + managed_disk_type = "Standard_LRS" + lun = "1" + } + + os_profile { + computer_name = "hn%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags { + environment = "Production" + cost-center = "Ops" + } +} +` var testAccAzureRMVirtualMachine_primaryNetworkInterfaceId = ` resource "azurerm_resource_group" "test" { diff --git a/builtin/providers/bitbucket/client.go b/builtin/providers/bitbucket/client.go index 02b9ed0db..bd2cebcce 100644 --- a/builtin/providers/bitbucket/client.go +++ b/builtin/providers/bitbucket/client.go @@ -2,64 +2,107 @@ package bitbucket import ( "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "log" "net/http" ) +// Error represents a error from the bitbucket api. +type Error struct { + APIError struct { + Message string `json:"message,omitempty"` + } `json:"error,omitempty"` + Type string `json:"type,omitempty"` + StatusCode int + Endpoint string +} + +func (e Error) Error() string { + return fmt.Sprintf("API Error: %d %s %s", e.StatusCode, e.Endpoint, e.APIError.Message) +} + +const ( + // BitbucketEndpoint is the fqdn used to talk to bitbucket + BitbucketEndpoint string = "https://api.bitbucket.org/" +) + type BitbucketClient struct { - Username string - Password string + Username string + Password string + HTTPClient *http.Client +} + +func (c *BitbucketClient) Do(method, endpoint string, payload *bytes.Buffer) (*http.Response, error) { + + absoluteendpoint := BitbucketEndpoint + endpoint + log.Printf("[DEBUG] Sending request to %s %s", method, absoluteendpoint) + + var bodyreader io.Reader + + if payload != nil { + log.Printf("[DEBUG] With payload %s", payload.String()) + bodyreader = payload + } + + req, err := http.NewRequest(method, absoluteendpoint, bodyreader) + if err != nil { + return nil, err + } + + req.SetBasicAuth(c.Username, c.Password) + + if payload != nil { + // Can cause bad request when putting default reviews if set. + req.Header.Add("Content-Type", "application/json") + } + + req.Close = true + + resp, err := c.HTTPClient.Do(req) + log.Printf("[DEBUG] Resp: %v Err: %v", resp, err) + if resp.StatusCode >= 400 || resp.StatusCode < 200 { + apiError := Error{ + StatusCode: resp.StatusCode, + Endpoint: endpoint, + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + log.Printf("[DEBUG] Resp Body: %s", string(body)) + + err = json.Unmarshal(body, &apiError) + if err != nil { + apiError.APIError.Message = string(body) + } + + return resp, error(apiError) + + } + return resp, err } func (c *BitbucketClient) Get(endpoint string) (*http.Response, error) { - client := &http.Client{} - req, err := http.NewRequest("GET", "https://api.bitbucket.org/"+endpoint, nil) - if err != nil { - return nil, err - } - - req.SetBasicAuth(c.Username, c.Password) - return client.Do(req) - + return c.Do("GET", endpoint, nil) } func (c *BitbucketClient) Post(endpoint string, jsonpayload *bytes.Buffer) (*http.Response, error) { - client := &http.Client{} - req, err := http.NewRequest("POST", "https://api.bitbucket.org/"+endpoint, jsonpayload) - if err != nil { - return nil, err - } - req.SetBasicAuth(c.Username, c.Password) - req.Header.Add("content-type", "application/json") - return client.Do(req) + return c.Do("POST", endpoint, jsonpayload) } func (c *BitbucketClient) Put(endpoint string, jsonpayload *bytes.Buffer) (*http.Response, error) { - client := &http.Client{} - req, err := http.NewRequest("PUT", "https://api.bitbucket.org/"+endpoint, jsonpayload) - if err != nil { - return nil, err - } - req.SetBasicAuth(c.Username, c.Password) - req.Header.Add("content-type", "application/json") - return client.Do(req) + return c.Do("PUT", endpoint, jsonpayload) } func (c *BitbucketClient) PutOnly(endpoint string) (*http.Response, error) { - client := &http.Client{} - req, err := http.NewRequest("PUT", "https://api.bitbucket.org/"+endpoint, nil) - if err != nil { - return nil, err - } - req.SetBasicAuth(c.Username, c.Password) - return client.Do(req) + return c.Do("PUT", endpoint, nil) } func (c *BitbucketClient) Delete(endpoint string) (*http.Response, error) { - client := &http.Client{} - req, err := http.NewRequest("DELETE", "https://api.bitbucket.org/"+endpoint, nil) - if err != nil { - return nil, err - } - req.SetBasicAuth(c.Username, c.Password) - return client.Do(req) + return c.Do("DELETE", endpoint, nil) } diff --git a/builtin/providers/bitbucket/provider.go b/builtin/providers/bitbucket/provider.go index afeb71249..e50f9295f 100644 --- a/builtin/providers/bitbucket/provider.go +++ b/builtin/providers/bitbucket/provider.go @@ -1,6 +1,8 @@ package bitbucket import ( + "net/http" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" ) @@ -30,8 +32,9 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { client := &BitbucketClient{ - Username: d.Get("username").(string), - Password: d.Get("password").(string), + Username: d.Get("username").(string), + Password: d.Get("password").(string), + HTTPClient: &http.Client{}, } return client, nil diff --git a/builtin/providers/bitbucket/resource_default_reviewers.go b/builtin/providers/bitbucket/resource_default_reviewers.go index 37a0f5883..9fc5d1e0a 100644 --- a/builtin/providers/bitbucket/resource_default_reviewers.go +++ b/builtin/providers/bitbucket/resource_default_reviewers.go @@ -3,6 +3,7 @@ package bitbucket import ( "encoding/json" "fmt" + "github.com/hashicorp/terraform/helper/schema" ) @@ -49,7 +50,7 @@ func resourceDefaultReviewersCreate(d *schema.ResourceData, m interface{}) error client := m.(*BitbucketClient) for _, user := range d.Get("reviewers").(*schema.Set).List() { - reviewer_resp, err := client.PutOnly(fmt.Sprintf("2.0/repositories/%s/%s/default-reviewers/%s", + reviewerResp, err := client.PutOnly(fmt.Sprintf("2.0/repositories/%s/%s/default-reviewers/%s", d.Get("owner").(string), d.Get("repository").(string), user, @@ -59,11 +60,11 @@ func resourceDefaultReviewersCreate(d *schema.ResourceData, m interface{}) error return err } - if reviewer_resp.StatusCode != 200 { - return fmt.Errorf("Failed to create reviewer %s got code %d", user.(string), reviewer_resp.StatusCode) + if reviewerResp.StatusCode != 200 { + return fmt.Errorf("Failed to create reviewer %s got code %d", user.(string), reviewerResp.StatusCode) } - defer reviewer_resp.Body.Close() + defer reviewerResp.Body.Close() } d.SetId(fmt.Sprintf("%s/%s/reviewers", d.Get("owner").(string), d.Get("repository").(string))) @@ -72,26 +73,26 @@ func resourceDefaultReviewersCreate(d *schema.ResourceData, m interface{}) error func resourceDefaultReviewersRead(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) - reviewers_response, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/default-reviewers", + reviewersResponse, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/default-reviewers", d.Get("owner").(string), d.Get("repository").(string), )) var reviewers PaginatedReviewers - decoder := json.NewDecoder(reviewers_response.Body) + decoder := json.NewDecoder(reviewersResponse.Body) err = decoder.Decode(&reviewers) if err != nil { return err } - terraform_reviewers := make([]string, 0, len(reviewers.Values)) + terraformReviewers := make([]string, 0, len(reviewers.Values)) for _, reviewer := range reviewers.Values { - terraform_reviewers = append(terraform_reviewers, reviewer.Username) + terraformReviewers = append(terraformReviewers, reviewer.Username) } - d.Set("reviewers", terraform_reviewers) + d.Set("reviewers", terraformReviewers) return nil } diff --git a/builtin/providers/bitbucket/resource_hook.go b/builtin/providers/bitbucket/resource_hook.go index c93862798..745292ad1 100644 --- a/builtin/providers/bitbucket/resource_hook.go +++ b/builtin/providers/bitbucket/resource_hook.go @@ -4,6 +4,10 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" + "log" + "net/url" + "github.com/hashicorp/terraform/helper/schema" ) @@ -81,86 +85,89 @@ func resourceHookCreate(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) hook := createHook(d) - var jsonbuffer []byte - - jsonpayload := bytes.NewBuffer(jsonbuffer) - enc := json.NewEncoder(jsonpayload) - enc.Encode(hook) - - hook_req, err := client.Post(fmt.Sprintf("2.0/repositories/%s/%s/hooks", - d.Get("owner").(string), - d.Get("repository").(string), - ), jsonpayload) - - decoder := json.NewDecoder(hook_req.Body) - err = decoder.Decode(&hook) + payload, err := json.Marshal(hook) if err != nil { return err } + hook_req, err := client.Post(fmt.Sprintf("2.0/repositories/%s/%s/hooks", + d.Get("owner").(string), + d.Get("repository").(string), + ), bytes.NewBuffer(payload)) + + if err != nil { + return err + } + + body, readerr := ioutil.ReadAll(hook_req.Body) + if readerr != nil { + return readerr + } + + decodeerr := json.Unmarshal(body, &hook) + if decodeerr != nil { + return decodeerr + } + d.SetId(hook.Uuid) - d.Set("uuid", hook.Uuid) return resourceHookRead(d, m) } func resourceHookRead(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) - hook_req, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", + + hook_req, _ := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", d.Get("owner").(string), d.Get("repository").(string), - d.Get("uuid").(string), + url.PathEscape(d.Id()), )) - if err != nil { - return err + log.Printf("ID: %s", url.PathEscape(d.Id())) + + if hook_req.StatusCode == 200 { + var hook Hook + + body, readerr := ioutil.ReadAll(hook_req.Body) + if readerr != nil { + return readerr + } + + decodeerr := json.Unmarshal(body, &hook) + if decodeerr != nil { + return decodeerr + } + + d.Set("uuid", hook.Uuid) + d.Set("description", hook.Description) + d.Set("active", hook.Active) + d.Set("url", hook.Url) + + eventsList := make([]string, 0, len(hook.Events)) + + for _, event := range hook.Events { + eventsList = append(eventsList, event) + } + + d.Set("events", eventsList) } - var hook Hook - - decoder := json.NewDecoder(hook_req.Body) - err = decoder.Decode(&hook) - if err != nil { - return err - } - - d.Set("uuid", hook.Uuid) - d.Set("description", hook.Description) - d.Set("active", hook.Active) - d.Set("url", hook.Url) - - eventsList := make([]string, 0, len(hook.Events)) - - for _, event := range hook.Events { - eventsList = append(eventsList, event) - } - - d.Set("events", eventsList) - return nil } func resourceHookUpdate(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) hook := createHook(d) - - var jsonbuffer []byte - - jsonpayload := bytes.NewBuffer(jsonbuffer) - enc := json.NewEncoder(jsonpayload) - enc.Encode(hook) - - hook_req, err := client.Put(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", - d.Get("owner").(string), - d.Get("repository").(string), - d.Get("uuid").(string), - ), jsonpayload) - + payload, err := json.Marshal(hook) if err != nil { return err } - decoder := json.NewDecoder(hook_req.Body) - err = decoder.Decode(&hook) + _, err = client.Put(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", + d.Get("owner").(string), + d.Get("repository").(string), + url.PathEscape(d.Id()), + ), bytes.NewBuffer(payload)) + if err != nil { return err } @@ -174,7 +181,7 @@ func resourceHookExists(d *schema.ResourceData, m interface{}) (bool, error) { hook_req, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", d.Get("owner").(string), d.Get("repository").(string), - d.Get("uuid").(string), + url.PathEscape(d.Id()), )) if err != nil { @@ -182,15 +189,14 @@ func resourceHookExists(d *schema.ResourceData, m interface{}) (bool, error) { } if hook_req.StatusCode != 200 { - d.SetId("") - return false, nil + return false, err } return true, nil - } else { - return false, nil } + return false, nil + } func resourceHookDelete(d *schema.ResourceData, m interface{}) error { @@ -198,11 +204,9 @@ func resourceHookDelete(d *schema.ResourceData, m interface{}) error { _, err := client.Delete(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", d.Get("owner").(string), d.Get("repository").(string), - d.Get("uuid").(string), + url.PathEscape(d.Id()), )) - if err != nil { - return err - } - return nil + return err + } diff --git a/builtin/providers/bitbucket/resource_hook_test.go b/builtin/providers/bitbucket/resource_hook_test.go index 178ebf27b..59a719b87 100644 --- a/builtin/providers/bitbucket/resource_hook_test.go +++ b/builtin/providers/bitbucket/resource_hook_test.go @@ -2,6 +2,7 @@ package bitbucket import ( "fmt" + "net/url" "os" "testing" @@ -16,7 +17,7 @@ func TestAccBitbucketHook_basic(t *testing.T) { testAccBitbucketHookConfig := fmt.Sprintf(` resource "bitbucket_repository" "test_repo" { owner = "%s" - name = "test-repo" + name = "test-repo-for-webhook-test" } resource "bitbucket_hook" "test_repo_hook" { owner = "%s" @@ -51,10 +52,10 @@ func testAccCheckBitbucketHookDestroy(s *terraform.State) error { return fmt.Errorf("Not found %s", "bitbucket_hook.test_repo_hook") } - response, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", rs.Primary.Attributes["owner"], rs.Primary.Attributes["repository"], rs.Primary.Attributes["uuid"])) + response, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/hooks/%s", rs.Primary.Attributes["owner"], rs.Primary.Attributes["repository"], url.PathEscape(rs.Primary.Attributes["uuid"]))) - if err != nil { - return err + if err == nil { + return fmt.Errorf("The resource was found should have errored") } if response.StatusCode != 404 { diff --git a/builtin/providers/bitbucket/resource_repository.go b/builtin/providers/bitbucket/resource_repository.go index 050ddd9b2..f57db3ea8 100644 --- a/builtin/providers/bitbucket/resource_repository.go +++ b/builtin/providers/bitbucket/resource_repository.go @@ -4,8 +4,9 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" + "github.com/hashicorp/terraform/helper/schema" - "log" ) type CloneUrl struct { @@ -131,7 +132,7 @@ func resourceRepositoryUpdate(d *schema.ResourceData, m interface{}) error { enc := json.NewEncoder(jsonpayload) enc.Encode(repository) - repository_response, err := client.Put(fmt.Sprintf("2.0/repositories/%s/%s", + _, err := client.Put(fmt.Sprintf("2.0/repositories/%s/%s", d.Get("owner").(string), d.Get("name").(string), ), jsonpayload) @@ -140,16 +141,6 @@ func resourceRepositoryUpdate(d *schema.ResourceData, m interface{}) error { return err } - if repository_response.StatusCode == 200 { - decoder := json.NewDecoder(repository_response.Body) - err = decoder.Decode(&repository) - if err != nil { - return err - } - } else { - return fmt.Errorf("Failed to put: %d", repository_response.StatusCode) - } - return resourceRepositoryRead(d, m) } @@ -157,29 +148,19 @@ func resourceRepositoryCreate(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) repo := newRepositoryFromResource(d) - var jsonbuffer []byte + bytedata, err := json.Marshal(repo) - jsonpayload := bytes.NewBuffer(jsonbuffer) - enc := json.NewEncoder(jsonpayload) - enc.Encode(repo) - - log.Printf("Sending %s \n", jsonpayload) - - repo_req, err := client.Post(fmt.Sprintf("2.0/repositories/%s/%s", - d.Get("owner").(string), - d.Get("name").(string), - ), jsonpayload) - - decoder := json.NewDecoder(repo_req.Body) - err = decoder.Decode(&repo) if err != nil { return err } - log.Printf("Received %s \n", repo_req.Body) + _, err = client.Post(fmt.Sprintf("2.0/repositories/%s/%s", + d.Get("owner").(string), + d.Get("name").(string), + ), bytes.NewBuffer(bytedata)) - if repo_req.StatusCode != 200 { - return fmt.Errorf("Failed to create repository got status code %d", repo_req.StatusCode) + if err != nil { + return err } d.SetId(string(fmt.Sprintf("%s/%s", d.Get("owner").(string), d.Get("name").(string)))) @@ -189,39 +170,42 @@ func resourceRepositoryCreate(d *schema.ResourceData, m interface{}) error { func resourceRepositoryRead(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) - repo_req, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s", + repo_req, _ := client.Get(fmt.Sprintf("2.0/repositories/%s/%s", d.Get("owner").(string), d.Get("name").(string), )) - if err != nil { - return err - } + if repo_req.StatusCode == 200 { - var repo Repository + var repo Repository - decoder := json.NewDecoder(repo_req.Body) - err = decoder.Decode(&repo) - if err != nil { - return err - } + body, readerr := ioutil.ReadAll(repo_req.Body) + if readerr != nil { + return readerr + } - d.Set("scm", repo.SCM) - d.Set("is_private", repo.IsPrivate) - d.Set("has_wiki", repo.HasWiki) - d.Set("has_issues", repo.HasIssues) - d.Set("name", repo.Name) - d.Set("language", repo.Language) - d.Set("fork_policy", repo.ForkPolicy) - d.Set("website", repo.Website) - d.Set("description", repo.Description) - d.Set("project_key", repo.Project.Key) + decodeerr := json.Unmarshal(body, &repo) + if decodeerr != nil { + return decodeerr + } - for _, clone_url := range repo.Links.Clone { - if clone_url.Name == "https" { - d.Set("clone_https", clone_url.Href) - } else { - d.Set("clone_ssh", clone_url.Href) + d.Set("scm", repo.SCM) + d.Set("is_private", repo.IsPrivate) + d.Set("has_wiki", repo.HasWiki) + d.Set("has_issues", repo.HasIssues) + d.Set("name", repo.Name) + d.Set("language", repo.Language) + d.Set("fork_policy", repo.ForkPolicy) + d.Set("website", repo.Website) + d.Set("description", repo.Description) + d.Set("project_key", repo.Project.Key) + + for _, clone_url := range repo.Links.Clone { + if clone_url.Name == "https" { + d.Set("clone_https", clone_url.Href) + } else { + d.Set("clone_ssh", clone_url.Href) + } } } @@ -230,18 +214,10 @@ func resourceRepositoryRead(d *schema.ResourceData, m interface{}) error { func resourceRepositoryDelete(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketClient) - delete_response, err := client.Delete(fmt.Sprintf("2.0/repositories/%s/%s", + _, err := client.Delete(fmt.Sprintf("2.0/repositories/%s/%s", d.Get("owner").(string), d.Get("name").(string), )) - if err != nil { - return err - } - - if delete_response.StatusCode != 204 { - return fmt.Errorf("Failed to delete the repository got status code %d", delete_response.StatusCode) - } - - return nil + return err } diff --git a/builtin/providers/bitbucket/resource_repository_test.go b/builtin/providers/bitbucket/resource_repository_test.go index 47d4f4405..1fa47a71f 100644 --- a/builtin/providers/bitbucket/resource_repository_test.go +++ b/builtin/providers/bitbucket/resource_repository_test.go @@ -16,9 +16,9 @@ func TestAccBitbucketRepository_basic(t *testing.T) { testAccBitbucketRepositoryConfig := fmt.Sprintf(` resource "bitbucket_repository" "test_repo" { owner = "%s" - name = "%s" + name = "test-repo-for-repository-test" } - `, testUser, testRepo) + `, testUser) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -42,11 +42,7 @@ func testAccCheckBitbucketRepositoryDestroy(s *terraform.State) error { return fmt.Errorf("Not found %s", "bitbucket_repository.test_repo") } - response, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s", rs.Primary.Attributes["owner"], rs.Primary.Attributes["name"])) - - if err != nil { - return err - } + response, _ := client.Get(fmt.Sprintf("2.0/repositories/%s/%s", rs.Primary.Attributes["owner"], rs.Primary.Attributes["name"])) if response.StatusCode != 404 { return fmt.Errorf("Repository still exists") diff --git a/helper/schema/schema.go b/helper/schema/schema.go index f62c4d128..e3a7b1a44 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -62,10 +62,20 @@ type Schema struct { DiffSuppressFunc SchemaDiffSuppressFunc // If this is non-nil, then this will be a default value that is used - // when this item is not set in the configuration/state. + // when this item is not set in the configuration. // - // DefaultFunc can be specified if you want a dynamic default value. - // Only one of Default or DefaultFunc can be set. + // DefaultFunc can be specified to compute a dynamic default. + // Only one of Default or DefaultFunc can be set. If DefaultFunc is + // used then its return value should be stable to avoid generating + // confusing/perpetual diffs. + // + // Changing either Default or the return value of DefaultFunc can be + // a breaking change, especially if the attribute in question has + // ForceNew set. If a default needs to change to align with changing + // assumptions in an upstream API then it may be necessary to also use + // the MigrateState function on the resource to change the state to match, + // or have the Read function adjust the state value to align with the + // new default. // // If Required is true above, then Default cannot be set. DefaultFunc // can be set with Required. If the DefaultFunc returns nil, then there diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index a2c122d6a..478aa6400 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/hashicorp/terraform/config" + "github.com/mitchellh/mapstructure" ) // EvalValidateError is the error structure returned if there were @@ -85,12 +86,31 @@ func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) { type EvalValidateProvisioner struct { Provisioner *ResourceProvisioner Config **ResourceConfig + ConnConfig **ResourceConfig } func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) { provisioner := *n.Provisioner config := *n.Config - warns, errs := provisioner.Validate(config) + var warns []string + var errs []error + + { + // Validate the provisioner's own config first + w, e := provisioner.Validate(config) + warns = append(warns, w...) + errs = append(errs, e...) + } + + { + // Now validate the connection config, which might either be from + // the provisioner block itself or inherited from the resource's + // shared connection info. + w, e := n.validateConnConfig(*n.ConnConfig) + warns = append(warns, w...) + errs = append(errs, e...) + } + if len(warns) == 0 && len(errs) == 0 { return nil, nil } @@ -101,6 +121,64 @@ func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) { } } +func (n *EvalValidateProvisioner) validateConnConfig(connConfig *ResourceConfig) (warns []string, errs []error) { + // We can't comprehensively validate the connection config since its + // final structure is decided by the communicator and we can't instantiate + // that until we have a complete instance state. However, we *can* catch + // configuration keys that are not valid for *any* communicator, catching + // typos early rather than waiting until we actually try to run one of + // the resource's provisioners. + + type connConfigSuperset struct { + // All attribute types are interface{} here because at this point we + // may still have unresolved interpolation expressions, which will + // appear as strings regardless of the final goal type. + + Type interface{} `mapstructure:"type"` + User interface{} `mapstructure:"user"` + Password interface{} `mapstructure:"password"` + Host interface{} `mapstructure:"host"` + Port interface{} `mapstructure:"port"` + Timeout interface{} `mapstructure:"timeout"` + ScriptPath interface{} `mapstructure:"script_path"` + + // For type=ssh only (enforced in ssh communicator) + PrivateKey interface{} `mapstructure:"private_key"` + Agent interface{} `mapstructure:"agent"` + BastionHost interface{} `mapstructure:"bastion_host"` + BastionPort interface{} `mapstructure:"bastion_port"` + BastionUser interface{} `mapstructure:"bastion_user"` + BastionPassword interface{} `mapstructure:"bastion_password"` + BastionPrivateKey interface{} `mapstructure:"bastion_private_key"` + + // For type=winrm only (enforced in winrm communicator) + HTTPS interface{} `mapstructure:"https"` + Insecure interface{} `mapstructure:"insecure"` + CACert interface{} `mapstructure:"cacert"` + } + + var metadata mapstructure.Metadata + decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + Metadata: &metadata, + Result: &connConfigSuperset{}, // result is disregarded; we only care about unused keys + }) + if err != nil { + // should never happen + errs = append(errs, err) + return + } + + if err := decoder.Decode(connConfig.Config); err != nil { + errs = append(errs, err) + return + } + + for _, attrName := range metadata.Unused { + errs = append(errs, fmt.Errorf("unknown 'connection' argument %q", attrName)) + } + return +} + // EvalValidateResource is an EvalNode implementation that validates // the configuration of a resource. type EvalValidateResource struct { diff --git a/terraform/eval_validate_test.go b/terraform/eval_validate_test.go index ac20f617c..0bde2a870 100644 --- a/terraform/eval_validate_test.go +++ b/terraform/eval_validate_test.go @@ -178,3 +178,117 @@ func TestEvalValidateResource_ignoreWarnings(t *testing.T) { t.Fatalf("Expected no error, got: %s", err) } } + +func TestEvalValidateProvisioner_valid(t *testing.T) { + mp := &MockResourceProvisioner{} + var p ResourceProvisioner = mp + ctx := &MockEvalContext{} + + cfg := &ResourceConfig{} + connInfo, err := config.NewRawConfig(map[string]interface{}{}) + if err != nil { + t.Fatalf("failed to make connInfo: %s", err) + } + connConfig := NewResourceConfig(connInfo) + + node := &EvalValidateProvisioner{ + Provisioner: &p, + Config: &cfg, + ConnConfig: &connConfig, + } + + result, err := node.Eval(ctx) + if err != nil { + t.Fatalf("node.Eval failed: %s", err) + } + if result != nil { + t.Errorf("node.Eval returned non-nil result") + } + + if !mp.ValidateCalled { + t.Fatalf("p.Config not called") + } + if mp.ValidateConfig != cfg { + t.Errorf("p.Config called with wrong config") + } +} + +func TestEvalValidateProvisioner_warning(t *testing.T) { + mp := &MockResourceProvisioner{} + var p ResourceProvisioner = mp + ctx := &MockEvalContext{} + + cfg := &ResourceConfig{} + connInfo, err := config.NewRawConfig(map[string]interface{}{}) + if err != nil { + t.Fatalf("failed to make connInfo: %s", err) + } + connConfig := NewResourceConfig(connInfo) + + node := &EvalValidateProvisioner{ + Provisioner: &p, + Config: &cfg, + ConnConfig: &connConfig, + } + + mp.ValidateReturnWarns = []string{"foo is deprecated"} + + _, err = node.Eval(ctx) + if err == nil { + t.Fatalf("node.Eval succeeded; want error") + } + + valErr, ok := err.(*EvalValidateError) + if !ok { + t.Fatalf("node.Eval error is %#v; want *EvalValidateError", valErr) + } + + warns := valErr.Warnings + if warns == nil || len(warns) != 1 { + t.Fatalf("wrong number of warnings in %#v; want one warning", warns) + } + if warns[0] != mp.ValidateReturnWarns[0] { + t.Fatalf("wrong warning %q; want %q", warns[0], mp.ValidateReturnWarns[0]) + } +} + +func TestEvalValidateProvisioner_connectionInvalid(t *testing.T) { + var p ResourceProvisioner = &MockResourceProvisioner{} + ctx := &MockEvalContext{} + + cfg := &ResourceConfig{} + connInfo, err := config.NewRawConfig(map[string]interface{}{ + "bananananananana": "foo", + "bazaz": "bar", + }) + if err != nil { + t.Fatalf("failed to make connInfo: %s", err) + } + connConfig := NewResourceConfig(connInfo) + + node := &EvalValidateProvisioner{ + Provisioner: &p, + Config: &cfg, + ConnConfig: &connConfig, + } + + _, err = node.Eval(ctx) + if err == nil { + t.Fatalf("node.Eval succeeded; want error") + } + + valErr, ok := err.(*EvalValidateError) + if !ok { + t.Fatalf("node.Eval error is %#v; want *EvalValidateError", valErr) + } + + errs := valErr.Errors + if errs == nil || len(errs) != 2 { + t.Fatalf("wrong number of errors in %#v; want two errors", errs) + } + + errStr := errs[0].Error() + if !(strings.Contains(errStr, "bananananananana") || strings.Contains(errStr, "bazaz")) { + t.Fatalf("wrong first error %q; want something about our invalid connInfo keys", errStr) + } +} diff --git a/terraform/node_resource_validate.go b/terraform/node_resource_validate.go index e01518de4..f528f24b1 100644 --- a/terraform/node_resource_validate.go +++ b/terraform/node_resource_validate.go @@ -129,17 +129,29 @@ func (n *NodeValidatableResourceInstance) EvalTree() EvalNode { // Validate all the provisioners for _, p := range n.Config.Provisioners { var provisioner ResourceProvisioner - seq.Nodes = append(seq.Nodes, &EvalGetProvisioner{ - Name: p.Type, - Output: &provisioner, - }, &EvalInterpolate{ - Config: p.RawConfig.Copy(), - Resource: resource, - Output: &config, - }, &EvalValidateProvisioner{ - Provisioner: &provisioner, - Config: &config, - }) + var connConfig *ResourceConfig + seq.Nodes = append( + seq.Nodes, + &EvalGetProvisioner{ + Name: p.Type, + Output: &provisioner, + }, + &EvalInterpolate{ + Config: p.RawConfig.Copy(), + Resource: resource, + Output: &config, + }, + &EvalInterpolate{ + Config: p.ConnInfo.Copy(), + Resource: resource, + Output: &connConfig, + }, + &EvalValidateProvisioner{ + Provisioner: &provisioner, + Config: &config, + ConnConfig: &connConfig, + }, + ) } return seq diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go new file mode 100644 index 000000000..d64eb2287 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go @@ -0,0 +1,58 @@ +// Package disk implements the Azure ARM Disk service API version +// 2016-04-30-preview. +// +// The Disk Resource Provider Client. +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Disk + APIVersion = "2016-04-30-preview" + + // DefaultBaseURI is the default URI used for the service Disk + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Disk. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go new file mode 100644 index 000000000..6fb03876f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go @@ -0,0 +1,638 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DisksClient is the the Disk Resource Provider Client. +type DisksClient struct { + ManagementClient +} + +// NewDisksClient creates an instance of the DisksClient client. +func NewDisksClient(subscriptionID string) DisksClient { + return NewDisksClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDisksClientWithBaseURI creates an instance of the DisksClient client. +func NewDisksClientWithBaseURI(baseURI string, subscriptionID string) DisksClient { + return DisksClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a disk. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Put disk operation. +func (client DisksClient) CreateOrUpdate(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: diskParameter, + Constraints: []validation.Constraint{{Target: "diskParameter.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "disk.DisksClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client DisksClient) CreateOrUpdatePreparer(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client DisksClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete deletes a disk. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used to +// cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Delete(resourceGroupName string, diskName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, diskName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client DisksClient) DeletePreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client DisksClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets information about a disk. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Get(resourceGroupName string, diskName string) (result Model, err error) { + req, err := client.GetPreparer(resourceGroupName, diskName) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DisksClient) GetPreparer(resourceGroupName string, diskName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DisksClient) GetResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. grantAccessData +// is access data object supplied in the body of the get disk access operation. +func (client DisksClient) GrantAccess(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "disk.DisksClient", "GrantAccess") + } + + req, err := client.GrantAccessPreparer(resourceGroupName, diskName, grantAccessData, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", nil, "Failure preparing request") + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure sending request") + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure responding to request") + } + + return +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client DisksClient) GrantAccessPreparer(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) GrantAccessResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// List lists all the disks under a subscription. +func (client DisksClient) List() (result ListType, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DisksClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DisksClient) ListResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client DisksClient) ListNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists all the disks under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client DisksClient) ListByResourceGroup(resourceGroupName string) (result ListType, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client DisksClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client DisksClient) ListByResourceGroupResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client DisksClient) ListByResourceGroupNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) RevokeAccess(resourceGroupName string, diskName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RevokeAccessPreparer(resourceGroupName, diskName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", nil, "Failure preparing request") + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure sending request") + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure responding to request") + } + + return +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client DisksClient) RevokeAccessPreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) RevokeAccessResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Update updates (patches) a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Patch disk operation. +func (client DisksClient) Update(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.UpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Update", nil, "Failure preparing request") + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure sending request") + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client DisksClient) UpdatePreparer(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client DisksClient) UpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go new file mode 100644 index 000000000..e8118696a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go @@ -0,0 +1,278 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// AccessLevel enumerates the values for access level. +type AccessLevel string + +const ( + // None specifies the none state for access level. + None AccessLevel = "None" + // Read specifies the read state for access level. + Read AccessLevel = "Read" +) + +// CreateOption enumerates the values for create option. +type CreateOption string + +const ( + // Attach specifies the attach state for create option. + Attach CreateOption = "Attach" + // Copy specifies the copy state for create option. + Copy CreateOption = "Copy" + // Empty specifies the empty state for create option. + Empty CreateOption = "Empty" + // FromImage specifies the from image state for create option. + FromImage CreateOption = "FromImage" + // Import specifies the import state for create option. + Import CreateOption = "Import" + // Restore specifies the restore state for create option. + Restore CreateOption = "Restore" +) + +// OperatingSystemTypes enumerates the values for operating system types. +type OperatingSystemTypes string + +const ( + // Linux specifies the linux state for operating system types. + Linux OperatingSystemTypes = "Linux" + // Windows specifies the windows state for operating system types. + Windows OperatingSystemTypes = "Windows" +) + +// StorageAccountTypes enumerates the values for storage account types. +type StorageAccountTypes string + +const ( + // PremiumLRS specifies the premium lrs state for storage account types. + PremiumLRS StorageAccountTypes = "Premium_LRS" + // StandardLRS specifies the standard lrs state for storage account types. + StandardLRS StorageAccountTypes = "Standard_LRS" +) + +// AccessURI is a disk access SAS uri. +type AccessURI struct { + autorest.Response `json:"-"` + *AccessURIOutput `json:"properties,omitempty"` +} + +// AccessURIOutput is azure properties, including output. +type AccessURIOutput struct { + *AccessURIRaw `json:"output,omitempty"` +} + +// AccessURIRaw is this object gets 'bubbled up' through flattening. +type AccessURIRaw struct { + AccessSAS *string `json:"accessSAS,omitempty"` +} + +// APIError is api error. +type APIError struct { + Details *[]APIErrorBase `json:"details,omitempty"` + Innererror *InnerError `json:"innererror,omitempty"` + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// APIErrorBase is api error base. +type APIErrorBase struct { + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// CreationData is data used when creating a disk. +type CreationData struct { + CreateOption CreateOption `json:"createOption,omitempty"` + StorageAccountID *string `json:"storageAccountId,omitempty"` + ImageReference *ImageDiskReference `json:"imageReference,omitempty"` + SourceURI *string `json:"sourceUri,omitempty"` + SourceResourceID *string `json:"sourceResourceId,omitempty"` +} + +// EncryptionSettings is encryption settings for disk or snapshot +type EncryptionSettings struct { + Enabled *bool `json:"enabled,omitempty"` + DiskEncryptionKey *KeyVaultAndSecretReference `json:"diskEncryptionKey,omitempty"` + KeyEncryptionKey *KeyVaultAndKeyReference `json:"keyEncryptionKey,omitempty"` +} + +// GrantAccessData is data used for requesting a SAS. +type GrantAccessData struct { + Access AccessLevel `json:"access,omitempty"` + DurationInSeconds *int32 `json:"durationInSeconds,omitempty"` +} + +// ImageDiskReference is the source image used for creating the disk. +type ImageDiskReference struct { + ID *string `json:"id,omitempty"` + Lun *int32 `json:"lun,omitempty"` +} + +// InnerError is inner error details. +type InnerError struct { + Exceptiontype *string `json:"exceptiontype,omitempty"` + Errordetail *string `json:"errordetail,omitempty"` +} + +// KeyVaultAndKeyReference is key Vault Key Url and vault id of KeK, KeK is +// optional and when provided is used to unwrap the encryptionKey +type KeyVaultAndKeyReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + KeyURL *string `json:"keyUrl,omitempty"` +} + +// KeyVaultAndSecretReference is key Vault Secret Url and vault id of the +// encryption key +type KeyVaultAndSecretReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + SecretURL *string `json:"secretUrl,omitempty"` +} + +// ListType is the List Disks operation response. +type ListType struct { + autorest.Response `json:"-"` + Value *[]Model `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ListTypePreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ListType) ListTypePreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// Model is disk resource. +type Model struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// OperationStatusResponse is operation status response +type OperationStatusResponse struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Error *APIError `json:"error,omitempty"` +} + +// Properties is disk resource properties. +type Properties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + TimeCreated *date.Time `json:"timeCreated,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + OwnerID *string `json:"ownerId,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Resource is the Resource model definition. +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceUpdate is the Resource model definition. +type ResourceUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` +} + +// Snapshot is snapshot resource. +type Snapshot struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// SnapshotList is the List Snapshots operation response. +type SnapshotList struct { + autorest.Response `json:"-"` + Value *[]Snapshot `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SnapshotListPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SnapshotList) SnapshotListPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SnapshotUpdate is snapshot update resource. +type SnapshotUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} + +// SourceVault is the vault id is an Azure Resource Manager Resoure id in the +// form +// /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName} +type SourceVault struct { + ID *string `json:"id,omitempty"` +} + +// UpdateProperties is disk resource update properties. +type UpdateProperties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` +} + +// UpdateType is disk update resource. +type UpdateType struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go new file mode 100644 index 000000000..20e6ec758 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go @@ -0,0 +1,643 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SnapshotsClient is the the Disk Resource Provider Client. +type SnapshotsClient struct { + ManagementClient +} + +// NewSnapshotsClient creates an instance of the SnapshotsClient client. +func NewSnapshotsClient(subscriptionID string) SnapshotsClient { + return NewSnapshotsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSnapshotsClientWithBaseURI creates an instance of the SnapshotsClient +// client. +func NewSnapshotsClientWithBaseURI(baseURI string, subscriptionID string) SnapshotsClient { + return SnapshotsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Put disk operation. +func (client SnapshotsClient) CreateOrUpdate(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: snapshot, + Constraints: []validation.Constraint{{Target: "snapshot.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "snapshot.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SnapshotsClient) CreateOrUpdatePreparer(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) CreateOrUpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete deletes a snapshot. This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Delete(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client SnapshotsClient) DeletePreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets information about a snapshot. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Get(resourceGroupName string, snapshotName string) (result Snapshot, err error) { + req, err := client.GetPreparer(resourceGroupName, snapshotName) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SnapshotsClient) GetPreparer(resourceGroupName string, snapshotName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GetResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// grantAccessData is access data object supplied in the body of the get +// snapshot access operation. +func (client SnapshotsClient) GrantAccess(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "GrantAccess") + } + + req, err := client.GrantAccessPreparer(resourceGroupName, snapshotName, grantAccessData, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", nil, "Failure preparing request") + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure sending request") + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure responding to request") + } + + return +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client SnapshotsClient) GrantAccessPreparer(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GrantAccessResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// List lists snapshots under a subscription. +func (client SnapshotsClient) List() (result SnapshotList, err error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SnapshotsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists snapshots under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client SnapshotsClient) ListByResourceGroup(resourceGroupName string) (result SnapshotList, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client SnapshotsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListByResourceGroupResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListByResourceGroupNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) RevokeAccess(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.RevokeAccessPreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", nil, "Failure preparing request") + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure sending request") + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure responding to request") + } + + return +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client SnapshotsClient) RevokeAccessPreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) RevokeAccessResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Update updates (patches) a snapshot. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Patch snapshot +// operation. +func (client SnapshotsClient) Update(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (result autorest.Response, err error) { + req, err := client.UpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", nil, "Failure preparing request") + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure sending request") + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client SnapshotsClient) UpdatePreparer(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) UpdateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go new file mode 100644 index 000000000..9b5497d54 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go @@ -0,0 +1,60 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "bytes" + "fmt" + "strings" +) + +const ( + major = "8" + minor = "1" + patch = "0" + tag = "beta" + userAgentFormat = "Azure-SDK-For-Go/%s arm-%s/%s" +) + +// cached results of UserAgent and Version to prevent repeated operations. +var ( + userAgent string + version string +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + if userAgent == "" { + userAgent = fmt.Sprintf(userAgentFormat, Version(), "disk", "2016-04-30-preview") + } + return userAgent +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + if version == "" { + versionBuilder := bytes.NewBufferString(fmt.Sprintf("%s.%s.%s", major, minor, patch)) + if tag != "" { + versionBuilder.WriteRune('-') + versionBuilder.WriteString(strings.TrimPrefix(tag, "-")) + } + version = string(versionBuilder.Bytes()) + } + return version +} diff --git a/vendor/vendor.json b/vendor/vendor.json index ba7383b71..7b007d414 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -50,6 +50,14 @@ "version": "v8.1.0-beta", "versionExact": "v8.1.0-beta" }, + { + "checksumSHA1": "iAZi+Mh1Tivk3bdBbAEz+bd5nPg=", + "path": "github.com/Azure/azure-sdk-for-go/arm/disk", + "revision": "ecf40e315d5ab0ca6d7b3b7f7fbb5c1577814813", + "revisionTime": "2017-03-02T00:14:02Z", + "version": "v8.1.0-beta", + "versionExact": "v8.1.0-beta" + }, { "checksumSHA1": "ro1i9qoJcSgbWgV7D93wXhBwoL8=", "comment": "v2.1.1-beta-8-gca4d906", diff --git a/website/Gemfile b/website/Gemfile index 08e6fe65e..405a8c992 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.13" +gem "middleman-hashicorp", "0.3.22" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index 0811f6d62..229218ac9 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -6,7 +6,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (6.7.6) + autoprefixer-rails (6.7.7.1) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -77,7 +77,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.13) + middleman-hashicorp (0.3.22) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -103,7 +103,7 @@ GEM mini_portile2 (2.1.0) minitest (5.10.1) multi_json (1.12.1) - nokogiri (1.7.0.1) + nokogiri (1.7.1) mini_portile2 (~> 2.1.0) padrino-helpers (0.12.8.1) i18n (~> 0.6, >= 0.6.7) @@ -138,7 +138,7 @@ GEM turbolinks (5.0.1) turbolinks-source (~> 5) turbolinks-source (5.0.0) - tzinfo (1.2.2) + tzinfo (1.2.3) thread_safe (~> 0.1) uber (0.0.15) uglifier (2.7.2) @@ -151,7 +151,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.13) + middleman-hashicorp (= 0.3.22) BUNDLED WITH 1.14.6 diff --git a/website/Makefile b/website/Makefile index 41fcf114e..d7620d1c2 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,14 +1,24 @@ -VERSION?="0.3.13" +VERSION?="0.3.22" + +build: + @echo "==> Starting build in Docker..." + @docker run \ + --interactive \ + --rm \ + --tty \ + --volume "$(shell pwd):/website" \ + hashicorp/middleman-hashicorp:${VERSION} \ + bundle exec middleman build --verbose --clean website: @echo "==> Starting website in Docker..." @docker run \ - --interactive \ - --rm \ + --interactive \ + --rm \ --tty \ --publish "4567:4567" \ --publish "35729:35729" \ --volume "$(shell pwd):/website" \ hashicorp/middleman-hashicorp:${VERSION} -.PHONY: website +.PHONY: build website diff --git a/website/config.rb b/website/config.rb index 6e2d25511..b58df71f0 100644 --- a/website/config.rb +++ b/website/config.rb @@ -7,6 +7,15 @@ activate :hashicorp do |h| end helpers do + # Returns the FQDN of the image URL. + # + # @param [String] path + # + # @return [String] + def image_url(path) + File.join(base_url, image_path(path)) + end + # Get the title for the page. # # @param [Middleman::Page] page @@ -26,17 +35,66 @@ helpers do # # @return [String] def description_for(page) - return escape_html(page.data.description || "") + description = (page.data.description || "") + .gsub('"', '') + .gsub(/\n+/, ' ') + .squeeze(' ') + + return escape_html(description) end # This helps by setting the "active" class for sidebar nav elements # if the YAML frontmatter matches the expected value. def sidebar_current(expected) current = current_page.data.sidebar_current || "" - if current == expected or (expected.is_a?(Regexp) and expected.match(current)) + if current.start_with?(expected) return " class=\"active\"" else return "" end end + + # Returns the id for this page. + # @return [String] + def body_id_for(page) + if !(name = page.data.sidebar_current).blank? + return "page-#{name.strip}" + end + if page.url == "/" || page.url == "/index.html" + return "page-home" + end + if !(title = page.data.page_title).blank? + return title + .downcase + .gsub('"', '') + .gsub(/[^\w]+/, '-') + .gsub(/_+/, '-') + .squeeze('-') + .squeeze(' ') + end + return "" + end + + # Returns the list of classes for this page. + # @return [String] + def body_classes_for(page) + classes = [] + + if !(layout = page.data.layout).blank? + classes << "layout-#{page.data.layout}" + end + + if !(title = page.data.page_title).blank? + title = title + .downcase + .gsub('"', '') + .gsub(/[^\w]+/, '-') + .gsub(/_+/, '-') + .squeeze('-') + .squeeze(' ') + classes << "page-#{title}" + end + + return classes.join(" ") + end end diff --git a/website/packer.json b/website/packer.json index b51f63801..35de63232 100644 --- a/website/packer.json +++ b/website/packer.json @@ -8,7 +8,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.13", + "image": "hashicorp/middleman-hashicorp:0.3.22", "discard": "true", "run_command": ["-d", "-i", "-t", "{{ .Image }}", "/bin/sh"] } diff --git a/website/source/.gitignore b/website/source/.gitignore deleted file mode 100644 index 67550a149..000000000 --- a/website/source/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Source folder -node_modules/ diff --git a/website/source/404.html.erb b/website/source/404.html.erb deleted file mode 100644 index f49742d5d..000000000 --- a/website/source/404.html.erb +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: "inner" -noindex: true -page_title: "404" ---- - -

Page not found

- -

-Unfortunately, the page you requested can't be found. -

diff --git a/website/source/404.html.md b/website/source/404.html.md new file mode 100644 index 000000000..e99ce088b --- /dev/null +++ b/website/source/404.html.md @@ -0,0 +1,14 @@ +--- +layout: "inner" +page_title: "Not Found" +noindex: true +description: |- + Page not found! +--- + +# Page Not Found + +Sorry, the page you tried to visit does not exist. This could be our fault, +and if so we will fix that up right away. + +Please go back, or go back to get back on track. diff --git a/website/source/android-manifest.json.erb b/website/source/android-manifest.json.erb new file mode 100644 index 000000000..224636a38 --- /dev/null +++ b/website/source/android-manifest.json.erb @@ -0,0 +1,18 @@ +{ + "name": "HashiCorp Terraform", + "icons": [ + { + "src": "<%= image_path('favicons/android-chrome-192x192.png') %>", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "<%= image_path('favicons/android-chrome-512x512.png') %>", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/website/source/assets/files/press-kit.zip b/website/source/assets/files/press-kit.zip new file mode 100644 index 000000000..dde265f79 Binary files /dev/null and b/website/source/assets/files/press-kit.zip differ diff --git a/website/source/assets/images/bg-galaxy.jpg b/website/source/assets/images/bg-galaxy.jpg deleted file mode 100644 index 587004afa..000000000 Binary files a/website/source/assets/images/bg-galaxy.jpg and /dev/null differ diff --git a/website/source/assets/images/bg-static.png b/website/source/assets/images/bg-static.png deleted file mode 100644 index 7d6436172..000000000 Binary files a/website/source/assets/images/bg-static.png and /dev/null differ diff --git a/website/source/assets/images/customer-logos/capital-one.svg b/website/source/assets/images/customer-logos/capital-one.svg deleted file mode 100644 index a03474332..000000000 --- a/website/source/assets/images/customer-logos/capital-one.svg +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/customer-logos/hbo.svg b/website/source/assets/images/customer-logos/hbo.svg deleted file mode 100644 index 784d540d0..000000000 --- a/website/source/assets/images/customer-logos/hbo.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - diff --git a/website/source/assets/images/customer-logos/home-depot.svg b/website/source/assets/images/customer-logos/home-depot.svg deleted file mode 100644 index 553b5ef97..000000000 --- a/website/source/assets/images/customer-logos/home-depot.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - diff --git a/website/source/assets/images/customer-logos/hotels-dot-com.svg b/website/source/assets/images/customer-logos/hotels-dot-com.svg deleted file mode 100644 index 1d84ec6e6..000000000 --- a/website/source/assets/images/customer-logos/hotels-dot-com.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/customer-logos/nike.svg b/website/source/assets/images/customer-logos/nike.svg deleted file mode 100644 index 51fa23ceb..000000000 --- a/website/source/assets/images/customer-logos/nike.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/customer-logos/target.svg b/website/source/assets/images/customer-logos/target.svg deleted file mode 100644 index 4d8094a6a..000000000 --- a/website/source/assets/images/customer-logos/target.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/docs/atlas-workflow.png b/website/source/assets/images/docs/atlas-workflow.png deleted file mode 100644 index 144e2cedc..000000000 Binary files a/website/source/assets/images/docs/atlas-workflow.png and /dev/null differ diff --git a/website/source/assets/images/graph-example.png b/website/source/assets/images/docs/graph-example.png similarity index 100% rename from website/source/assets/images/graph-example.png rename to website/source/assets/images/docs/graph-example.png diff --git a/website/source/assets/images/enterprise-callout-bg copy.svg b/website/source/assets/images/enterprise-callout-bg copy.svg new file mode 100644 index 000000000..14a97072a --- /dev/null +++ b/website/source/assets/images/enterprise-callout-bg copy.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/website/source/assets/images/enterprise-callout-bg.svg b/website/source/assets/images/enterprise-callout-bg.svg index c7c2649f2..ee4ba0afc 100644 --- a/website/source/assets/images/enterprise-callout-bg.svg +++ b/website/source/assets/images/enterprise-callout-bg.svg @@ -1,21 +1,8 @@ - - - - - - - - - - - - - - - - + + + + + + + diff --git a/website/source/assets/images/favicon.png b/website/source/assets/images/favicon.png deleted file mode 100644 index 14d04676c..000000000 Binary files a/website/source/assets/images/favicon.png and /dev/null differ diff --git a/website/source/assets/images/favicons/android-chrome-192x192.png b/website/source/assets/images/favicons/android-chrome-192x192.png new file mode 100644 index 000000000..c35bdbed5 Binary files /dev/null and b/website/source/assets/images/favicons/android-chrome-192x192.png differ diff --git a/website/source/assets/images/favicons/android-chrome-512x512.png b/website/source/assets/images/favicons/android-chrome-512x512.png new file mode 100644 index 000000000..83a03ab49 Binary files /dev/null and b/website/source/assets/images/favicons/android-chrome-512x512.png differ diff --git a/website/source/assets/images/favicons/apple-touch-icon.png b/website/source/assets/images/favicons/apple-touch-icon.png new file mode 100644 index 000000000..91cb96176 Binary files /dev/null and b/website/source/assets/images/favicons/apple-touch-icon.png differ diff --git a/website/source/assets/images/favicons/favicon-16x16.png b/website/source/assets/images/favicons/favicon-16x16.png new file mode 100644 index 000000000..a474f146f Binary files /dev/null and b/website/source/assets/images/favicons/favicon-16x16.png differ diff --git a/website/source/assets/images/favicons/favicon-32x32.png b/website/source/assets/images/favicons/favicon-32x32.png new file mode 100644 index 000000000..576c5402f Binary files /dev/null and b/website/source/assets/images/favicons/favicon-32x32.png differ diff --git a/website/source/assets/images/favicons/favicon.ico b/website/source/assets/images/favicons/favicon.ico new file mode 100644 index 000000000..fd3d1442e Binary files /dev/null and b/website/source/assets/images/favicons/favicon.ico differ diff --git a/website/source/assets/images/favicons/mstile-150x150.png b/website/source/assets/images/favicons/mstile-150x150.png new file mode 100644 index 000000000..d81ed5df7 Binary files /dev/null and b/website/source/assets/images/favicons/mstile-150x150.png differ diff --git a/website/source/assets/images/favicons/safari-pinned-tab.svg b/website/source/assets/images/favicons/safari-pinned-tab.svg new file mode 100644 index 000000000..d331c170c --- /dev/null +++ b/website/source/assets/images/favicons/safari-pinned-tab.svg @@ -0,0 +1,22 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + + + diff --git a/website/source/assets/images/feature-card-create.svg b/website/source/assets/images/feature-card-create.svg index 0c77fe438..c45fc221e 100644 --- a/website/source/assets/images/feature-card-create.svg +++ b/website/source/assets/images/feature-card-create.svg @@ -1,15 +1,6 @@ - - - - - - - - - - + + + + + diff --git a/website/source/assets/images/feature-card-plan.svg b/website/source/assets/images/feature-card-plan.svg index 765579dce..c1a010733 100644 --- a/website/source/assets/images/feature-card-plan.svg +++ b/website/source/assets/images/feature-card-plan.svg @@ -1,31 +1,3 @@ - - - - - - - - - - - - - - - - - + + diff --git a/website/source/assets/images/feature-card-write.svg b/website/source/assets/images/feature-card-write.svg index 3e81bc1b2..9be021d9a 100644 --- a/website/source/assets/images/feature-card-write.svg +++ b/website/source/assets/images/feature-card-write.svg @@ -1,24 +1,3 @@ - - - - - - - - - - - - - - - - - - - - + + diff --git a/website/source/assets/images/feature-create-bg.svg b/website/source/assets/images/feature-create-bg.svg index 80d89b0f8..0392a2c6a 100644 --- a/website/source/assets/images/feature-create-bg.svg +++ b/website/source/assets/images/feature-create-bg.svg @@ -1,312 +1,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/source/assets/images/feature-plan-bg.svg b/website/source/assets/images/feature-plan-bg.svg index 31059abf9..9d9e3e012 100644 --- a/website/source/assets/images/feature-plan-bg.svg +++ b/website/source/assets/images/feature-plan-bg.svg @@ -1,429 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/source/assets/images/feature-plan-sm-bg.svg b/website/source/assets/images/feature-plan-sm-bg.svg deleted file mode 100644 index cf38d86f0..000000000 --- a/website/source/assets/images/feature-plan-sm-bg.svg +++ /dev/null @@ -1,398 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/feature-write-bg.svg b/website/source/assets/images/feature-write-bg.svg index c3ecbb76b..32224066e 100644 --- a/website/source/assets/images/feature-write-bg.svg +++ b/website/source/assets/images/feature-write-bg.svg @@ -1,253 +1,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/website/source/assets/images/footer-hashicorp-logo.png b/website/source/assets/images/footer-hashicorp-logo.png deleted file mode 100644 index 96ac85814..000000000 Binary files a/website/source/assets/images/footer-hashicorp-logo.png and /dev/null differ diff --git a/website/source/assets/images/footer-hashicorp-logo@2x.png b/website/source/assets/images/footer-hashicorp-logo@2x.png deleted file mode 100644 index 34699040a..000000000 Binary files a/website/source/assets/images/footer-hashicorp-logo@2x.png and /dev/null differ diff --git a/website/source/assets/images/footer-hashicorp-white-logo.png b/website/source/assets/images/footer-hashicorp-white-logo.png deleted file mode 100644 index 9fddc9779..000000000 Binary files a/website/source/assets/images/footer-hashicorp-white-logo.png and /dev/null differ diff --git a/website/source/assets/images/footer-hashicorp-white-logo@2x.png b/website/source/assets/images/footer-hashicorp-white-logo@2x.png deleted file mode 100644 index a0b479799..000000000 Binary files a/website/source/assets/images/footer-hashicorp-white-logo@2x.png and /dev/null differ diff --git a/website/source/assets/images/header-download-icon.png b/website/source/assets/images/header-download-icon.png deleted file mode 100644 index bface9334..000000000 Binary files a/website/source/assets/images/header-download-icon.png and /dev/null differ diff --git a/website/source/assets/images/header-download-icon@2x.png b/website/source/assets/images/header-download-icon@2x.png deleted file mode 100644 index bd1c9a313..000000000 Binary files a/website/source/assets/images/header-download-icon@2x.png and /dev/null differ diff --git a/website/source/assets/images/header-github-icon.png b/website/source/assets/images/header-github-icon.png deleted file mode 100644 index 5bef9cb89..000000000 Binary files a/website/source/assets/images/header-github-icon.png and /dev/null differ diff --git a/website/source/assets/images/header-github-icon@2x.png b/website/source/assets/images/header-github-icon@2x.png deleted file mode 100644 index ab15e12df..000000000 Binary files a/website/source/assets/images/header-github-icon@2x.png and /dev/null differ diff --git a/website/source/assets/images/header-nav-divider.png b/website/source/assets/images/header-nav-divider.png deleted file mode 100644 index 130f1c71d..000000000 Binary files a/website/source/assets/images/header-nav-divider.png and /dev/null differ diff --git a/website/source/assets/images/header-nav-divider@2x.png b/website/source/assets/images/header-nav-divider@2x.png deleted file mode 100644 index a747226e5..000000000 Binary files a/website/source/assets/images/header-nav-divider@2x.png and /dev/null differ diff --git a/website/source/assets/images/hero-bg.png b/website/source/assets/images/hero-bg.png deleted file mode 100644 index 61cac8172..000000000 Binary files a/website/source/assets/images/hero-bg.png and /dev/null differ diff --git a/website/source/assets/images/latest-announce-bg.svg b/website/source/assets/images/latest-announce-bg.svg deleted file mode 100644 index 1513807fd..000000000 --- a/website/source/assets/images/latest-announce-bg.svg +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/logo-hashicorp.svg b/website/source/assets/images/logo-hashicorp.svg new file mode 100644 index 000000000..e7dce0da4 --- /dev/null +++ b/website/source/assets/images/logo-hashicorp.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/website/source/assets/images/logo-header-black@2x.png b/website/source/assets/images/logo-header-black@2x.png deleted file mode 100644 index 312f8692e..000000000 Binary files a/website/source/assets/images/logo-header-black@2x.png and /dev/null differ diff --git a/website/source/assets/images/logo-header.png b/website/source/assets/images/logo-header.png deleted file mode 100644 index 76f5eae3a..000000000 Binary files a/website/source/assets/images/logo-header.png and /dev/null differ diff --git a/website/source/assets/images/logo-header.svg b/website/source/assets/images/logo-header.svg deleted file mode 100644 index 7f9e690f4..000000000 --- a/website/source/assets/images/logo-header.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - HashiCorp Terraform - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/source/assets/images/logo-header@2x.png b/website/source/assets/images/logo-header@2x.png deleted file mode 100644 index 1fc0bf2e3..000000000 Binary files a/website/source/assets/images/logo-header@2x.png and /dev/null differ diff --git a/website/source/assets/images/logo-static.png b/website/source/assets/images/logo-static.png deleted file mode 100644 index 7cfecc36a..000000000 Binary files a/website/source/assets/images/logo-static.png and /dev/null differ diff --git a/website/source/assets/images/logo-text.svg b/website/source/assets/images/logo-text.svg new file mode 100644 index 000000000..5ff7645c2 --- /dev/null +++ b/website/source/assets/images/logo-text.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/website/source/assets/images/logo_large.png b/website/source/assets/images/logo_large.png deleted file mode 100644 index 94b66fdae..000000000 Binary files a/website/source/assets/images/logo_large.png and /dev/null differ diff --git a/website/source/assets/images/og-image.png b/website/source/assets/images/og-image.png new file mode 100644 index 000000000..dbc7d61cc Binary files /dev/null and b/website/source/assets/images/og-image.png differ diff --git a/website/source/assets/images/readme.png b/website/source/assets/images/readme.png deleted file mode 100644 index bec5aa7f5..000000000 Binary files a/website/source/assets/images/readme.png and /dev/null differ diff --git a/website/source/assets/images/sidebar-wire.png b/website/source/assets/images/sidebar-wire.png deleted file mode 100644 index 87ccdf351..000000000 Binary files a/website/source/assets/images/sidebar-wire.png and /dev/null differ diff --git a/website/source/assets/images/terraform-enterprise-logo.svg b/website/source/assets/images/terraform-enterprise-logo.svg index 5c1b21abe..7bbdd0055 100644 --- a/website/source/assets/images/terraform-enterprise-logo.svg +++ b/website/source/assets/images/terraform-enterprise-logo.svg @@ -1,47 +1,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/source/assets/images/webinar-Terraform-4-4-2017.jpg b/website/source/assets/images/webinar-Terraform-4-4-2017.jpg deleted file mode 100644 index 1bc50497c..000000000 Binary files a/website/source/assets/images/webinar-Terraform-4-4-2017.jpg and /dev/null differ diff --git a/website/source/assets/images/webinar-Terraform-4-4-2017@2x.jpg b/website/source/assets/images/webinar-Terraform-4-4-2017@2x.jpg deleted file mode 100644 index 17b3aa725..000000000 Binary files a/website/source/assets/images/webinar-Terraform-4-4-2017@2x.jpg and /dev/null differ diff --git a/website/source/assets/images/webinar-image.jpg b/website/source/assets/images/webinar-image.jpg deleted file mode 100644 index c670b8594..000000000 Binary files a/website/source/assets/images/webinar-image.jpg and /dev/null differ diff --git a/website/source/assets/images/webinar-image@2x.jpg b/website/source/assets/images/webinar-image@2x.jpg deleted file mode 100644 index f03b20ac9..000000000 Binary files a/website/source/assets/images/webinar-image@2x.jpg and /dev/null differ diff --git a/website/source/assets/images/white-wireframe.png b/website/source/assets/images/white-wireframe.png deleted file mode 100644 index 831c0145b..000000000 Binary files a/website/source/assets/images/white-wireframe.png and /dev/null differ diff --git a/website/source/assets/images/white-wireframe@2x.png b/website/source/assets/images/white-wireframe@2x.png deleted file mode 100644 index 3afe389ea..000000000 Binary files a/website/source/assets/images/white-wireframe@2x.png and /dev/null differ diff --git a/website/source/assets/javascripts/app/_Docs.js b/website/source/assets/javascripts/app/_Docs.js deleted file mode 100644 index 5f35a8cd7..000000000 --- a/website/source/assets/javascripts/app/_Docs.js +++ /dev/null @@ -1,46 +0,0 @@ -(function(){ - -var Init = { - - start: function(){ - var classname = this.hasClass(document.body, 'page-sub'); - - if (classname) { - this.addEventListeners(); - } - }, - - hasClass: function (elem, className) { - return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' '); - }, - - addEventListeners: function(){ - var _this = this; - //console.log(document.querySelectorAll('.navbar-static-top')[0]); - window.addEventListener('resize', _this.resizeImage, false); - - this.resizeImage(); - }, - - resizeImage: function(){ - - var header = document.getElementById('header'), - footer = document.getElementById('footer'), - main = document.getElementById('main-content'), - vp = window.innerHeight, - bodyHeight = document.body.clientHeight, - hHeight = header.clientHeight, - fHeight = footer.clientHeight, - withMinHeight = hHeight + fHeight + 830; - - if(withMinHeight < vp && bodyHeight < vp){ - var newHeight = (vp - (hHeight+fHeight)) + 'px'; - main.style.height = newHeight; - } - } - -}; - -Init.start(); - -})(); diff --git a/website/source/assets/javascripts/app/_Engine.Particle.Fixed.js b/website/source/assets/javascripts/app/_Engine.Particle.Fixed.js deleted file mode 100644 index 530edad9c..000000000 --- a/website/source/assets/javascripts/app/_Engine.Particle.Fixed.js +++ /dev/null @@ -1,77 +0,0 @@ -(function( - Particle, - Engine, - Vector -){ - -Particle.Fixed = function(width, height){ - var targetX, targetY; - - this.radius = Engine.getRandomFloat(0.1, 1); - // this.fillA = 'rgba(136,67,237,' + Engine.getRandomFloat(0.4, 0.5) + ')'; - // this.fillB = 'rgba(136,67,237,' + Engine.getRandomFloat(0.51, 0.6) + ')'; - this.fillA = '#3a1066'; - this.fillB = '#561799'; - this.frameMax = Engine.getRandomInt(4, 10); - - this.max = { - x: width + this.maxRadius, - y: height + this.maxRadius - }; - - this.min = { - x: 0 - this.maxRadius, - y: 0 - this.maxRadius - }; - - targetX = Engine.getRandomInt(0 + this.radius, width + this.radius); - targetY = Engine.getRandomInt(0 + this.radius, height + this.radius); - - this.pos = new Vector(targetX, targetY); -}; - -Engine.Particle.Fixed.prototype = { - - radius: 1, - - pos: { - x: 0, - y: 0 - }, - - frame: 0, - showA: false, - - update: function(engine){ - this.frame++; - if (this.frame > this.frameMax) { - this.frame = 0; - this.showA = !this.showA; - } - return this; - }, - - draw: function(ctx, scale){ - // Draw a circle - far less performant - ctx.beginPath(); - ctx.arc( - this.pos.x * scale >> 0, - this.pos.y * scale >> 0, - this.radius * scale, - 0, - Math.PI * 2, - false - ); - if (this.showA) { - ctx.fillStyle = this.fillA; - } else { - ctx.fillStyle = this.fillB; - } - ctx.fill(); - - return this; - } - -}; - -})(window.Engine.Particle, window.Engine, window.Vector); diff --git a/website/source/assets/javascripts/app/_Engine.Particle.js b/website/source/assets/javascripts/app/_Engine.Particle.js deleted file mode 100644 index 6666ac8c9..000000000 --- a/website/source/assets/javascripts/app/_Engine.Particle.js +++ /dev/null @@ -1,154 +0,0 @@ -(function( - Engine, - Vector -){ - -Engine.Particle = function(width, height){ - var side, targetX, targetY; - this.accel = Vector.coerce(this.accel); - this.vel = Vector.coerce(this.vel); - this.pos = new Vector(0, 0); - - this.maxRadius = Engine.getRandomFloat(0.1, 2.5); - // this.maxSpeed = Engine.getRandomFloat(0.01, 1000); - this.maxSpeed = Engine.getRandomFloat(20, 1000); - - // Pick a random target - side = Engine.getRandomInt(0, 3); - if (side === 0 || side === 2) { - targetY = (side === 0) ? -(height / 2) : (height / 2); - targetX = Engine.getRandomInt(-(width / 2), width / 2); - } else { - targetY = Engine.getRandomInt(-(height / 2), height / 2); - targetX = (side === 3) ? -(width / 2) : (width / 2); - } - - this.target = new Vector(targetX, targetY); - this.getAccelVector(); - - this.maxDistance = this.distanceTo(this.target); - - this.fillA = '#8750c2'; - this.fillB = '#b976ff'; - this.frameMax = Engine.getRandomInt(1, 5); -}; - -Engine.Particle.prototype = { - - radius: 1, - - frame: 0, - showA: false, - - accel: { - x: 0, - y: 0 - }, - - vel: { - x: 0, - y: 0 - }, - - pos: { - x: 0, - y: 0 - }, - - opacity: 1, - - maxSpeed: 1500, - maxForce: 1500, - - getAccelVector: function(){ - this.accel = Vector.sub(this.target, this.pos) - .normalize() - .mult(this.maxSpeed); - }, - - update: function(engine){ - var distancePercent, halfWidth, halfHeight; - - this.vel - .add(this.accel) - .limit(this.maxSpeed); - - this.pos.add(Vector.mult(this.vel, engine.tick)); - - halfWidth = engine.width / 2 + this.maxRadius; - halfHeight = engine.height / 2 + this.maxRadius; - - if ( - this.pos.x < -(halfWidth) || - this.pos.x > halfWidth || - this.pos.y < -(halfHeight) || - this.pos.y > halfHeight - ) { - this.kill(engine); - } - - distancePercent = (this.maxDistance - this.distanceTo(this.target)) / this.maxDistance; - this.radius = Math.max(0.1, this.maxRadius * distancePercent); - - this.frame++; - if (this.frame > this.frameMax) { - this.frame = 0; - this.showA = !this.showA; - } - - if (this.showA) { - engine.particlesA[engine.particlesA.length] = this; - } else { - engine.particlesB[engine.particlesB.length] = this; - } - - return this; - }, - - draw: function(ctx, scale){ - if (this.radius < 0.25) { - return; - } - - if (this.showA) { - ctx.fillStyle = this.fillA; - } else { - ctx.fillStyle = this.fillB; - } - - // Draw a square - very performant - ctx.fillRect( - this.pos.x * scale >> 0, - this.pos.y * scale >> 0, - this.radius * scale, - this.radius * scale - ); - - // Draw a circle - far less performant - // ctx.beginPath(); - // ctx.arc( - // this.pos.x * scale, - // this.pos.y * scale, - // this.radius * scale, - // 0, - // Math.PI * 2, - // false - // ); - // ctx.fill(); - - return this; - }, - - kill: function(engine){ - engine._deferredParticles.push(this); - return this; - }, - - distanceTo: function(target) { - var xd = this.pos.x - target.x; - var yd = this.pos.y - target.y; - return Math.sqrt(xd * xd + yd * yd ); - } -}; - -})(window.Engine, window.Vector); diff --git a/website/source/assets/javascripts/app/_Engine.Point.Puller.js b/website/source/assets/javascripts/app/_Engine.Point.Puller.js deleted file mode 100644 index 910093a60..000000000 --- a/website/source/assets/javascripts/app/_Engine.Point.Puller.js +++ /dev/null @@ -1,153 +0,0 @@ -(function( - Engine, - Vector -){ - -Engine.Point.Puller = function(id, x, y, shapeSize){ - this.id = id; - - this.shapeSize = shapeSize; - this.ref = new Vector(x, y); - - this.pos = new Vector( - x * shapeSize.x, - y * shapeSize.y - ); - - this.home = this.pos.clone(); - this.accel = Vector.coerce(this.accel); - this.vel = Vector.coerce(this.vel); -}; - -Engine.Point.Puller.prototype = { - - fillStyle: null, - defaultFillstyle: '#b976ff', - chasingFillstyle: '#ff6b6b', - - radius: 1, - - maxSpeed: 160, - maxForce: 50, - - pos: { - x: 0, - y: 0 - }, - - accel: { - x: 0, - y: 0 - }, - - vel: { - x: 0, - y: 0 - }, - - aRad: 200, - - safety: 0.25, - - resize: function(){ - this.home.x = this.pos.x = this.ref.x * this.shapeSize.x; - this.home.y = this.pos.y = this.ref.y * this.shapeSize.y; - - return this; - }, - - update: function(engine){ - var target = Vector.coerce(engine.mouse), - distanceToMouse, toHome, mag, safety; - - target.x += (this.shapeSize.x - engine.width) / 2; - target.y += (this.shapeSize.y - engine.height) / 2; - - distanceToMouse = this.distanceTo(target); - - this.accel.mult(0); - - if (distanceToMouse < this.aRad) { - this._chasing = true; - this.toChase(target); - this.fillStyle = this.chasingFillstyle; - } else { - this._chasing = false; - this.fillStyle = this.defaultFillstyle; - } - - this.toChase(this.home, this.maxForce / 2); - - this.vel.add(this.accel); - this.pos.add( - Vector.mult(this.vel, engine.tick) - ); - - toHome = Vector.sub(this.home, this.pos); - mag = toHome.mag(); - safety = this.aRad * (this.safety * 3); - if (mag > this.aRad - safety) { - toHome.normalize(); - toHome.mult(this.aRad - safety); - this.pos = Vector.sub(this.home, toHome); - } - - target = null; - toHome = null; - return this; - }, - - toChase: function(target, maxForce){ - var desired, steer, distance, mult, safety; - - maxForce = maxForce || this.maxForce; - - target = Vector.coerce(target); - desired = Vector.sub(target, this.pos); - distance = desired.mag(); - desired.normalize(); - - safety = this.aRad * this.safety; - - if (distance < safety) { - mult = Engine.map(distance, 0, safety, 0, this.maxSpeed); - } else if (distance > this.aRad - safety){ - mult = Engine.map(this.aRad - distance, 0, safety, 0, this.maxSpeed); - } else { - mult = this.maxSpeed; - } - - desired.mult(mult); - - steer = Vector.sub(desired, this.vel); - steer.limit(maxForce); - this.accel.add(steer); - - target = null; - desired = null; - steer = null; - }, - - draw: function(ctx, scale){ - ctx.fillStyle = this.fillStyle; - ctx.fillRect( - (this.pos.x - this.radius / 2) * scale >> 0, - (this.pos.y - this.radius / 2) * scale >> 0, - this.radius * scale, - this.radius * scale - ); - - return this; - }, - - distanceTo: function(target) { - var xd = this.home.x - target.x; - var yd = this.home.y - target.y; - return Math.sqrt(xd * xd + yd * yd ); - } -}; - -})( - window.Engine, - window.Vector -); diff --git a/website/source/assets/javascripts/app/_Engine.Point.js b/website/source/assets/javascripts/app/_Engine.Point.js deleted file mode 100644 index 4d53eb265..000000000 --- a/website/source/assets/javascripts/app/_Engine.Point.js +++ /dev/null @@ -1,118 +0,0 @@ -(function( - Engine, - Vector -){ 'use strict'; - -Engine.Point = function(id, x, y, shapeSize){ - this.id = id; - - this.shapeSize = shapeSize; - this.ref = new Vector(x, y); - - this.pos = new Vector( - x * shapeSize.x, - y * shapeSize.y - ); - - this.target = this.pos.clone(); - this.pos.x = shapeSize.x / 2; - this.pos.y = shapeSize.y / 2; - this.accel = Vector.coerce(this.accel); - this.vel = Vector.coerce(this.vel); - - this.stiffness = Engine.getRandomFloat(150, 600); - this.friction = Engine.getRandomFloat(12, 18); -}; - -Engine.Point.prototype = { - - radius: 1, - - stiffness : 200, - friction : 13, - threshold : 0.03, - - pos: { - x: 0, - y: 0 - }, - - accel: { - x: 0, - y: 0 - }, - - vel : { - x: 0, - y: 0 - }, - - target: { - x: 0, - y: 0 - }, - - resize: function(){ - this.target.x = this.pos.x = this.ref.x * this.shapeSize.x; - this.target.y = this.pos.y = this.ref.y * this.shapeSize.y; - }, - - updateBreathingPhysics: function(){ - this.stiffness = Engine.getRandomFloat(2, 4); - this.friction = Engine.getRandomFloat(1, 2); - }, - - updateTarget: function(newSize){ - var diff; - - this.target.x = this.ref.x * newSize.x; - this.target.y = this.ref.y * newSize.y; - - diff = Vector.sub(newSize, this.shapeSize).div(2); - - this.target.sub(diff); - - this.target.add({ - x: Engine.getRandomFloat(-3, 3), - y: Engine.getRandomFloat(-3, 3) - }); - }, - - update: function(engine){ - var newAccel; - - newAccel = Vector.sub(this.target, this.pos) - .mult(this.stiffness) - .sub(Vector.mult(this.vel, this.friction)); - - this.accel.set(newAccel); - - this.vel.add(Vector.mult(this.accel, engine.tick)); - - this.pos.add( - Vector.mult(this.vel, engine.tick) - ); - - newAccel = null; - - return this; - }, - - draw: function(ctx, scale){ - ctx.beginPath(); - ctx.arc( - this.pos.x * scale, - this.pos.y * scale, - this.radius * scale, - 0, - Math.PI * 2, - false - ); - ctx.fillStyle = '#ffffff'; - ctx.fill(); - return this; - } - -}; - -})(window.Engine, window.Vector); diff --git a/website/source/assets/javascripts/app/_Engine.Polygon.Puller.js b/website/source/assets/javascripts/app/_Engine.Polygon.Puller.js deleted file mode 100644 index 3ad4227b7..000000000 --- a/website/source/assets/javascripts/app/_Engine.Polygon.Puller.js +++ /dev/null @@ -1,29 +0,0 @@ -(function( - Engine, - Vector -){ - -Engine.Polygon.Puller = function(a, b, c, color, simple){ - this.a = a; - this.b = b; - this.c = c; - - this.strokeStyle = '#ffffff'; -}; - -Engine.Polygon.Puller.prototype = { - - checkChasing: function(){ - if ( - this.a._chasing === true && - this.b._chasing === true && - this.c._chasing === true - ) { - return true; - } - return false; - } - -}; - -})(window.Engine, window.Vector); diff --git a/website/source/assets/javascripts/app/_Engine.Polygon.js b/website/source/assets/javascripts/app/_Engine.Polygon.js deleted file mode 100644 index 74e80a96d..000000000 --- a/website/source/assets/javascripts/app/_Engine.Polygon.js +++ /dev/null @@ -1,80 +0,0 @@ -(function( - Engine, - Vector -){ - -Engine.Polygon = function(a, b, c, color, strokeColor){ - this.a = a; - this.b = b; - this.c = c; - - this.color = Engine.clone(color); - this.strokeColor = strokeColor ? Engine.clone(strokeColor) : Engine.clone(color); - - if (strokeColor) { - this.strokeColor = Engine.clone(strokeColor); - } else { - this.strokeColor = Engine.clone(color); - } - - this.strokeWidth = 0.25; - this.maxStrokeS = this.strokeColor.s; - this.maxStrokeL = this.strokeColor.l; - this.maxColorL = this.color.l; - - this.strokeColor.s = 0; - this.strokeColor.l = 100; - this.color.l = 0; - - this.fillStyle = this.hslaTemplate.substitute(this.color); - this.strokeStyle = this.hslaTemplate.substitute(this.strokeColor); -}; - -Engine.Polygon.prototype = { - - rgbaTemplate: 'rgba({r},{g},{b},{a})', - hslaTemplate: 'hsla({h},{s}%,{l}%,{a})', - - hueShiftSpeed: 20, - duration: 2, - delay: 0, - start: 0, - - // Determine color fill? - update: function(engine){ - var delta; - - if (this.simple) { - return; - } - - this.start += engine.tick; - - delta = this.start; - - if ( - delta > this.delay && - delta < this.delay + this.duration + 1 && - this.color.l < this.maxColorL - ) { - this.color.l = this.maxColorL * (delta - this.delay) / this.duration; - - this.strokeColor.s = this.maxStrokeS * (delta - this.delay) / this.duration; - this.strokeColor.l = (this.maxStrokeL - 100) * (delta - this.delay) / this.duration + 100; - - this.strokeWidth = 1.5 * (delta - this.delay) / this.duration + 0.25; - - if (this.color.l > this.maxColorL) { - this.color.l = this.maxColorL; - this.strokeColor.l = this.maxStrokeL; - this.strokeWidth = 1.5; - } - - this.strokeStyle = this.hslaTemplate.substitute(this.strokeColor); - this.fillStyle = this.hslaTemplate.substitute(this.color); - } - } - -}; - -})(window.Engine, window.Vector); diff --git a/website/source/assets/javascripts/app/_Engine.Shape.Puller.js b/website/source/assets/javascripts/app/_Engine.Shape.Puller.js deleted file mode 100644 index 27f7fd7d5..000000000 --- a/website/source/assets/javascripts/app/_Engine.Shape.Puller.js +++ /dev/null @@ -1,179 +0,0 @@ -(function( - Engine, - Point, - Polygon, - Vector -){ - -Engine.Shape.Puller = function(width, height, json){ - var i, ref, point, poly; - - this.pos = new Vector(0, 0); - this.size = new Vector(width, height); - this.heightRatio = json.data.width / json.data.height; - this.widthRatio = json.data.ar; - - this.resize(width, height, true); - - ref = {}; - this.points = []; - this.polygons = []; - - for (i = 0; i < json.points.length; i++) { - point = new Point( - json.points[i].id, - json.points[i].x, - json.points[i].y, - this.size - ); - ref[point.id] = point; - this.points.push(point); - } - - for (i = 0; i < json.polygons.length; i++) { - poly = json.polygons[i]; - this.polygons.push(new Polygon( - ref[poly.points[0]], - ref[poly.points[1]], - ref[poly.points[2]], - poly.color - )); - this.polygons[this.polygons.length - 1].noFill = true; - } - - this.ref = undefined; -}; - -Engine.Shape.Puller.prototype = { - - alpha: 0, - - sizeOffset: 100, - - resize: function(width, height, sizeOnly){ - var len, p, newWidth, newHeight; - - newHeight = height + this.sizeOffset; - newWidth = this.size.y * this.heightRatio; - - if (newWidth < width) { - newWidth = width + this.sizeOffset; - newHeight = newWidth * this.widthRatio; - } - - this.size.y = newHeight; - this.size.x = newWidth; - - this.pos.x = -(newWidth / 2); - this.pos.y = -(newHeight / 2); - - if (sizeOnly) { - return this; - } - - for (p = 0, len = this.points.length; p < len; p++) { - this.points[p].resize(); - } - }, - - update: function(engine){ - var p; - - for (p = 0; p < this.points.length; p++) { - this.points[p].update(engine); - } - - if (this.alpha < 1) { - this.alpha = Math.min(this.alpha + 2 * engine.tick, 1); - } - - return this; - }, - - draw: function(ctx, scale, engine){ - var p, poly; - - ctx.translate( - this.pos.x * scale >> 0, - this.pos.y * scale >> 0 - ); - - if (this.alpha < 1) { - ctx.globalAlpha = this.alpha; - } - - ctx.beginPath(); - for (p = 0; p < this.polygons.length; p++) { - poly = this.polygons[p]; - ctx.moveTo( - poly.a.pos.x * scale >> 0, - poly.a.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.b.pos.x * scale >> 0, - poly.b.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.c.pos.x * scale >> 0, - poly.c.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.a.pos.x * scale >> 0, - poly.a.pos.y * scale >> 0 - ); - } - ctx.closePath(); - ctx.lineWidth = 0.4 * scale; - ctx.strokeStyle = 'rgba(108,0,243,0.15)'; - ctx.stroke(); - - if (this.alpha < 1) { - ctx.globalAlpha = 1; - } - - for (p = 0; p < this.points.length; p++) { - this.points[p].draw(ctx, scale); - } - - ctx.beginPath(); - for (p = 0; p < this.polygons.length; p++) { - if (this.polygons[p].checkChasing()) { - poly = this.polygons[p]; - ctx.moveTo( - poly.a.pos.x * scale >> 0, - poly.a.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.b.pos.x * scale >> 0, - poly.b.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.c.pos.x * scale >> 0, - poly.c.pos.y * scale >> 0 - ); - ctx.lineTo( - poly.a.pos.x * scale >> 0, - poly.a.pos.y * scale >> 0 - ); - } - } - ctx.closePath(); - ctx.fillStyle = 'rgba(108,0,243,0.05)'; - ctx.fill(); - - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.translate( - engine.width / 2 * engine.scale >> 0, - engine.height / 2 * engine.scale >> 0 - ); - return this; - } - -}; - -})( - window.Engine, - window.Engine.Point.Puller, - window.Engine.Polygon.Puller, - window.Vector -); diff --git a/website/source/assets/javascripts/app/_Engine.Shape.js b/website/source/assets/javascripts/app/_Engine.Shape.js deleted file mode 100644 index 97be30c83..000000000 --- a/website/source/assets/javascripts/app/_Engine.Shape.js +++ /dev/null @@ -1,159 +0,0 @@ -(function( - Engine, - Point, - Polygon, - Vector -){ - -Engine.Shape = function(x, y, width, height, points, polygons){ - var i, ref, point, poly; - - this.pos = new Vector(x, y); - this.size = new Vector(width, height); - this.sizeRef = this.size.clone(); - - ref = {}; - this.points = []; - this.polygons = []; - - for (i = 0; i < points.length; i++) { - point = new Point( - points[i].id, - points[i].x, - points[i].y, - this.size - ); - ref[point.id] = point; - this.points.push(point); - } - - for (i = 0; i < polygons.length; i++) { - poly = polygons[i]; - this.polygons.push(new Polygon( - ref[poly.points[0]], - ref[poly.points[1]], - ref[poly.points[2]], - poly.color, - poly.stroke - )); - } -}; - -Engine.Shape.prototype = { - - breathing: false, - - breath: 0, - breathLength: 1, - breatheIn: false, - - resize: function(newSize, offset){ - var len, p; - - this.size.x = newSize; - this.size.y = newSize; - this.sizeRef.x = newSize; - this.sizeRef.y = newSize; - - this.pos.x = -(newSize / 2); - this.pos.y = -(newSize / 2 + offset); - - for (p = 0, len = this.points.length; p < len; p++) { - this.points[p].resize(); - } - }, - - startBreathing: function(){ - var p; - - this.breathing = true; - this.breath = this.breathLength; - - for (p = 0; p < this.points.length; p++) { - this.points[p].updateBreathingPhysics(); - } - }, - - breathe: function(tick){ - var p, scale, newSize; - - this.breath += tick; - - if (this.breath < this.breathLength) { - return; - } - - scale = 1; - - newSize = Vector.mult(this.sizeRef, scale); - - for (p = 0; p < this.points.length; p++) { - this.points[p].updateTarget(newSize); - } - - this.breath = 0; - }, - - update: function(engine){ - var p; - - if (this.breathing === true) { - this.breathe(engine.tick); - } - - for (p = 0; p < this.points.length; p++) { - this.points[p].update(engine); - } - - for (p = 0; p < this.polygons.length; p++) { - this.polygons[p].update(engine); - } - - return this; - }, - - draw: function(ctx, scale, engine){ - var p, poly; - - ctx.translate( - this.pos.x * scale >> 0, - this.pos.y * scale >> 0 - ); - for (p = 0; p < this.polygons.length; p++) { - poly = this.polygons[p]; - ctx.beginPath(); - ctx.moveTo( - poly.a.pos.x * scale, - poly.a.pos.y * scale - ); - ctx.lineTo( - poly.b.pos.x * scale, - poly.b.pos.y * scale - ); - ctx.lineTo( - poly.c.pos.x * scale, - poly.c.pos.y * scale - ); - ctx.closePath(); - ctx.fillStyle = poly.fillStyle; - ctx.fill(); - ctx.lineWidth = poly.strokeWidth * scale; - ctx.strokeStyle = poly.strokeStyle; - ctx.stroke(); - } - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.translate( - engine.width / 2 * engine.scale >> 0, - engine.height / 2 * engine.scale >> 0 - ); - return this; - } - -}; - -})( - window.Engine, - window.Engine.Point, - window.Engine.Polygon, - window.Vector -); diff --git a/website/source/assets/javascripts/app/_Engine.Typewriter.js b/website/source/assets/javascripts/app/_Engine.Typewriter.js deleted file mode 100644 index 61762c41c..000000000 --- a/website/source/assets/javascripts/app/_Engine.Typewriter.js +++ /dev/null @@ -1,71 +0,0 @@ -/* jshint unused:false */ -/* global console */ -(function(Engine){ 'use strict'; - -Engine.Typewriter = function(element){ - this.element = element; - this.content = this.element.textContent.split(''); - this.element.innerHTML = ''; - this.element.style.visibility = 'visible'; -}; - -Engine.Typewriter.prototype = { - - running: false, - - letterInterval : 0.02, - spaceInterval : 0.4, - - charCount: -1, - waitSpace: false, - - toDraw: '', - - start: function(){ - if (!this.content.length) { - return this; - } - - this._last = this.letterInterval; - this.running = true; - }, - - update: function(engine){ - var newChar; - - if (!this.running) { - return this; - } - - this._last += engine.tick; - - if (this.waitSpace && this._last < this.spaceInterval) { - return this; - } - - if (!this.waitSpace && this._last < this.letterInterval){ - return this; - } - - this._last = 0; - newChar = this.content.shift(); - this.toDraw += newChar; - - if (newChar === ',') { - this.waitSpace = true; - } else { - this.waitSpace = false; - } - - this.element.innerHTML = this.toDraw + '_'; - - if (!this.content.length) { - this.running = false; - } - - return this; - } - -}; - -})(window.Engine); diff --git a/website/source/assets/javascripts/app/_Engine.js b/website/source/assets/javascripts/app/_Engine.js deleted file mode 100644 index e89d61074..000000000 --- a/website/source/assets/javascripts/app/_Engine.js +++ /dev/null @@ -1,388 +0,0 @@ -(function( - Base, - Vector, - Logo, - Grid, - Chainable -){ - -var sqrt, pow, Engine; - -if (!window.requestAnimationFrame) { - window.requestAnimationFrame = (function(){ - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - function( callback ){ - window.setTimeout(callback, 1000 / 60); - }; - })(); -} - -sqrt = Math.sqrt; -pow = Math.pow; - -Engine = Base.extend({ - - scale: window.devicePixelRatio || 1, - // scale:1, - - shapes : [], - particles : [], - particlesA : [], - particlesB : [], - - _deferredParticles: [], - - ticks: [], - - starGeneratorRate: 600, - - mouse: { - x: -9999, - y: -9999 - }, - - constructor: function(canvas, background, tagLine){ - this.canvas = canvas; - this.background = background; - this.tagLine = tagLine; - - if (!this.canvas.getContext) { - return null; - } - - this.context = this.canvas.getContext('2d'); - - this.setupEvents(); - this.setupStarfield(); - this.setupTessellation(); - this.setupMisc(); - - this.startEngine(); - }, - - startEngine: function(){ - var parent = this.canvas.parentNode; - - this.background.className += ' show'; - this.canvas.style.opacity = 1; - - // We have to pass the engine into Chainable to - // enable the timers to properly attach to the - // run/render loop - new Chainable(this) - .wait(1000) - .then(function(){ - this.starGeneratorRate = 200; - }, this) - .wait(500) - .then(function(){ - parent.className += ' state-one'; - }) - .wait(150) - .then(function(){ - parent.className += ' state-two'; - }) - .wait(150) - .then(function(){ - parent.className += ' state-three'; - }) - .wait(500) - .then(function(){ - parent.className += ' state-four'; - }) - .wait(100) - .then(function(){ - this.showShapes = true; - }, this) - .wait(1000) - .then(function(){ - this.logo.startBreathing(); - this.showGrid = true; - }, this) - .wait(1000) - .then(function(){ - this.typewriter.start(); - }, this); - - this.render(); - }, - - - setupMisc: function(){ - this.last = Date.now() / 1000; - this.render = this.render.bind(this); - - this.typewriter = new Engine.Typewriter(this.tagLine); - }, - - setupEvents: function(){ - this.resize = this.resize.bind(this); - this.resize(); - window.addEventListener('resize', this.resize, false); - - this._handleScroll = this._handleScroll.bind(this); - this._handleScroll(); - window.addEventListener('scroll', this._handleScroll, false); - - this._handleMouseCoords = this._handleMouseCoords.bind(this); - window.addEventListener('mousemove', this._handleMouseCoords, false); - }, - - setupStarfield: function(){ - this.particles = []; - // this.generateParticles(50, true); - this.generateParticles(400); - }, - - setupTessellation: function(canvas){ - var size, offset; - this.shapes = []; - if (window.innerWidth < 570) { - size = 300; - offset = 0; - } else { - size = 360; - offset = 40; - } - - this.logo = new Engine.Shape( - -(size / 2), - -(size / 2 + offset), - size, - size, - Logo.points, - Logo.polygons - ); - - this.grid = new Engine.Shape.Puller(this.width, this.height, Grid); - }, - - - getAverageTickTime: function(){ - var sum = 0, s; - - for (s = 0; s < this.ticks.length; s++) { - sum += this.ticks[s]; - } - - window.console.log('Average Tick Time:', sum / this.ticks.length); - }, - - getLongestTick: function(){ - var max = 0, index, s; - - for (s = 0; s < this.ticks.length; s++) { - if (this.ticks[s] > max) { - max = this.ticks[s]; - index = s; - } - } - - window.console.log('Max tick was:', max, 'at index:', index); - }, - - render: function(){ - var scale = this.scale, p, particle, index; - - if (this.paused) { - return; - } - - if (this.scrollY > this.height) { - window.requestAnimationFrame(this.render); - return; - } - - this.context.clearRect( - -(this.width / 2) * scale, - -(this.height / 2) * scale, - this.width * scale, - this.height * scale - ); - - this.now = Date.now() / 1000; - this.tick = Math.min(this.now - this.last, 0.017); - - // We must attach the chainable timer to the engine - // run/render loop or else things can get pretty - // out of wack - if (this.updateChainTimer) { - this.updateChainTimer(this.tick); - } - - // Update all particles... may need to be optimized - for (p = 0; p < this.particles.length; p++) { - this.particles[p].update(this); - } - - // Batch render particles based on color - // to prevent unneeded context state change - this.context.fillStyle = '#8750c2'; - for (p = 0; p < this.particlesA.length; p++) { - particle = this.particlesA[p]; - - if (particle.radius < 0.25) { - continue; - } - this.context.fillRect( - particle.pos.x * scale >> 0, - particle.pos.y * scale >> 0, - particle.radius * scale, - particle.radius * scale - ); - } - - this.context.fillStyle = '#b976ff'; - for (p = 0; p < this.particlesB.length; p++) { - particle = this.particlesB[p]; - - if (particle.radius < 0.25) { - continue; - } - this.context.fillRect( - particle.pos.x * scale >> 0, - particle.pos.y * scale >> 0, - particle.radius * scale, - particle.radius * scale - ); - } - - this.particlesA.length = 0; - this.particlesB.length = 0; - - // Remove destroyed particles - for (p = 0; p < this._deferredParticles.length; p++) { - index = this.particles.indexOf(this._deferredParticles.pop()); - if (index >= 0) { - this.particles.splice(index, 1); - } - } - - if (this.showGrid) { - this.grid - .update(this) - .draw(this.context, scale, this); - } - - if (this.showShapes) { - this.logo - .update(this) - .draw(this.context, scale, this); - } - - this.typewriter.update(this); - - this.last = this.now; - - this.generateParticles(this.starGeneratorRate * this.tick >> 0); - - window.requestAnimationFrame(this.render); - }, - - generateParticles: function(num, fixed){ - var p; - - for (p = 0; p < num; p++) { - if (fixed) { - this.particles.push(new Engine.Particle.Fixed(this.width, this.height)); - } else { - this.particles.push(new Engine.Particle(this.width, this.height)); - } - } - }, - - resize: function(){ - var scale = this.scale, - size, offset; - - if (window.innerWidth < 570) { - this.height = 560; - } else { - this.height = 700; - } - - this.width = window.innerWidth; - - this.canvas.width = this.width * scale; - this.canvas.height = this.height * scale; - - this.context.translate( - this.width / 2 * scale >> 0, - this.height / 2 * scale >> 0 - ); - this.context.lineJoin = 'bevel'; - - if (this.grid) { - this.grid.resize(this.width, this.height); - } - - if (this.logo) { - if (this.height === 560) { - size = 300; - offset = 0; - } else { - size = 360; - offset = 40; - } - this.logo.resize(size, offset); - } - }, - - _handleMouseCoords: function(event){ - this.mouse.x = event.pageX; - this.mouse.y = event.pageY; - }, - - _handleScroll: function(){ - this.scrollY = window.scrollY; - }, - - pause: function(){ - this.paused = true; - }, - - resume: function(){ - if (!this.paused) { - return; - } - this.paused = false; - this.render(); - }, - - getSnapshot: function(){ - window.open(this.canvas.toDataURL('image/png')); - } - -}); - -Engine.map = function(val, istart, istop, ostart, ostop) { - return ostart + (ostop - ostart) * ((val - istart) / (istop - istart)); -}; - -Engine.getRandomFloat = function(min, max) { - return Math.random() * (max - min) + min; -}; - -Engine.getRandomInt = function(min, max) { - return Math.floor(Math.random() * (max - min + 1) + min); -}; - -Engine.clone = function(ref) { - var clone = {}, key; - for (key in ref) { - clone[key] = ref[key]; - } - return clone; -}; - -window.Engine = Engine; - -})( - window.Base, - window.Vector, - window.Logo, - window.Grid, - window.Chainable -); diff --git a/website/source/assets/javascripts/app/_Grid.js b/website/source/assets/javascripts/app/_Grid.js deleted file mode 100644 index 9ea5055ec..000000000 --- a/website/source/assets/javascripts/app/_Grid.js +++ /dev/null @@ -1,2384 +0,0 @@ -var Grid = { - "data": { - "width": 1572, - "height": 979, - "ar": 0.6227735368956743 - }, - "points": [ - { - "id": "point-0", - "x": 0.01743002544529262, - "y": 0.045658835546476005 - }, - { - "id": "point-1", - "x": -0.0001272264631043257, - "y": 0.7701736465781408 - }, - { - "id": "point-2", - "x": 0.012468193384223917, - "y": 0.32665985699693567 - }, - { - "id": "point-7", - "x": 0.04052162849872774, - "y": 0.12277834525025537 - }, - { - "id": "point-12", - "x": 0.13568702290076337, - "y": 0.030847803881511746 - }, - { - "id": "point-17", - "x": 0.14465648854961832, - "y": 0.16772216547497446 - }, - { - "id": "point-22", - "x": 0.20184478371501274, - "y": 0.05536261491317671 - }, - { - "id": "point-27", - "x": 0.37099236641221384, - "y": 0.02696629213483146 - }, - { - "id": "point-32", - "x": 0.49357506361323156, - "y": 0.00020429009193054137 - }, - { - "id": "point-37", - "x": 0.1993002544529262, - "y": 0.16281920326864147 - }, - { - "id": "point-42", - "x": 0.30337150127226464, - "y": 0.05965270684371808 - }, - { - "id": "point-52", - "x": 0.32461832061068707, - "y": 0.1689479060265577 - }, - { - "id": "point-62", - "x": 0.4028625954198473, - "y": 0.12502553626149132 - }, - { - "id": "point-72", - "x": 0.5604325699745547, - "y": 0.13003064351378957 - }, - { - "id": "point-77", - "x": 0.5724554707379135, - "y": 0.01491317671092952 - }, - { - "id": "point-82", - "x": 0.8836513994910941, - "y": 0.05372829417773237 - }, - { - "id": "point-87", - "x": 0.9759541984732825, - "y": 0.061184882533197135 - }, - { - "id": "point-92", - "x": 0.7122137404580152, - "y": 0.07405515832482125 - }, - { - "id": "point-102", - "x": 0.6561704834605598, - "y": 0.218488253319714 - }, - { - "id": "point-107", - "x": 0.7784351145038169, - "y": 0.1319713993871297 - }, - { - "id": "point-112", - "x": 0.7912213740458014, - "y": 0.08672114402451482 - }, - { - "id": "point-122", - "x": 0.8616412213740458, - "y": 0.12941777323799797 - }, - { - "id": "point-132", - "x": 0.9780534351145039, - "y": 0.17242083758937693 - }, - { - "id": "point-142", - "x": 0.9898854961832061, - "y": 0.30960163432073545 - }, - { - "id": "point-152", - "x": 0.12888040712468193, - "y": 0.36149131767109294 - }, - { - "id": "point-162", - "x": 0.21743002544529266, - "y": 0.39662921348314606 - }, - { - "id": "point-167", - "x": 0.3361959287531807, - "y": 0.2868232890704801 - }, - { - "id": "point-182", - "x": 0.37220101781170484, - "y": 0.3344228804902961 - }, - { - "id": "point-187", - "x": 0.4620865139949109, - "y": 0.32533197139938713 - }, - { - "id": "point-192", - "x": 0.5159033078880407, - "y": 0.24106230847803883 - }, - { - "id": "point-202", - "x": 0.5856234096692112, - "y": 0.3547497446373851 - }, - { - "id": "point-217", - "x": 0.7061704834605598, - "y": 0.30643513789581206 - }, - { - "id": "point-227", - "x": 0.7717557251908397, - "y": 0.35556690500510724 - }, - { - "id": "point-232", - "x": 0.8581424936386769, - "y": 0.2822267620020429 - }, - { - "id": "point-252", - "x": 0.009287531806615776, - "y": 0.47477017364657814 - }, - { - "id": "point-257", - "x": 0.10756997455470736, - "y": 0.4454545454545455 - }, - { - "id": "point-267", - "x": 0.17767175572519084, - "y": 0.5234933605720122 - }, - { - "id": "point-277", - "x": 0.2962468193384224, - "y": 0.5465781409601634 - }, - { - "id": "point-292", - "x": 0.4138676844783716, - "y": 0.4349336057201226 - }, - { - "id": "point-302", - "x": 0.5194020356234097, - "y": 0.5248212461695607 - }, - { - "id": "point-307", - "x": 0.5548982188295165, - "y": 0.49836567926455566 - }, - { - "id": "point-317", - "x": 0.6503816793893129, - "y": 0.5194075587334014 - }, - { - "id": "point-327", - "x": 0.7473282442748093, - "y": 0.4626149131767109 - }, - { - "id": "point-337", - "x": 0.8691475826972009, - "y": 0.49458631256384067 - }, - { - "id": "point-352", - "x": 0.9832061068702289, - "y": 0.4917262512768131 - }, - { - "id": "point-357", - "x": 0.9990458015267175, - "y": 0.7504596527068438 - }, - { - "id": "point-362", - "x": 0.05012722646310432, - "y": 0.6356486210418795 - }, - { - "id": "point-372", - "x": 0.14440203562340967, - "y": 0.6027579162410623 - }, - { - "id": "point-382", - "x": 0.17550890585241732, - "y": 0.6821246169560776 - }, - { - "id": "point-392", - "x": 0.3370229007633587, - "y": 0.6620020429009194 - }, - { - "id": "point-397", - "x": 0.38403307888040716, - "y": 0.6074565883554648 - }, - { - "id": "point-407", - "x": 0.49141221374045796, - "y": 0.609090909090909 - }, - { - "id": "point-417", - "x": 0.6092239185750636, - "y": 0.6490296220633298 - }, - { - "id": "point-432", - "x": 0.6994910941475826, - "y": 0.6377936670071501 - }, - { - "id": "point-442", - "x": 0.8021628498727735, - "y": 0.6412665985699693 - }, - { - "id": "point-452", - "x": 0.8450381679389314, - "y": 0.6878447395301328 - }, - { - "id": "point-457", - "x": 0.9385496183206108, - "y": 0.5991828396322778 - }, - { - "id": "point-472", - "x": 0.08269720101781171, - "y": 0.8129724208375894 - }, - { - "id": "point-487", - "x": 0.19293893129770992, - "y": 0.7488253319713994 - }, - { - "id": "point-497", - "x": 0.3399491094147582, - "y": 0.7432073544433095 - }, - { - "id": "point-507", - "x": 0.4349872773536895, - "y": 0.8191011235955056 - }, - { - "id": "point-517", - "x": 0.4825699745547074, - "y": 0.8216547497446374 - }, - { - "id": "point-527", - "x": 0.6143129770992367, - "y": 0.8338100102145046 - }, - { - "id": "point-532", - "x": 0.6626590330788804, - "y": 0.7674157303370785 - }, - { - "id": "point-542", - "x": 0.80470737913486, - "y": 0.7797752808988764 - }, - { - "id": "point-557", - "x": 0.858587786259542, - "y": 0.780388151174668 - }, - { - "id": "point-571", - "x": 0.04058524173027989, - "y": 0.9923391215526047 - }, - { - "id": "point-577", - "x": 0.10038167938931299, - "y": 0.9534218590398367 - }, - { - "id": "point-587", - "x": 0.21615776081424937, - "y": 0.9832482124616956 - }, - { - "id": "point-592", - "x": 0.31653944020356234, - "y": 0.8937691521961184 - }, - { - "id": "point-602", - "x": 0.3648218829516539, - "y": 0.9393258426966292 - }, - { - "id": "point-612", - "x": 0.4798346055979643, - "y": 0.9085801838610827 - }, - { - "id": "point-627", - "x": 0.6159669211195928, - "y": 0.9221654749744637 - }, - { - "id": "point-632", - "x": 0.7001272264631042, - "y": 0.9664964249233913 - }, - { - "id": "point-647", - "x": 0.7608778625954199, - "y": 0.9989785495403473 - }, - { - "id": "point-652", - "x": 0.8911577608142494, - "y": 0.9557711950970379 - }, - { - "id": "point-667", - "x": 0.9989821882951655, - "y": 0.9853932584269665 - } - ], - "polygons": [ - { - "id": "poly-0", - "color": { - "h": 269.25373134328356, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-0", - "point-1", - "point-2" - ] - }, - { - "id": "poly-1", - "color": { - "h": 277.1428571428571, - "s": 100, - "l": 67.05882352941177, - "a": 1 - }, - "points": [ - "point-0", - "point-2", - "point-7" - ] - }, - { - "id": "poly-2", - "color": { - "h": 277.1428571428571, - "s": 100, - "l": 67.05882352941177, - "a": 1 - }, - "points": [ - "point-0", - "point-7", - "point-12" - ] - }, - { - "id": "poly-3", - "color": { - "h": 275.31428571428575, - "s": 100, - "l": 65.68627450980392, - "a": 1 - }, - "points": [ - "point-12", - "point-7", - "point-17" - ] - }, - { - "id": "poly-4", - "color": { - "h": 276.26373626373623, - "s": 100, - "l": 64.31372549019608, - "a": 1 - }, - "points": [ - "point-12", - "point-17", - "point-22" - ] - }, - { - "id": "poly-5", - "color": { - "h": 272.23404255319144, - "s": 100, - "l": 63.13725490196078, - "a": 1 - }, - "points": [ - "point-12", - "point-22", - "point-27" - ] - }, - { - "id": "poly-6", - "color": { - "h": 268.2692307692307, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-12", - "point-27", - "point-32" - ] - }, - { - "id": "poly-7", - "color": { - "h": 274.46808510638294, - "s": 100, - "l": 63.13725490196078, - "a": 1 - }, - "points": [ - "point-22", - "point-17", - "point-37" - ] - }, - { - "id": "poly-8", - "color": { - "h": 272.23404255319144, - "s": 100, - "l": 63.13725490196078, - "a": 1 - }, - "points": [ - "point-22", - "point-37", - "point-42" - ] - }, - { - "id": "poly-9", - "color": { - "h": 269.25373134328356, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-22", - "point-42", - "point-27" - ] - }, - { - "id": "poly-10", - "color": { - "h": 269.25373134328356, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-42", - "point-37", - "point-52" - ] - }, - { - "id": "poly-11", - "color": { - "h": 268.2692307692307, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-42", - "point-52", - "point-27" - ] - }, - { - "id": "poly-12", - "color": { - "h": 265.96153846153845, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-27", - "point-52", - "point-62" - ] - }, - { - "id": "poly-13", - "color": { - "h": 265.88235294117646, - "s": 86.4406779661017, - "l": 53.72549019607843, - "a": 1 - }, - "points": [ - "point-27", - "point-62", - "point-32" - ] - }, - { - "id": "poly-14", - "color": { - "h": 265.48387096774195, - "s": 76.22950819672131, - "l": 47.84313725490196, - "a": 1 - }, - "points": [ - "point-32", - "point-62", - "point-72" - ] - }, - { - "id": "poly-15", - "color": { - "h": 265.1933701657459, - "s": 83.41013824884793, - "l": 42.549019607843135, - "a": 1 - }, - "points": [ - "point-32", - "point-72", - "point-77" - ] - }, - { - "id": "poly-16", - "color": { - "h": 264.45859872611464, - "s": 96.31901840490798, - "l": 31.960784313725487, - "a": 1 - }, - "points": [ - "point-32", - "point-77", - "point-82" - ] - }, - { - "id": "poly-17", - "color": { - "h": 261.69230769230774, - "s": 100, - "l": 25.49019607843137, - "a": 1 - }, - "points": [ - "point-32", - "point-82", - "point-87" - ] - }, - { - "id": "poly-18", - "color": { - "h": 263.3532934131737, - "s": 91.2568306010929, - "l": 35.88235294117647, - "a": 1 - }, - "points": [ - "point-77", - "point-72", - "point-92" - ] - }, - { - "id": "poly-19", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-77", - "point-92", - "point-82" - ] - }, - { - "id": "poly-20", - "color": { - "h": 264.45859872611464, - "s": 96.31901840490798, - "l": 31.960784313725487, - "a": 1 - }, - "points": [ - "point-92", - "point-72", - "point-102" - ] - }, - { - "id": "poly-21", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-92", - "point-102", - "point-107" - ] - }, - { - "id": "poly-22", - "color": { - "h": 261.69230769230774, - "s": 100, - "l": 25.49019607843137, - "a": 1 - }, - "points": [ - "point-92", - "point-107", - "point-112" - ] - }, - { - "id": "poly-23", - "color": { - "h": 260, - "s": 100, - "l": 24.11764705882353, - "a": 1 - }, - "points": [ - "point-92", - "point-112", - "point-82" - ] - }, - { - "id": "poly-24", - "color": { - "h": 260, - "s": 100, - "l": 24.11764705882353, - "a": 1 - }, - "points": [ - "point-112", - "point-107", - "point-122" - ] - }, - { - "id": "poly-25", - "color": { - "h": 260, - "s": 100, - "l": 24.11764705882353, - "a": 1 - }, - "points": [ - "point-112", - "point-122", - "point-82" - ] - }, - { - "id": "poly-26", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-82", - "point-122", - "point-132" - ] - }, - { - "id": "poly-27", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-82", - "point-132", - "point-87" - ] - }, - { - "id": "poly-28", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-87", - "point-132", - "point-142" - ] - }, - { - "id": "poly-29", - "color": { - "h": 275.31428571428575, - "s": 100, - "l": 65.68627450980392, - "a": 1 - }, - "points": [ - "point-7", - "point-2", - "point-17" - ] - }, - { - "id": "poly-30", - "color": { - "h": 274.46808510638294, - "s": 100, - "l": 63.13725490196078, - "a": 1 - }, - "points": [ - "point-17", - "point-2", - "point-152" - ] - }, - { - "id": "poly-31", - "color": { - "h": 272.23404255319144, - "s": 100, - "l": 63.13725490196078, - "a": 1 - }, - "points": [ - "point-17", - "point-152", - "point-37" - ] - }, - { - "id": "poly-32", - "color": { - "h": 269.25373134328356, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-37", - "point-152", - "point-162" - ] - }, - { - "id": "poly-33", - "color": { - "h": 268.2692307692307, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-37", - "point-162", - "point-167" - ] - }, - { - "id": "poly-34", - "color": { - "h": 268.2692307692307, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-37", - "point-167", - "point-52" - ] - }, - { - "id": "poly-35", - "color": { - "h": 265.92233009708735, - "s": 92.7927927927928, - "l": 56.470588235294116, - "a": 1 - }, - "points": [ - "point-52", - "point-167", - "point-62" - ] - }, - { - "id": "poly-36", - "color": { - "h": 265.88235294117646, - "s": 86.4406779661017, - "l": 53.72549019607843, - "a": 1 - }, - "points": [ - "point-62", - "point-167", - "point-182" - ] - }, - { - "id": "poly-37", - "color": { - "h": 265.48387096774195, - "s": 76.22950819672131, - "l": 47.84313725490196, - "a": 1 - }, - "points": [ - "point-62", - "point-182", - "point-187" - ] - }, - { - "id": "poly-38", - "color": { - "h": 265.24590163934425, - "s": 79.22077922077922, - "l": 45.294117647058826, - "a": 1 - }, - "points": [ - "point-62", - "point-187", - "point-192" - ] - }, - { - "id": "poly-39", - "color": { - "h": 265.24590163934425, - "s": 79.22077922077922, - "l": 45.294117647058826, - "a": 1 - }, - "points": [ - "point-62", - "point-192", - "point-72" - ] - }, - { - "id": "poly-40", - "color": { - "h": 263.3532934131737, - "s": 91.2568306010929, - "l": 35.88235294117647, - "a": 1 - }, - "points": [ - "point-192", - "point-187", - "point-202" - ] - }, - { - "id": "poly-41", - "color": { - "h": 264.45859872611464, - "s": 96.31901840490798, - "l": 31.960784313725487, - "a": 1 - }, - "points": [ - "point-192", - "point-202", - "point-102" - ] - }, - { - "id": "poly-42", - "color": { - "h": 263.3532934131737, - "s": 91.2568306010929, - "l": 35.88235294117647, - "a": 1 - }, - "points": [ - "point-192", - "point-102", - "point-72" - ] - }, - { - "id": "poly-43", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-102", - "point-202", - "point-217" - ] - }, - { - "id": "poly-44", - "color": { - "h": 261.69230769230774, - "s": 100, - "l": 25.49019607843137, - "a": 1 - }, - "points": [ - "point-102", - "point-217", - "point-107" - ] - }, - { - "id": "poly-45", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-107", - "point-217", - "point-227" - ] - }, - { - "id": "poly-46", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-107", - "point-227", - "point-232" - ] - }, - { - "id": "poly-47", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-107", - "point-232", - "point-122" - ] - }, - { - "id": "poly-48", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-122", - "point-232", - "point-132" - ] - }, - { - "id": "poly-49", - "color": { - "h": 255.31914893617022, - "s": 100, - "l": 18.43137254901961, - "a": 1 - }, - "points": [ - "point-132", - "point-232", - "point-142" - ] - }, - { - "id": "poly-50", - "color": { - "h": 265.24590163934425, - "s": 79.22077922077922, - "l": 45.294117647058826, - "a": 1 - }, - "points": [ - "point-2", - "point-1", - "point-252" - ] - }, - { - "id": "poly-51", - "color": { - "h": 265.96153846153845, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-2", - "point-252", - "point-257" - ] - }, - { - "id": "poly-52", - "color": { - "h": 268.2692307692307, - "s": 100, - "l": 59.21568627450981, - "a": 1 - }, - "points": [ - "point-2", - "point-257", - "point-152" - ] - }, - { - "id": "poly-53", - "color": { - "h": 265.54455445544556, - "s": 80.8, - "l": 50.98039215686274, - "a": 1 - }, - "points": [ - "point-152", - "point-257", - "point-267" - ] - }, - { - "id": "poly-54", - "color": { - "h": 265.54455445544556, - "s": 80.8, - "l": 50.98039215686274, - "a": 1 - }, - "points": [ - "point-152", - "point-267", - "point-162" - ] - }, - { - "id": "poly-55", - "color": { - "h": 264.68571428571425, - "s": 91.62303664921467, - "l": 37.450980392156865, - "a": 1 - }, - "points": [ - "point-162", - "point-267", - "point-277" - ] - }, - { - "id": "poly-56", - "color": { - "h": 265.24590163934425, - "s": 79.22077922077922, - "l": 45.294117647058826, - "a": 1 - }, - "points": [ - "point-162", - "point-277", - "point-167" - ] - }, - { - "id": "poly-57", - "color": { - "h": 265.1933701657459, - "s": 83.41013824884793, - "l": 42.549019607843135, - "a": 1 - }, - "points": [ - "point-167", - "point-277", - "point-182" - ] - }, - { - "id": "poly-58", - "color": { - "h": 263.3532934131737, - "s": 91.2568306010929, - "l": 35.88235294117647, - "a": 1 - }, - "points": [ - "point-182", - "point-277", - "point-292" - ] - }, - { - "id": "poly-59", - "color": { - "h": 264.68571428571425, - "s": 91.62303664921467, - "l": 37.450980392156865, - "a": 1 - }, - "points": [ - "point-182", - "point-292", - "point-187" - ] - }, - { - "id": "poly-60", - "color": { - "h": 262.3448275862069, - "s": 100, - "l": 28.431372549019606, - "a": 1 - }, - "points": [ - "point-187", - "point-292", - "point-302" - ] - }, - { - "id": "poly-61", - "color": { - "h": 260, - "s": 100, - "l": 24.11764705882353, - "a": 1 - }, - "points": [ - "point-187", - "point-302", - "point-307" - ] - }, - { - "id": "poly-62", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-187", - "point-307", - "point-202" - ] - }, - { - "id": "poly-63", - "color": { - "h": 255.31914893617022, - "s": 100, - "l": 18.43137254901961, - "a": 1 - }, - "points": [ - "point-202", - "point-307", - "point-317" - ] - }, - { - "id": "poly-64", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-202", - "point-317", - "point-217" - ] - }, - { - "id": "poly-65", - "color": { - "h": 249.75, - "s": 100, - "l": 15.686274509803921, - "a": 1 - }, - "points": [ - "point-217", - "point-317", - "point-327" - ] - }, - { - "id": "poly-66", - "color": { - "h": 249.75, - "s": 100, - "l": 15.686274509803921, - "a": 1 - }, - "points": [ - "point-217", - "point-327", - "point-227" - ] - }, - { - "id": "poly-67", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-227", - "point-327", - "point-337" - ] - }, - { - "id": "poly-68", - "color": { - "h": 246.57534246575347, - "s": 100, - "l": 14.313725490196077, - "a": 1 - }, - "points": [ - "point-227", - "point-337", - "point-232" - ] - }, - { - "id": "poly-69", - "color": { - "h": 242.99999999999997, - "s": 100, - "l": 11.76470588235294, - "a": 1 - }, - "points": [ - "point-232", - "point-337", - "point-142" - ] - }, - { - "id": "poly-70", - "color": { - "h": 240, - "s": 100, - "l": 8.03921568627451, - "a": 1 - }, - "points": [ - "point-142", - "point-337", - "point-352" - ] - }, - { - "id": "poly-71", - "color": { - "h": 240, - "s": 100, - "l": 1.5686274509803921, - "a": 1 - }, - "points": [ - "point-142", - "point-352", - "point-357" - ] - }, - { - "id": "poly-72", - "color": { - "h": 264.45859872611464, - "s": 96.31901840490798, - "l": 31.960784313725487, - "a": 1 - }, - "points": [ - "point-252", - "point-1", - "point-362" - ] - }, - { - "id": "poly-73", - "color": { - "h": 265.24590163934425, - "s": 79.22077922077922, - "l": 45.294117647058826, - "a": 1 - }, - "points": [ - "point-252", - "point-362", - "point-257" - ] - }, - { - "id": "poly-74", - "color": { - "h": 264.68571428571425, - "s": 91.62303664921467, - "l": 37.450980392156865, - "a": 1 - }, - "points": [ - "point-257", - "point-362", - "point-372" - ] - }, - { - "id": "poly-75", - "color": { - "h": 264.9438202247191, - "s": 87.25490196078431, - "l": 40, - "a": 1 - }, - "points": [ - "point-257", - "point-372", - "point-267" - ] - }, - { - "id": "poly-76", - "color": { - "h": 262.3448275862069, - "s": 100, - "l": 28.431372549019606, - "a": 1 - }, - "points": [ - "point-267", - "point-372", - "point-382" - ] - }, - { - "id": "poly-77", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-267", - "point-382", - "point-277" - ] - }, - { - "id": "poly-78", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-277", - "point-382", - "point-392" - ] - }, - { - "id": "poly-79", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-277", - "point-392", - "point-397" - ] - }, - { - "id": "poly-80", - "color": { - "h": 261.69230769230774, - "s": 100, - "l": 25.49019607843137, - "a": 1 - }, - "points": [ - "point-277", - "point-397", - "point-292" - ] - }, - { - "id": "poly-81", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-292", - "point-397", - "point-407" - ] - }, - { - "id": "poly-82", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-292", - "point-407", - "point-302" - ] - }, - { - "id": "poly-83", - "color": { - "h": 240, - "s": 100, - "l": 10.588235294117647, - "a": 1 - }, - "points": [ - "point-302", - "point-407", - "point-417" - ] - }, - { - "id": "poly-84", - "color": { - "h": 242.99999999999997, - "s": 100, - "l": 11.76470588235294, - "a": 1 - }, - "points": [ - "point-302", - "point-417", - "point-307" - ] - }, - { - "id": "poly-85", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-307", - "point-417", - "point-317" - ] - }, - { - "id": "poly-86", - "color": { - "h": 240, - "s": 100, - "l": 4.705882352941177, - "a": 1 - }, - "points": [ - "point-317", - "point-417", - "point-432" - ] - }, - { - "id": "poly-87", - "color": { - "h": 240, - "s": 100, - "l": 6.862745098039216, - "a": 1 - }, - "points": [ - "point-317", - "point-432", - "point-327" - ] - }, - { - "id": "poly-88", - "color": { - "h": 240, - "s": 100, - "l": 1.5686274509803921, - "a": 1 - }, - "points": [ - "point-327", - "point-432", - "point-442" - ] - }, - { - "id": "poly-89", - "color": { - "h": 240, - "s": 100, - "l": 2.549019607843137, - "a": 1 - }, - "points": [ - "point-327", - "point-442", - "point-337" - ] - }, - { - "id": "poly-90", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-337", - "point-442", - "point-452" - ] - }, - { - "id": "poly-91", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-337", - "point-452", - "point-457" - ] - }, - { - "id": "poly-92", - "color": { - "h": 240, - "s": 100, - "l": 1.5686274509803921, - "a": 1 - }, - "points": [ - "point-337", - "point-457", - "point-352" - ] - }, - { - "id": "poly-93", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-352", - "point-457", - "point-357" - ] - }, - { - "id": "poly-94", - "color": { - "h": 261.69230769230774, - "s": 100, - "l": 25.49019607843137, - "a": 1 - }, - "points": [ - "point-362", - "point-1", - "point-472" - ] - }, - { - "id": "poly-95", - "color": { - "h": 260, - "s": 100, - "l": 24.11764705882353, - "a": 1 - }, - "points": [ - "point-362", - "point-472", - "point-382" - ] - }, - { - "id": "poly-96", - "color": { - "h": 263.64963503649636, - "s": 100, - "l": 26.862745098039216, - "a": 1 - }, - "points": [ - "point-362", - "point-382", - "point-372" - ] - }, - { - "id": "poly-97", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-382", - "point-472", - "point-487" - ] - }, - { - "id": "poly-98", - "color": { - "h": 255.31914893617022, - "s": 100, - "l": 18.43137254901961, - "a": 1 - }, - "points": [ - "point-382", - "point-487", - "point-392" - ] - }, - { - "id": "poly-99", - "color": { - "h": 249.75, - "s": 100, - "l": 15.686274509803921, - "a": 1 - }, - "points": [ - "point-392", - "point-487", - "point-497" - ] - }, - { - "id": "poly-100", - "color": { - "h": 246.57534246575347, - "s": 100, - "l": 14.313725490196077, - "a": 1 - }, - "points": [ - "point-392", - "point-497", - "point-397" - ] - }, - { - "id": "poly-101", - "color": { - "h": 240, - "s": 100, - "l": 10.588235294117647, - "a": 1 - }, - "points": [ - "point-397", - "point-497", - "point-507" - ] - }, - { - "id": "poly-102", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-397", - "point-507", - "point-407" - ] - }, - { - "id": "poly-103", - "color": { - "h": 240, - "s": 100, - "l": 6.862745098039216, - "a": 1 - }, - "points": [ - "point-407", - "point-507", - "point-517" - ] - }, - { - "id": "poly-104", - "color": { - "h": 240, - "s": 100, - "l": 5.686274509803922, - "a": 1 - }, - "points": [ - "point-407", - "point-517", - "point-417" - ] - }, - { - "id": "poly-105", - "color": { - "h": 240, - "s": 100, - "l": 1.5686274509803921, - "a": 1 - }, - "points": [ - "point-417", - "point-517", - "point-527" - ] - }, - { - "id": "poly-106", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-417", - "point-527", - "point-532" - ] - }, - { - "id": "poly-107", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-417", - "point-532", - "point-432" - ] - }, - { - "id": "poly-108", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-432", - "point-532", - "point-542" - ] - }, - { - "id": "poly-109", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-432", - "point-542", - "point-442" - ] - }, - { - "id": "poly-110", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-442", - "point-542", - "point-452" - ] - }, - { - "id": "poly-111", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-452", - "point-542", - "point-557" - ] - }, - { - "id": "poly-112", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-452", - "point-557", - "point-457" - ] - }, - { - "id": "poly-113", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-457", - "point-557", - "point-357" - ] - }, - { - "id": "poly-114", - "color": { - "h": 259.44444444444446, - "s": 100, - "l": 21.176470588235293, - "a": 1 - }, - "points": [ - "point-1", - "point-571", - "point-472" - ] - }, - { - "id": "poly-115", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-472", - "point-571", - "point-577" - ] - }, - { - "id": "poly-116", - "color": { - "h": 257.2277227722772, - "s": 100, - "l": 19.80392156862745, - "a": 1 - }, - "points": [ - "point-472", - "point-577", - "point-487" - ] - }, - { - "id": "poly-117", - "color": { - "h": 252.41379310344828, - "s": 100, - "l": 17.058823529411764, - "a": 1 - }, - "points": [ - "point-487", - "point-577", - "point-587" - ] - }, - { - "id": "poly-118", - "color": { - "h": 246.57534246575347, - "s": 100, - "l": 14.313725490196077, - "a": 1 - }, - "points": [ - "point-487", - "point-587", - "point-592" - ] - }, - { - "id": "poly-119", - "color": { - "h": 246.57534246575347, - "s": 100, - "l": 14.313725490196077, - "a": 1 - }, - "points": [ - "point-487", - "point-592", - "point-497" - ] - }, - { - "id": "poly-120", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-497", - "point-592", - "point-602" - ] - }, - { - "id": "poly-121", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-497", - "point-602", - "point-507" - ] - }, - { - "id": "poly-122", - "color": { - "h": 240, - "s": 100, - "l": 5.686274509803922, - "a": 1 - }, - "points": [ - "point-507", - "point-602", - "point-612" - ] - }, - { - "id": "poly-123", - "color": { - "h": 240, - "s": 100, - "l": 5.686274509803922, - "a": 1 - }, - "points": [ - "point-507", - "point-612", - "point-517" - ] - }, - { - "id": "poly-124", - "color": { - "h": 240, - "s": 100, - "l": 1.5686274509803921, - "a": 1 - }, - "points": [ - "point-517", - "point-612", - "point-527" - ] - }, - { - "id": "poly-125", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-527", - "point-612", - "point-627" - ] - }, - { - "id": "poly-126", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-527", - "point-627", - "point-632" - ] - }, - { - "id": "poly-127", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-527", - "point-632", - "point-532" - ] - }, - { - "id": "poly-128", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-532", - "point-632", - "point-542" - ] - }, - { - "id": "poly-129", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-542", - "point-632", - "point-647" - ] - }, - { - "id": "poly-130", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-542", - "point-647", - "point-652" - ] - }, - { - "id": "poly-131", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-542", - "point-652", - "point-557" - ] - }, - { - "id": "poly-132", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-557", - "point-652", - "point-357" - ] - }, - { - "id": "poly-133", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-357", - "point-652", - "point-667" - ] - }, - { - "id": "poly-134", - "color": { - "h": 240, - "s": 100, - "l": 6.862745098039216, - "a": 1 - }, - "points": [ - "point-571", - "point-647", - "point-587" - ] - }, - { - "id": "poly-135", - "color": { - "h": 252.41379310344828, - "s": 100, - "l": 17.058823529411764, - "a": 1 - }, - "points": [ - "point-571", - "point-587", - "point-577" - ] - }, - { - "id": "poly-136", - "color": { - "h": 240, - "s": 100, - "l": 2.549019607843137, - "a": 1 - }, - "points": [ - "point-587", - "point-647", - "point-602" - ] - }, - { - "id": "poly-137", - "color": { - "h": 240, - "s": 100, - "l": 9.215686274509805, - "a": 1 - }, - "points": [ - "point-587", - "point-602", - "point-592" - ] - }, - { - "id": "poly-138", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-602", - "point-647", - "point-632" - ] - }, - { - "id": "poly-139", - "color": { - "h": 240, - "s": 100, - "l": 0.5882352941176471, - "a": 1 - }, - "points": [ - "point-602", - "point-632", - "point-612" - ] - }, - { - "id": "poly-140", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-612", - "point-632", - "point-627" - ] - }, - { - "id": "poly-141", - "color": { - "h": 0, - "s": 0, - "l": 0, - "a": 1 - }, - "points": [ - "point-647", - "point-667", - "point-652" - ] - } - ] -}; diff --git a/website/source/assets/javascripts/app/_Init.js b/website/source/assets/javascripts/app/_Init.js deleted file mode 100644 index 06e772beb..000000000 --- a/website/source/assets/javascripts/app/_Init.js +++ /dev/null @@ -1,89 +0,0 @@ -(function( - Engine -){ - -// Quick and dirty IE detection -var isIE = (function(){ - if (window.navigator.userAgent.match('Trident')) { - return true; - } else { - return false; - } -})(); - -// isIE = true; - -var Init = { - - start: function(){ - var id = document.body.id.toLowerCase(); - - if (this.Pages[id]) { - this.Pages[id](); - } - //always init sidebar - Init.initializeSidebar(); - }, - - initializeSidebar: function(){ - new Sidebar(); - }, - - generateAnimatedLogo: function(){ - var container, x, block; - - container = document.createElement('div'); - container.className = 'animated-logo'; - - for (x = 1; x < 5; x++) { - block = document.createElement('div'); - block.className = 'white-block block-' + x; - container.appendChild(block); - } - - return container; - }, - - initializeEngine: function(){ - var jumbotron = document.getElementById('jumbotron'), - content = document.getElementById('jumbotron-content'), - tagLine = document.getElementById('tag-line'), - canvas, galaxy; - - if (!jumbotron) { - return; - } - - galaxy = document.createElement('div'); - galaxy.id = 'galaxy-bg'; - galaxy.className = 'galaxy-bg'; - jumbotron.appendChild(galaxy); - - content.appendChild( - Init.generateAnimatedLogo() - ); - - canvas = document.createElement('canvas'); - canvas.className = 'terraform-canvas'; - - jumbotron.appendChild(canvas); - new Engine(canvas, galaxy, tagLine); - }, - - Pages: { - 'page-home': function(){ - if (isIE) { - document.getElementById('jumbotron').className += ' static'; - document.getElementById('tag-line').style.visibility = 'visible'; - return; - } - - Init.initializeEngine(); - } - } - -}; - -Init.start(); - -})(window.Engine); diff --git a/website/source/assets/javascripts/app/_Logo.js b/website/source/assets/javascripts/app/_Logo.js deleted file mode 100644 index 0824b1c7e..000000000 --- a/website/source/assets/javascripts/app/_Logo.js +++ /dev/null @@ -1,1330 +0,0 @@ -// jshint unused:false -var Logo = { - "data": { - "width": 587, - "height": 587, - "ar": 1 - }, - "points": [ - { - "id": "point-0", - "x": 0.5809199318568995, - "y": 0.7478705281090289 - }, - { - "id": "point-1", - "x": 0.8160136286201022, - "y": 0.616695059625213 - }, - { - "id": "point-2", - "x": 0.6081771720613288, - "y": 0.8943781942078366 - }, - { - "id": "point-4", - "x": 0.9761499148211243, - "y": 0.6550255536626917 - }, - { - "id": "point-5", - "x": 0.848381601362862, - "y": 0.8603066439522997 - }, - { - "id": "point-12", - "x": 0.6354344122657581, - "y": 0.9829642248722317 - }, - { - "id": "point-16", - "x": 0.5536626916524702, - "y": 0.9982964224872233 - }, - { - "id": "point-20", - "x": 0.45451448040885867, - "y": 0.9463373083475298 - }, - { - "id": "point-24", - "x": 0.48126064735945484, - "y": 0.9982964224872233 - }, - { - "id": "point-28", - "x": 0.403747870528109, - "y": 0.994037478705281 - }, - { - "id": "point-32", - "x": 0.18143100511073254, - "y": 0.8858603066439524 - }, - { - "id": "point-36", - "x": 0.22998296422487224, - "y": 0.8057921635434411 - }, - { - "id": "point-40", - "x": 0.3373083475298126, - "y": 0.7052810902896082 - }, - { - "id": "point-44", - "x": 0.5143100511073253, - "y": 0.6933560477001702 - }, - { - "id": "point-56", - "x": 0.8918228279386712, - "y": 0.46337308347529815 - }, - { - "id": "point-60", - "x": 0.9974446337308348, - "y": 0.5366269165247018 - }, - { - "id": "point-64", - "x": 0.9574105621805792, - "y": 0.368824531516184 - }, - { - "id": "point-68", - "x": 0.9761499148211243, - "y": 0.36201022146507666 - }, - { - "id": "point-72", - "x": 0.6626916524701874, - "y": 0.43781942078364566 - }, - { - "id": "point-84", - "x": 0.4335604770017036, - "y": 0.5698466780238501 - }, - { - "id": "point-92", - "x": 0.11158432708688246, - "y": 0.8197614991482112 - }, - { - "id": "point-96", - "x": 0.09540034071550256, - "y": 0.6669505962521295 - }, - { - "id": "point-104", - "x": 0.05536626916524703, - "y": 0.7257240204429302 - }, - { - "id": "point-108", - "x": 0.03492333901192504, - "y": 0.6831345826235093 - }, - { - "id": "point-112", - "x": 0.15417376490630325, - "y": 0.4892674616695059 - }, - { - "id": "point-116", - "x": 0.22487223168654175, - "y": 0.4599659284497445 - }, - { - "id": "point-124", - "x": 0.2785349233390119, - "y": 0.35945485519591147 - }, - { - "id": "point-128", - "x": 0.48722316865417375, - "y": 0.35945485519591147 - }, - { - "id": "point-136", - "x": 0.5809199318568995, - "y": 0.2925042589437819 - }, - { - "id": "point-140", - "x": 0.889267461669506, - "y": 0.27649063032367976 - }, - { - "id": "point-152", - "x": 0.944633730834753, - "y": 0.2737649063032368 - }, - { - "id": "point-160", - "x": 0.8802385008517888, - "y": 0.18177172061328795 - }, - { - "id": "point-168", - "x": 0.5809199318568995, - "y": 0.19471890971039182 - }, - { - "id": "point-176", - "x": 0.7989778534923339, - "y": 0.10391822827938672 - }, - { - "id": "point-180", - "x": 0.6218057921635435, - "y": 0.018739352640545145 - }, - { - "id": "point-184", - "x": 0.5252129471890972, - "y": 0.0005110732538330494 - }, - { - "id": "point-188", - "x": 0.3889267461669506, - "y": 0.09761499148211243 - }, - { - "id": "point-192", - "x": 0.38126064735945486, - "y": 0.018739352640545145 - }, - { - "id": "point-196", - "x": 0.30153321976149916, - "y": 0.04258943781942079 - }, - { - "id": "point-200", - "x": 0.2969335604770017, - "y": 0.09761499148211243 - }, - { - "id": "point-216", - "x": 0.049403747870528106, - "y": 0.3083475298126065 - }, - { - "id": "point-228", - "x": 0.002214650766609881, - "y": 0.47155025553662694 - }, - { - "id": "point-232", - "x": 0.0005110732538330494, - "y": 0.5289608177172062 - }, - { - "id": "point-244", - "x": 0.17325383304940373, - "y": 0.12180579216354344 - } - ], - "polygons": [ - { - "id": "poly-0", - "color": { - "h": 264.688995215311, - "s": 100, - "l": 59.01960784313726, - "a": 1 - }, - "points": [ - "point-0", - "point-1", - "point-2" - ] - }, - { - "id": "poly-1", - "color": { - "h": 268.3076923076923, - "s": 100, - "l": 61.76470588235294, - "a": 1 - }, - "points": [ - "point-4", - "point-5", - "point-1" - ] - }, - { - "id": "poly-2", - "color": { - "h": 267.1641791044776, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-5", - "point-2", - "point-1" - ] - }, - { - "id": "poly-3", - "color": { - "h": 268.3076923076923, - "s": 100, - "l": 61.76470588235294, - "a": 1 - }, - "points": [ - "point-12", - "point-2", - "point-5" - ] - }, - { - "id": "poly-4", - "color": { - "h": 267.1641791044776, - "s": 100, - "l": 60.588235294117645, - "a": 1 - }, - "points": [ - "point-16", - "point-12", - "point-2" - ] - }, - { - "id": "poly-5", - "color": { - "h": 264.9, - "s": 92.59259259259261, - "l": 57.647058823529406, - "a": 1 - }, - "points": [ - "point-20", - "point-2", - "point-16" - ] - }, - { - "id": "poly-6", - "color": { - "h": 264.9, - "s": 92.59259259259261, - "l": 57.647058823529406, - "a": 1 - }, - "points": [ - "point-24", - "point-20", - "point-16" - ] - }, - { - "id": "poly-7", - "color": { - "h": 264.97461928934007, - "s": 85.28138528138528, - "l": 54.70588235294118, - "a": 1 - }, - "points": [ - "point-28", - "point-20", - "point-24" - ] - }, - { - "id": "poly-8", - "color": { - "h": 265.4347826086956, - "s": 80, - "l": 45.09803921568628, - "a": 1 - }, - "points": [ - "point-32", - "point-20", - "point-28" - ] - }, - { - "id": "poly-9", - "color": { - "h": 265.4347826086956, - "s": 80, - "l": 45.09803921568628, - "a": 1 - }, - "points": [ - "point-36", - "point-32", - "point-20" - ] - }, - { - "id": "poly-10", - "color": { - "h": 265.4347826086956, - "s": 80, - "l": 45.09803921568628, - "a": 1 - }, - "points": [ - "point-40", - "point-36", - "point-20" - ] - }, - { - "id": "poly-11", - "color": { - "h": 265.48387096774195, - "s": 76.22950819672131, - "l": 47.84313725490196, - "a": 1 - }, - "points": [ - "point-44", - "point-20", - "point-40" - ] - }, - { - "id": "poly-12", - "color": { - "h": 264.61538461538464, - "s": 79.59183673469387, - "l": 51.9607843137255, - "a": 1 - }, - "points": [ - "point-0", - "point-44", - "point-20" - ] - }, - { - "id": "poly-13", - "color": { - "h": 264.9, - "s": 92.59259259259261, - "l": 57.647058823529406, - "a": 1 - }, - "points": [ - "point-0", - "point-20", - "point-2" - ] - }, - { - "id": "poly-14", - "color": { - "h": 264.61538461538464, - "s": 79.59183673469387, - "l": 51.9607843137255, - "a": 1 - }, - "points": [ - "point-56", - "point-1", - "point-4" - ] - }, - { - "id": "poly-15", - "color": { - "h": 264.61538461538464, - "s": 79.59183673469387, - "l": 51.9607843137255, - "a": 1 - }, - "points": [ - "point-60", - "point-4", - "point-56" - ] - }, - { - "id": "poly-16", - "color": { - "h": 263.64705882352945, - "s": 86.73469387755101, - "l": 38.43137254901961, - "a": 1 - }, - "points": [ - "point-64", - "point-56", - "point-60" - ] - }, - { - "id": "poly-17", - "color": { - "h": 264.9056603773585, - "s": 90.85714285714286, - "l": 34.31372549019608, - "a": 1 - }, - "points": [ - "point-68", - "point-64", - "point-60" - ] - }, - { - "id": "poly-18", - "color": { - "h": 263.64705882352945, - "s": 86.73469387755101, - "l": 38.43137254901961, - "a": 1 - }, - "points": [ - "point-72", - "point-56", - "point-1" - ] - }, - { - "id": "poly-19", - "color": { - "h": 265.4347826086956, - "s": 80, - "l": 45.09803921568628, - "a": 1 - }, - "points": [ - "point-0", - "point-72", - "point-1" - ] - }, - { - "id": "poly-20", - "color": { - "h": 264.20454545454544, - "s": 79.27927927927928, - "l": 43.529411764705884, - "a": 1 - }, - "points": [ - "point-72", - "point-0", - "point-44" - ] - }, - { - "id": "poly-21", - "color": { - "h": 264.2307692307692, - "s": 95.12195121951221, - "l": 32.15686274509804, - "a": 1 - }, - "points": [ - "point-84", - "point-44", - "point-72" - ] - }, - { - "id": "poly-22", - "color": { - "h": 263.64705882352945, - "s": 86.73469387755101, - "l": 38.43137254901961, - "a": 1 - }, - "points": [ - "point-40", - "point-84", - "point-44" - ] - }, - { - "id": "poly-23", - "color": { - "h": 264.9056603773585, - "s": 90.85714285714286, - "l": 34.31372549019608, - "a": 1 - }, - "points": [ - "point-92", - "point-32", - "point-36" - ] - }, - { - "id": "poly-24", - "color": { - "h": 264.2307692307692, - "s": 95.12195121951221, - "l": 32.15686274509804, - "a": 1 - }, - "points": [ - "point-96", - "point-92", - "point-36" - ] - }, - { - "id": "poly-25", - "color": { - "h": 264.9056603773585, - "s": 90.85714285714286, - "l": 34.31372549019608, - "a": 1 - }, - "points": [ - "point-40", - "point-96", - "point-36" - ] - }, - { - "id": "poly-26", - "color": { - "h": 264.2307692307692, - "s": 95.12195121951221, - "l": 32.15686274509804, - "a": 1 - }, - "points": [ - "point-104", - "point-92", - "point-96" - ] - }, - { - "id": "poly-27", - "color": { - "h": 261.6, - "s": 100, - "l": 14.705882352941178, - "a": 1 - }, - "points": [ - "point-108", - "point-104", - "point-96" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-28", - "color": { - "h": 261.6, - "s": 100, - "l": 14.705882352941178, - "a": 1 - }, - "points": [ - "point-112", - "point-40", - "point-96" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-29", - "color": { - "h": 257.910447761194, - "s": 100, - "l": 13.137254901960786, - "a": 1 - }, - "points": [ - "point-116", - "point-112", - "point-40" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-30", - "color": { - "h": 262.8571428571429, - "s": 100, - "l": 16.470588235294116, - "a": 1 - }, - "points": [ - "point-84", - "point-40", - "point-116" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-31", - "color": { - "h": 252.00000000000003, - "s": 100, - "l": 9.803921568627452, - "a": 1 - }, - "points": [ - "point-124", - "point-84", - "point-116" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-32", - "color": { - "h": 252.00000000000003, - "s": 100, - "l": 9.803921568627452, - "a": 1 - }, - "points": [ - "point-128", - "point-84", - "point-124" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-33", - "color": { - "h": 257.910447761194, - "s": 100, - "l": 13.137254901960786, - "a": 1 - }, - "points": [ - "point-72", - "point-128", - "point-84" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-34", - "color": { - "h": 252.00000000000003, - "s": 100, - "l": 9.803921568627452, - "a": 1 - }, - "points": [ - "point-136", - "point-128", - "point-72" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-35", - "color": { - "h": 253.44827586206898, - "s": 100, - "l": 11.372549019607844, - "a": 1 - }, - "points": [ - "point-140", - "point-136", - "point-72" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-36", - "color": { - "h": 261.6, - "s": 100, - "l": 14.705882352941178, - "a": 1 - }, - "points": [ - "point-140", - "point-56", - "point-72" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-37", - "color": { - "h": 262.8571428571429, - "s": 100, - "l": 16.470588235294116, - "a": 1 - }, - "points": [ - "point-64", - "point-56", - "point-140" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-38", - "color": { - "h": 259.4366197183098, - "s": 100, - "l": 13.92156862745098, - "a": 1 - }, - "points": [ - "point-152", - "point-140", - "point-64" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-39", - "color": { - "h": 259.4366197183098, - "s": 100, - "l": 13.92156862745098, - "a": 1 - }, - "points": [ - "point-68", - "point-64", - "point-152" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-40", - "color": { - "h": 253.44827586206898, - "s": 100, - "l": 11.372549019607844, - "a": 1 - }, - "points": [ - "point-160", - "point-140", - "point-152" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-41", - "color": { - "h": 245.58139534883722, - "s": 100, - "l": 8.431372549019608, - "a": 1 - }, - "points": [ - "point-136", - "point-160", - "point-140" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-42", - "color": { - "h": 246.15384615384613, - "s": 100, - "l": 7.647058823529412, - "a": 1 - }, - "points": [ - "point-168", - "point-128", - "point-136" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-43", - "color": { - "h": 245.58139534883722, - "s": 100, - "l": 8.431372549019608, - "a": 1 - }, - "points": [ - "point-160", - "point-168", - "point-136" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-44", - "color": { - "h": 246.15384615384613, - "s": 100, - "l": 7.647058823529412, - "a": 1 - }, - "points": [ - "point-176", - "point-160", - "point-168" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-45", - "color": { - "h": 246.15384615384613, - "s": 100, - "l": 7.647058823529412, - "a": 1 - }, - "points": [ - "point-180", - "point-168", - "point-176" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-46", - "color": { - "h": 240, - "s": 100, - "l": 4.509803921568627, - "a": 1 - }, - "points": [ - "point-184", - "point-168", - "point-180" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-47", - "color": { - "h": 240, - "s": 100, - "l": 4.509803921568627, - "a": 1 - }, - "points": [ - "point-188", - "point-168", - "point-184" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-48", - "color": { - "h": 240, - "s": 100, - "l": 4.509803921568627, - "a": 1 - }, - "points": [ - "point-192", - "point-188", - "point-184" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-49", - "color": { - "h": 240, - "s": 100, - "l": 4.509803921568627, - "a": 1 - }, - "points": [ - "point-196", - "point-188", - "point-192" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-50", - "color": { - "h": 240, - "s": 100, - "l": 0.5882352941176471, - "a": 1 - }, - "points": [ - "point-200", - "point-196", - "point-188" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-51", - "color": { - "h": 240, - "s": 100, - "l": 3.3333333333333335, - "a": 1 - }, - "points": [ - "point-188", - "point-124", - "point-200" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-52", - "color": { - "h": 240, - "s": 100, - "l": 5.294117647058823, - "a": 1 - }, - "points": [ - "point-188", - "point-124", - "point-128" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-53", - "color": { - "h": 245.1428571428571, - "s": 100, - "l": 6.862745098039216, - "a": 1 - }, - "points": [ - "point-188", - "point-128", - "point-168" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-54", - "color": { - "h": 240, - "s": 100, - "l": 3.3333333333333335, - "a": 1 - }, - "points": [ - "point-216", - "point-200", - "point-124" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-55", - "color": { - "h": 240, - "s": 100, - "l": 5.294117647058823, - "a": 1 - }, - "points": [ - "point-216", - "point-116", - "point-124" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-56", - "color": { - "h": 245.1428571428571, - "s": 100, - "l": 6.862745098039216, - "a": 1 - }, - "points": [ - "point-112", - "point-216", - "point-116" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-57", - "color": { - "h": 240, - "s": 100, - "l": 5.294117647058823, - "a": 1 - }, - "points": [ - "point-228", - "point-216", - "point-112" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-58", - "color": { - "h": 249.13043478260872, - "s": 100, - "l": 9.019607843137255, - "a": 1 - }, - "points": [ - "point-232", - "point-112", - "point-96" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-59", - "color": { - "h": 253.44827586206898, - "s": 100, - "l": 11.372549019607844, - "a": 1 - }, - "points": [ - "point-108", - "point-96", - "point-232" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-60", - "color": { - "h": 240, - "s": 100, - "l": 5.294117647058823, - "a": 1 - }, - "points": [ - "point-228", - "point-112", - "point-232" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-61", - "color": { - "h": 240, - "s": 100, - "l": 0.5882352941176471, - "a": 1 - }, - "points": [ - "point-244", - "point-216", - "point-200" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - }, - { - "id": "poly-62", - "color": { - "h": 240, - "s": 100, - "l": 0.5882352941176471, - "a": 1 - }, - "points": [ - "point-196", - "point-200", - "point-244" - ], - "stroke": { - "h": 262.24719101123594, - "s": 60.544217687074834, - "l": 28.82352941176471, - "a": 0.4 - } - } - ] -}; diff --git a/website/source/assets/javascripts/app/_Puller.js b/website/source/assets/javascripts/app/_Puller.js deleted file mode 100644 index 2df85c733..000000000 --- a/website/source/assets/javascripts/app/_Puller.js +++ /dev/null @@ -1,136 +0,0 @@ -(function( - Engine, - Vector -){ - -var Puller = function(x, y){ - this.pos.x = x; - this.pos.y = y; - this.pos = Vector.coerce(this.pos); - this.home = this.pos.clone(); - this.accel = Vector.coerce(this.accel); - this.vel = Vector.coerce(this.vel); -}; - -Puller.prototype = { - - fillStyle: '#ffffff', - radius: 5, - - maxSpeed: 160, - maxForce: 50, - - pos: { - x: 0, - y: 0 - }, - - accel: { - x: 0, - y: 0 - }, - - vel: { - x: 0, - y: 0 - }, - - aRad: 200, - - safety: 0.25, - - update: function(engine){ - var distanceToMouse = this.distanceTo(engine.mouse), - toHome, mag, safety; - // distanceToHome = this.distanceTo(this.home); - - this.accel.mult(0); - - if (distanceToMouse < this.aRad) { - this.toChase(engine.mouse); - } - - this.toChase(this.home, this.maxForce / 2); - - this.vel.add(this.accel); - this.pos.add( - Vector.mult(this.vel, engine.tick) - ); - - toHome = Vector.sub(this.home, this.pos); - mag = toHome.mag(); - safety = this.aRad * (this.safety * 3); - if (mag > this.aRad - safety) { - toHome.normalize(); - toHome.mult(this.aRad - safety); - this.pos = Vector.sub(this.home, toHome); - } - }, - - toChase: function(target, maxForce){ - var desired, steer, distance, mult, safety; - - maxForce = maxForce || this.maxForce; - - target = Vector.coerce(target); - desired = Vector.sub(target, this.pos); - distance = desired.mag(); - desired.normalize(); - - safety = this.aRad * this.safety; - - if (distance < safety) { - mult = Engine.map(distance, 0, safety, 0, this.maxSpeed); - } else if (distance > this.aRad - safety){ - mult = Engine.map(this.aRad - distance, 0, safety, 0, this.maxSpeed); - } else { - mult = this.maxSpeed; - } - - desired.mult(mult); - - steer = Vector.sub(desired, this.vel); - steer.limit(maxForce); - this.accel.add(steer); - }, - - draw: function(ctx, scale){ - // ctx.beginPath(); - // ctx.arc( - // this.home.x * scale, - // this.home.y * scale, - // this.aRad * scale, - // 0, - // Math.PI * 2, - // false - // ); - // ctx.fillStyle = 'rgba(255,255,255,0.1)'; - // ctx.fill(); - - ctx.beginPath(); - ctx.arc( - this.pos.x * scale, - this.pos.y * scale, - this.radius * scale, - 0, - Math.PI * 2, - false - ); - ctx.fillStyle = this.fillStyle; - ctx.fill(); - - }, - - distanceTo: function(target) { - var xd = this.home.x - target.x; - var yd = this.home.y - target.y; - return Math.sqrt(xd * xd + yd * yd ); - } -}; - -window.Puller = Puller; - -})( - window.Engine, - window.Vector -); diff --git a/website/source/assets/javascripts/app/_Sidebar.js b/website/source/assets/javascripts/app/_Sidebar.js deleted file mode 100644 index b36e508c4..000000000 --- a/website/source/assets/javascripts/app/_Sidebar.js +++ /dev/null @@ -1,50 +0,0 @@ -(function(){ - - Sidebar = Base.extend({ - - $body: null, - $overlay: null, - $sidebar: null, - $sidebarHeader: null, - $sidebarImg: null, - $toggleButton: null, - - constructor: function(){ - this.$body = $('body'); - this.$overlay = $('.sidebar-overlay'); - this.$sidebar = $('#sidebar'); - this.$sidebarHeader = $('#sidebar .sidebar-header'); - this.$toggleButton = $('.navbar-toggle'); - this.sidebarImg = this.$sidebarHeader.css('background-image'); - - this.addEventListeners(); - }, - - addEventListeners: function(){ - var _this = this; - - _this.$toggleButton.on('click', function() { - _this.$sidebar.toggleClass('open'); - if ((_this.$sidebar.hasClass('sidebar-fixed-left') || _this.$sidebar.hasClass('sidebar-fixed-right')) && _this.$sidebar.hasClass('open')) { - _this.$overlay.addClass('active'); - _this.$body.css('overflow', 'hidden'); - } else { - _this.$overlay.removeClass('active'); - _this.$body.css('overflow', 'auto'); - } - - return false; - }); - - _this.$overlay.on('click', function() { - $(this).removeClass('active'); - _this.$body.css('overflow', 'auto'); - _this.$sidebar.removeClass('open'); - }); - } - - }); - - window.Sidebar = Sidebar; - -})(); diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index bc70be7fb..ad181b4cc 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -1,29 +1,5 @@ //= require turbolinks //= require jquery -//= require bootstrap -//= require lib/_String.substitute -//= require lib/_Vector -//= require lib/_Function.prototype.bind -//= require lib/_Base -//= require lib/_Chainable -//= require lib/_dbg - -//= require app/_Docs -//= require app/_Logo -//= require app/_Grid -//= require app/_Engine -//= require app/_Engine.Particle -//= require app/_Engine.Particle.Fixed -//= require app/_Engine.Point -//= require app/_Engine.Point.Puller -//= require app/_Engine.Polygon -//= require app/_Engine.Polygon.Puller -//= require app/_Engine.Shape -//= require app/_Engine.Shape.Puller -//= require app/_Engine.Typewriter -//= require app/_Sidebar -//= require app/_Init - -// assets/javascripts/application.js //= require hashicorp/mega-nav +//= require hashicorp/sidebar diff --git a/website/source/assets/javascripts/lib/_Base.js b/website/source/assets/javascripts/lib/_Base.js deleted file mode 100644 index 504e2beea..000000000 --- a/website/source/assets/javascripts/lib/_Base.js +++ /dev/null @@ -1,145 +0,0 @@ -/* - Based on Base.js 1.1a (c) 2006-2010, Dean Edwards - Updated to pass JSHint and converted into a module by Kenneth Powers - License: http://www.opensource.org/licenses/mit-license.php -*/ -/*global define:true module:true*/ -/*jshint eqeqeq:true*/ -(function (name, global, definition) { - if (typeof module !== 'undefined') { - module.exports = definition(); - } else if (typeof define !== 'undefined' && typeof define.amd === 'object') { - define(definition); - } else { - global[name] = definition(); - } -})('Base', this, function () { - // Base Object - var Base = function () {}; - - // Implementation - Base.extend = function (_instance, _static) { // subclass - var extend = Base.prototype.extend; - // build the prototype - Base._prototyping = true; - var proto = new this(); - extend.call(proto, _instance); - proto.base = function () { - // call this method from any other method to invoke that method's ancestor - }; - delete Base._prototyping; - // create the wrapper for the constructor function - //var constructor = proto.constructor.valueOf(); //-dean - var constructor = proto.constructor; - var klass = proto.constructor = function () { - if (!Base._prototyping) { - if (this._constructing || this.constructor === klass) { // instantiation - this._constructing = true; - constructor.apply(this, arguments); - delete this._constructing; - } else if (arguments[0] !== null) { // casting - return (arguments[0].extend || extend).call(arguments[0], proto); - } - } - }; - // build the class interface - klass.ancestor = this; - klass.extend = this.extend; - klass.forEach = this.forEach; - klass.implement = this.implement; - klass.prototype = proto; - klass.toString = this.toString; - klass.valueOf = function (type) { - return (type === 'object') ? klass : constructor.valueOf(); - }; - extend.call(klass, _static); - // class initialization - if (typeof klass.init === 'function') klass.init(); - return klass; - }; - - Base.prototype = { - extend: function (source, value) { - if (arguments.length > 1) { // extending with a name/value pair - var ancestor = this[source]; - if (ancestor && (typeof value === 'function') && // overriding a method? - // the valueOf() comparison is to avoid circular references - (!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) { - // get the underlying method - var method = value.valueOf(); - // override - value = function () { - var previous = this.base || Base.prototype.base; - this.base = ancestor; - var returnValue = method.apply(this, arguments); - this.base = previous; - return returnValue; - }; - // point to the underlying method - value.valueOf = function (type) { - return (type === 'object') ? value : method; - }; - value.toString = Base.toString; - } - this[source] = value; - } else if (source) { // extending with an object literal - var extend = Base.prototype.extend; - // if this object has a customized extend method then use it - if (!Base._prototyping && typeof this !== 'function') { - extend = this.extend || extend; - } - var proto = { - toSource: null - }; - // do the "toString" and other methods manually - var hidden = ['constructor', 'toString', 'valueOf']; - // if we are prototyping then include the constructor - for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) { - var h = hidden[i]; - if (source[h] !== proto[h]) - extend.call(this, h, source[h]); - } - // copy each of the source object's properties to this object - for (var key in source) { - if (!proto[key]) extend.call(this, key, source[key]); - } - } - return this; - } - }; - - // initialize - Base = Base.extend({ - constructor: function () { - this.extend(arguments[0]); - } - }, { - ancestor: Object, - version: '1.1', - forEach: function (object, block, context) { - for (var key in object) { - if (this.prototype[key] === undefined) { - block.call(context, object[key], key, object); - } - } - }, - implement: function () { - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] === 'function') { - // if it's a function, call it - arguments[i](this.prototype); - } else { - // add the interface using the extend method - this.prototype.extend(arguments[i]); - } - } - return this; - }, - toString: function () { - return String(this.valueOf()); - } - }); - - // Return Base implementation - return Base; -}); diff --git a/website/source/assets/javascripts/lib/_Chainable.js b/website/source/assets/javascripts/lib/_Chainable.js deleted file mode 100644 index dbe51dd1d..000000000 --- a/website/source/assets/javascripts/lib/_Chainable.js +++ /dev/null @@ -1,92 +0,0 @@ -(function(){ - -var Chainable = function(engine){ - this.engine = engine; - this._chain = []; - this._updateTimer = this._updateTimer.bind(this); - this._cycle = this._cycle.bind(this); -}; - -Chainable.prototype._running = false; - -Chainable.prototype._updateTimer = function(tick){ - this._timer += tick; - if (this._timer >= this._timerMax) { - this.resetTimer(); - this._cycle(); - } -}; - -Chainable.prototype.resetTimer = function(){ - this.engine.updateChainTimer = undefined; - this._timer = 0; - this._timerMax = 0; - return this; -}; - -Chainable.prototype.start = function(){ - if (this._running || !this._chain.length) { - return this; - } - this._running = true; - return this._cycle(); -}; - -Chainable.prototype.reset = function(){ - if (!this._running) { - return this; - } - this.resetTimer(); - this._timer = 0; - this._running = false; - return this; -}; - -Chainable.prototype._cycle = function(){ - var current; - if (!this._chain.length) { - return this.reset(); - } - - current = this._chain.shift(); - - if (current.type === 'function') { - current.func.apply(current.scope, current.args); - current = null; - return this._cycle(); - } - if (current.type === 'wait') { - this.resetTimer(); - // Convert timer to seconds - this._timerMax = current.time / 1000; - this.engine.updateChainTimer = this._updateTimer; - current = null; - } - - return this; -}; - -Chainable.prototype.then = Chainable.prototype.exec = function(func, scope, args){ - this._chain.push({ - type : 'function', - - func : func, - scope : scope || window, - args : args || [] - }); - - return this.start(); -}; - -Chainable.prototype.wait = function(time){ - this._chain.push({ - type : 'wait', - time : time - }); - - return this.start(); -}; - -window.Chainable = Chainable; - -})(); diff --git a/website/source/assets/javascripts/lib/_Function.prototype.bind.js b/website/source/assets/javascripts/lib/_Function.prototype.bind.js deleted file mode 100644 index 82c3cb6c6..000000000 --- a/website/source/assets/javascripts/lib/_Function.prototype.bind.js +++ /dev/null @@ -1,21 +0,0 @@ -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis ? - this : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; -} diff --git a/website/source/assets/javascripts/lib/_String.substitute.js b/website/source/assets/javascripts/lib/_String.substitute.js deleted file mode 100644 index da2b52a38..000000000 --- a/website/source/assets/javascripts/lib/_String.substitute.js +++ /dev/null @@ -1,14 +0,0 @@ -(function(String){ - -if (String.prototype.substitute) { - return; -} - -String.prototype.substitute = function(object, regexp){ - return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ - if (match.charAt(0) == '\\') return match.slice(1); - return (object[name] !== null) ? object[name] : ''; - }); -}; - -})(String); diff --git a/website/source/assets/javascripts/lib/_Vector.js b/website/source/assets/javascripts/lib/_Vector.js deleted file mode 100644 index 0334c7ac7..000000000 --- a/website/source/assets/javascripts/lib/_Vector.js +++ /dev/null @@ -1,111 +0,0 @@ -(function(global){ 'use strict'; - -var Vector = function(x, y){ - this.x = x || 0; - this.y = y || 0; -}; - -Vector.prototype = { - - clone: function(){ - return new Vector(this.x, this.y); - }, - - add: function(vec){ - this.x += vec.x; - this.y += vec.y; - return this; - }, - - sub: function(vec){ - this.x -= vec.x; - this.y -= vec.y; - return this; - }, - - subVal: function(val){ - this.x -= val; - this.y -= val; - return this; - }, - - mult: function(mul){ - this.x *= mul; - this.y *= mul; - return this; - }, - - div: function(div){ - if (div === 0) { - return this; - } - this.x /= div; - this.y /= div; - return this; - }, - - mag: function(){ - return Math.sqrt( - this.x * this.x + - this.y * this.y - ); - }, - - limit: function(max){ - if (this.mag() > max) { - this.normalize(); - this.mult(max); - } - return this; - }, - - normalize: function(){ - var mag = this.mag(); - if (mag === 0) { - return this; - } - this.div(mag); - return this; - }, - - heading: function(){ - return Math.atan2(this.y, this.x); - }, - - set: function(vec){ - this.x = vec.x; - this.y = vec.y; - return this; - } - -}; - -Vector.add = function(vec1, vec2){ - return vec1.clone().add(vec2.clone()); -}; - -Vector.sub = function(vec1, vec2){ - return vec1.clone().sub(vec2.clone()); -}; - -Vector.mult = function(vec, mult){ - return vec.clone().mult(mult); -}; - -Vector.div = function(vec, div){ - return vec.clone().div(div); -}; - -// Ripped from processing -Vector.random2D = function(){ - var angle = Math.random(0, 1) * Math.PI * 2; - return new Vector(Math.cos(angle), Math.sin(angle)); -}; - -Vector.coerce = function(obj){ - return new Vector(obj.x, obj.y); -}; - -global.Vector = Vector; - -})(this); diff --git a/website/source/assets/javascripts/lib/_dbg.js b/website/source/assets/javascripts/lib/_dbg.js deleted file mode 100644 index 6df4f3762..000000000 --- a/website/source/assets/javascripts/lib/_dbg.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * name: dbg - * - * description: A bad ass little console utility, check the README for deets - * - * license: MIT-style license - * - * author: Amadeus Demarzi - * - * provides: window.dbg - * - */ - -(function(){ - - var global = this, - - // Get the real console or set to null for easy boolean checks - realConsole = global.console || null, - - // Backup / Disabled Lambda - fn = function(){}, - - // Supported console methods - methodNames = ['log', 'error', 'warn', 'info', 'count', 'debug', 'profileEnd', 'trace', 'dir', 'dirxml', 'assert', 'time', 'profile', 'timeEnd', 'group', 'groupEnd'], - - // Disabled Console - disabledConsole = { - - // Enables dbg, if it exists, otherwise it just provides disabled - enable: function(quiet){ - global.dbg = realConsole ? realConsole : disabledConsole; - }, - - // Disable dbg - disable: function(){ - global.dbg = disabledConsole; - } - - }, name, i; - - // Setup disabled console and provide fallbacks on the real console - for (i = 0; i < methodNames.length;i++){ - name = methodNames[i]; - disabledConsole[name] = fn; - if (realConsole && !realConsole[name]) - realConsole[name] = fn; - } - - // Add enable/disable methods - if (realConsole) { - realConsole.disable = disabledConsole.disable; - realConsole.enable = disabledConsole.enable; - } - - // Enable dbg - disabledConsole.enable(); - -}).call(this); diff --git a/website/source/assets/stylesheets/_buttons.scss b/website/source/assets/stylesheets/_buttons.scss index c1f44435d..e1037e818 100755 --- a/website/source/assets/stylesheets/_buttons.scss +++ b/website/source/assets/stylesheets/_buttons.scss @@ -1,137 +1,37 @@ -// -// Button Styles -// -------------------------------------------------- - -.outline-btn{ - position: relative; - display: inline-block; - // Extra 3px of bottom padding compensates for ::after content - padding: 20px 30px 23px; - background-color: transparent; - color: $white; - border: 2px solid $white; - //border-radius: $btn-border-radius; - font-size: 20px; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 2px; - text-decoration: none !important; - @include transition(background-color .3s ease-in-out); - - &::after { - font-size: 1.2em; - content: "»"; - position: relative; - left: 5px; - } - - &.purple{ - color: $purple; - border: 2px solid $purple; - } - - &.small-outline-btn{ - font-size: 16px; - padding: 0px 15px 3px 10px; - letter-spacing: 0; - border: 2px solid rgba(255, 255, 255, .7); - } - - &:hover{ - color: $white; - background-color: rgba(255, 255, 255, .2); - @include transition(background-color .3s ease-in-out); - - &.purple{ - background-color: rgba(255, 255, 255, .5); - } - } -} - -.simple-btn{ - position: relative; - display: inline-block; - // Extra 3px of bottom padding compensates for ::after content - background-color: transparent; - color: $white; - font-size: 16px; - font-weight: 500; - text-transform: uppercase; - text-decoration: none !important; - @include transition(color .3s ease-in-out); - - &::after { - font-size: 1.2em; - content: "»"; - position: relative; - left: 5px; - } - - &:hover{ - color: rgba(255, 255, 255, .4); - @include transition(color .3s ease-in-out); - } -} - -.terra-btn{ - position: relative; - display: inline-block; - // Extra 3px of bottom padding compensates for ::after content - padding: 20px 30px 23px; - color: white; - background-color: $purple; - font-size: 20px; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 2px; - @include transition( background-color 0.3s ease ); - - &::after { - font-size: 1.2em; - content: "»"; - position: relative; - left: 5px; - } - - &:hover{ - color: white; - background-color: rgba(130, 47, 247, 0.8); - text-decoration: none; - @include transition( background-color 0.3s ease ); - } -} - -@media (max-width: 768px) { - .outline-btn, .terra-btn{ - font-size: 16px; - text-align: center; - } -} - -//animation on header main nav link hover -/*.li-under a::after { - position: absolute; - top: 68%; - left: 50%; - margin-left: -4px; - width: 6px; - height: 6px; - background-color: white; - content: ''; - opacity: 0; +.button { + background: $button-background; + border: 1px solid $button-font-color; + box-shadow: 3px 4px 0 rgba(0,0,0,0.1); + color: $button-font-color; + display: inline-block; + font-family: $button-font-family; + font-size: $button-font-size; + font-weight: $button-font-weight; + letter-spacing: 1px; + margin-bottom: 4px; + padding: 10px 30px; + text-transform: uppercase; text-decoration: none; - -webkit-transition: height 0.3s, opacity 0.3s, -webkit-transform 0.3s; - -moz-transition: height 0.3s, opacity 0.3s, -moz-transform 0.3s; - transition: height 0.3s, opacity 0.3s, transform 0.3s; - -webkit-transform: translateY(-10px); - -moz-transform: translateY(-10px); - transform: translateY(-10px); -} -.li-under a:hover::after, -.li-under a:focus::after { - opacity: 1; - -webkit-transform: skewY(15deg) translateY(10px); - -moz-transform: skewY(15deg) translateY(10px); - transform: skewY(15deg) translateY(10px); -}*/ + &:hover, + &:active, + &:focus { + text-decoration: none; + } + + &:hover { + background: $button-font-color; + border: 1px solid $button-font-color; + color: $button-background; + } + + &.primary { + background: $button-primary-background; + border: 1px solid darken($button-primary-background, 5%); + color: $button-primary-font-color; + + &:hover { + background: lighten($button-primary-background, 5%); + } + } +} diff --git a/website/source/assets/stylesheets/_community.scss b/website/source/assets/stylesheets/_community.scss index ff8c3412e..1ff047de6 100644 --- a/website/source/assets/stylesheets/_community.scss +++ b/website/source/assets/stylesheets/_community.scss @@ -1,21 +1,22 @@ -.people { +#inner { + .people { margin-top: 30px; .person { - margin-bottom: 40px; - min-height: 165px; // enough space for five lines of bio text + &:after { + display: block; + clear: both; + content: ' '; + } - h3 { - text-transform: none; - } + img { + width: 125px; + margin: auto auto; + } - img { - width: 125px; - margin: auto auto; - } - - .bio { - padding-left: 150px; - } + .bio { + padding-left: 150px; + } } + } } diff --git a/website/source/assets/stylesheets/_docs.scss b/website/source/assets/stylesheets/_docs.scss index 35f16eb60..475aa46d8 100755 --- a/website/source/assets/stylesheets/_docs.scss +++ b/website/source/assets/stylesheets/_docs.scss @@ -1,362 +1,91 @@ -// -// Docs -// -------------------------------------------------- - -body.page-sub{ - background-color: $light-black; -} - -body.layout-backend-types, -body.layout-commands-env, -body.layout-commands-state, -body.layout-alicloud, -body.layout-archive, -body.layout-arukas, -body.layout-atlas, -body.layout-aws, -body.layout-azure, -body.layout-bitbucket, -body.layout-chef, -body.layout-azurerm, -body.layout-circonus, -body.layout-clc, -body.layout-cloudflare, -body.layout-cloudstack, -body.layout-cobbler, -body.layout-consul, -body.layout-datadog, -body.layout-digitalocean, -body.layout-dme, -body.layout-dns, -body.layout-dnsimple, -body.layout-docker, -body.layout-dyn, -body.layout-external, -body.layout-github, -body.layout-grafana, -body.layout-fastly, -body.layout-google, -body.layout-heroku, -body.layout-ignition, -body.layout-icinga2, -body.layout-influxdb, -body.layout-kubernetes, -body.layout-librato, -body.layout-logentries, -body.layout-mailgun, -body.layout-mysql, -body.layout-newrelic, -body.layout-nomad, -body.layout-ns1, -body.layout-openstack, -body.layout-opsgenie, -body.layout-packet, -body.layout-pagerduty, -body.layout-postgresql, -body.layout-powerdns, -body.layout-profitbricks, -body.layout-rabbitmq, -body.layout-rancher, -body.layout-random, -body.layout-rundeck, -body.layout-scaleway, -body.layout-spotinst, -body.layout-statuscake, -body.layout-softlayer, -body.layout-template, -body.layout-tls, -body.layout-ultradns, -body.layout-triton, -body.layout-vault, -body.layout-vcd, -body.layout-vsphere, -body.layout-docs, -body.layout-downloads, -body.layout-inner, -body.layout-remotestate, -body.layout-terraform, -body.layout-intro{ - background: $light-black image-url('sidebar-wire.png') left 62px no-repeat; - - >.container{ - .col-md-8[role=main]{ - min-height: 800px; - background-color: white; - - >div{ - position: relative; - z-index: 10; - } - } - } -} - -.docs-sidebar{ - position: relative; - z-index: 20; +#docs-sidebar { margin-bottom: 30px; - margin-top: 50px; - margin-right: 4%; + margin-top: 50px; + overflow: hidden; - a{ - color: $purple; - } - - .docs-sidenav{ - padding-top: 15px; - padding-bottom: 15px; - font-family: $font-family-klavika; - font-size: 16px; - - :last-child{ - border-bottom: none; - } - - //all li > a - li{ - position: relative; - - > a{ - color: white; - @include transition( color 0.5s ease ); - } - - > a:hover, - > a:focus { - background-color: transparent !important; - color: white; - @include transition( color 0.5s ease ); - } - } - - - > li { - padding: 10px 0; - - >.nav{ - li{ - a{ - font-family: $font-family-open-sans; - color: white; - } - } - } - - &.active { - >a{ - color: lighten($purple, 4%); - font-weight: 600; - } - - &:before{ - content: ''; - position: absolute; - width: 6px; - height: 8px; - background-color: $purple; - font-weight: 500; - @include skewY(24deg); - top: 26px; - left: -10px; - } - > a{ - -webkit-font-smoothing: antialiased; - } - - .nav { - display: block; - - li.active a { - color: lighten($purple, 4%); - font-weight: 500; - } - } - } - - > a { - text-transform: uppercase; - letter-spacing: 1px; - -webkit-font-smoothing: antialiased; - } - } - - .nav { - display: none; - margin-bottom: 15px; - - > li{ - margin-left: 20px; - - > a{ - -webkit-font-smoothing: antialiased; - padding: 6px 15px; - } - } - } - - .nav-visible { - display: block; - } - } -} - -.bs-docs-section{ - @media(max-width: 767px){ - padding: 10px 5px 80px 5px; - } - @media(min-width: 768px){ - padding: 10px 20px 80px 20px; - } - - .lead{ - margin-bottom: 48px - } - - .doc-sectional{ - margin-bottom: 48px; - } - - p, li, .alert { - font-size: 18px; - line-height: 1.5; - margin: 0 0 18px; - -webkit-font-smoothing: antialiased; - } - - pre{ - margin: 0 0 18px; - } - - a{ - color: $purple; - &:hover{ - text-decoration: underline; - } - } - - img{ - max-width: 650px; - margin-top: 25px; - margin-bottom: 25px; - } - - h1{ - margin-top: 72px; - color: $purple; - font-weight: 400; - text-transform: uppercase; - letter-spacing: -1px; - word-wrap: break-word; - } - - h2, h3, h4{ - margin-top: 48px; - font-family: $font-family-open-sans; - text-transform: none; - } - - h2 { - margin-bottom: 16px; - padding-bottom: 10px; - border-bottom: 1px solid #eeeeee; - } - - p { - color: $light-black; - } - - #graph { + h1, + h2, + h3, + h4, + h5, + h6 { margin-top: 30px; } -} -@media (max-width: 992px) { - body.layout-docs, - body.layout-inner, - body.layout-intro{ - >.container{ - .col-md-8[role=main]{ - min-height: 0; - &::before { - border-left: 9999px solid white; - } - } - } - } + ul.nav.docs-sidenav { + display: block; + padding-bottom: 15px; - body.page-sub{ - >.container{ - background-color: white; - } - } + li { + a { + color: $sidebar-link-color; + font-size: $sidebar-font-size; + padding: 10px 0 10px 15px; - .docs-sidebar{ - margin-top: 0px; - margin-bottom: 0px; + &:before { + color: $sidebar-link-color-active; + content: '\203A'; + font-size: $font-size; + left: 0; + line-height: 100%; + opacity: 0.4; + position: absolute; - .docs-sidenav{ - padding-bottom: 0; - - //all li > a - li{ - > a{ - color: black; - @include transition( color 0.5s ease ); + height: 100%; + width: 8px } - > a:hover, - > a:focus { - color: $purple; - @include transition( color 0.5s ease ); + &:focus, + &:hover { + background-color: transparent; + color: $sidebar-link-color-hover; + + &:before { + opacity: 1; + } } - } - - > li { - >.nav{ - li{ - a{ - color: black; - - &:hover{ - color: $purple; - } - } + &.back { + &:before { + content: '\2039'; } } } - } - } - .bs-docs-section{ - h1{ - font-size: 32px; - padding-top: 24px; - border-top: 1px solid #eeeeee; + // For forcing sub-navs to appear - in the long term, this should not + // be a thing anymore... + > ul.nav-visible { + display: block; + } } - h2 { - font-size: 24px; - } + li.active { + > a { + color: $sidebar-link-color-active; - h2, h3, h4{ - margin-top: 32px; - } - - p, li, .alert { - font-size: 16px; - } - } -} - -@media (max-width: 480px) { - .bs-docs-section{ - img{ - max-width: 450px; + &:before { + opacity: 1; } + } - h1{ - font-size: 28px; - } - } + // Open nested navigations + > ul.nav { + display: block; + } + } + + // subnav + ul.nav { + display: none; + margin: 10px; + + li { + margin-left: 10px; + + a { + padding: 6px 15px; + } + } + } + } } diff --git a/website/source/assets/stylesheets/_downloads.scss b/website/source/assets/stylesheets/_downloads.scss index be2187eaf..97a4dfc66 100644 --- a/website/source/assets/stylesheets/_downloads.scss +++ b/website/source/assets/stylesheets/_downloads.scss @@ -1,59 +1,60 @@ -.downloads { - margin-top: 20px; +body.layout-downloads { + #inner { + .downloads { + margin-top: 20px; - .description { + .description { margin-bottom: 20px; - } + } - .download { + .download { + align-items: center; border-bottom: 1px solid #b2b2b2; - padding-bottom: 15px; - margin-top: 10px; - margin-bottom: 10px; + display: flex; + padding: 15px; .details { - padding-left: 95px; + padding-left: 20px; - h2 { - margin-top: 30px; + h2 { + margin-top: 4px; + border: none; + } + + ul { + padding-left: 0px; + margin: -8px 0 0 0; + } + + li { + display: inline-block; + + &:after { + content: " | "; } - ul { - padding-left: 0px; - } - - li { - display: inline-block; - - &:after { - content: " | "; - } - - &:last-child:after { - content: ""; - } + &:last-child:after { + content: ""; } + } } .icon { - img { - width: 75px; - } + svg { + width: 75px; + } } .os-name { - font-size: 40px; - margin-bottom: -3px; + font-size: 40px; + margin-bottom: -3px; } - } + } - .poweredby { + .poweredby { margin-top: 20px; - - img { - display: block; - margin: 0 auto; - width: 122px; - } + text-align: center; + } } + } } diff --git a/website/source/assets/stylesheets/_footer.scss b/website/source/assets/stylesheets/_footer.scss index 2bf21204f..ae34a057a 100644 --- a/website/source/assets/stylesheets/_footer.scss +++ b/website/source/assets/stylesheets/_footer.scss @@ -1,98 +1,22 @@ -body.page-sub{ - #footer{ - padding: 40px 0; - margin-top: 0; +#footer { + padding-top: 50px; - .hashicorp-project{ - margin-top: 24px; - &:hover{ - svg{ - .svg-bg-line{ - opacity: .4; - } + ul.footer-links { + li { + a { + color: $footer-link-color; + font-size: $footer-font-size; + font-family: $font-family-open-sans; + text-decoration: none; + + &:hover, &:focus, &:active { + background-color: transparent; + color: $footer-link-color-hover; + outline: 0; } - } - } - } -} -#footer{ - background-color: white; - padding: 150px 0 80px; - margin-top: -40px; - - &.white{ - background-color: $black; - .footer-links{ - li > a { - @include project-footer-a-subpage-style(); - } - } - } - - .footer-links{ - li > a { - @include project-footer-a-style(); - } - } - - .hashicorp-project{ - margin-top: 24px; - } - - .pull-right{ - padding-right: 15px; - } -} - -.edit-page-link{ - position: absolute; - top: -70px; - right: 30px; - z-index: 9999; - - a{ - text-transform: uppercase; - color: $black; - font-size: 13px; - } -} - -@media (max-width: 992px) { - .footer-links { - display: block; - text-align: center; - - ul{ - display: inline-block;; - float: none !important; - } - - .footer-hashi{ - display: block; - float: none !important; - } - } -} - -@media (max-width: 414px) { - #footer{ - ul{ - display: block; - li{ - display: block; - float: none; - } - - &.external-links{ - li{ - svg{ - position: relative; - left: 0; - top: 2px; - margin-top: 0; - margin-right: 4px; - } + @media (max-width: 992px) { + text-align: center; } } } diff --git a/website/source/assets/stylesheets/_global.scss b/website/source/assets/stylesheets/_global.scss index f30bbff6d..3b69c05dd 100755 --- a/website/source/assets/stylesheets/_global.scss +++ b/website/source/assets/stylesheets/_global.scss @@ -1,117 +1,35 @@ -// -// Global Site -// -------------------------------------------------- - -/*html{ +html { + height: 100%; + min-height: 100%; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -}*/ +} body { - // -webkit-font-smoothing: subpixel-antialiased; - color: $black; - font-size: 15px; - font-family: $font-family-open-sans; - font-weight: 500; + -webkit-font-smoothing: antialiased; + color: $body-font-color; + background-color: $white; + font-size: $font-size; + font-family: $font-family-open-sans; + font-weight: $font-weight-reg; + height: 100%; + min-height: 100%; } h1, h2, h3, h4, h5 { - -webkit-font-smoothing: antialiased; - font-family: $font-family-klavika; - font-weight: 600; -} -h1{ - font-size: 42px; - line-height: 40px; - margin-bottom: 24px; - text-transform: uppercase; + font-family: $font-family-klavika; + -webkit-font-smoothing: antialiased; } -h2{ - font-size: 34px; - text-transform: uppercase; +h1 { + margin-bottom: 24px; } -h3{ - font-size: 20px; - line-height: 20px; - text-transform: uppercase; -} - -h4 { - font-size: 18px; -} - -p { - margin-bottom: 30px; - font-size: 16px; - font-weight: regular; - line-height: 1.5; -} - -p.lead{ - font-size: 21px; - font-weight: 400 !important; -} - -//an alternative color for buttons in the doc body -.btn-serf{ - color: $white !important; - background-color: $btn-color; - border-radius: $btn-border-radius; - //@include box-shadow( $shadow ); -} - -.highlight{ - margin-bottom: 18px; -} - -pre { - background-color: $black; - color: $white; - font-size: 14px; - font-weight: normal; - font-family: "Courier New", Monaco, Menlo, Consolas, monospace; - border: none; - padding: 20px; - margin-bottom: 0; -} - -// Typekit utilites to hide FOUC +// Avoid FOUT .wf-loading { visibility: hidden; } + .wf-active, .wf-inactive { visibility: visible; } - - -//fixed grid below 992 to prevent smaller responsive sizes -@media (max-width: 992px) { - .container{ - max-width: 970px; - } -} - -//all below styles are overriding corrections for below (min-width: 992px) -//below (min-width: 992px) these styles change -.navbar-nav { - margin: 0; -} - -.navbar-right { - float: right !important; -} - -.navbar-nav > li { - float: left; -} - -.navbar-nav > li > a { - padding-top: 15px; - padding-bottom: 15px; -} - -.center { - text-align: center; -} diff --git a/website/source/assets/stylesheets/_header.scss b/website/source/assets/stylesheets/_header.scss index 310664235..dde70d7d6 100755 --- a/website/source/assets/stylesheets/_header.scss +++ b/website/source/assets/stylesheets/_header.scss @@ -1,57 +1,78 @@ -// -// Header -// - Project Specific -// - edits should be made here -// -------------------------------------------------- - -body.page-sub{ - #header{ - background-color: $purple; - } -} - #header { - .navbar-brand { - .logo{ - width: $project-logo-width; - height: $project-logo-height; - font-size: 0px; - font-family: $font-family-klavika; - background: image-url('logo-header.svg') 0 32% no-repeat; + background: $header-background-color; - &:hover{ - opacity: .6; + .navbar-toggle { + height: $header-height; + margin: 0; + padding-right: 15px; + border-radius: 0; + + .icon-bar { + border: 1px solid $white; + border-radius: 0; + } + } + + .navbar-brand { + display: block; + margin: 0; + padding: 0; + + a { + display: flex; + align-items: center; + height: $header-height; + line-height: $header-height; + + svg.logo { + transition: opacity 0.15s ease-in-out; + @extend svg.logo.white; + + &:hover, &:focus, &:active { + opacity: 0.6; + outline: 0; + text-decoration: none; + } } } + } - .by-hashicorp{ - margin-top: 2px; - &:hover{ - svg{ - .svg-bg-line{ - opacity: .4; + ul.nav { + li { + a { + color: $header-link-color; + font-size: $header-font-size; + font-family: $font-family-open-sans; + font-weight: $font-weight-bold; + height: $header-height; + line-height: $header-height; + padding: 0 10px; + margin: 0; + text-decoration: none; + + &:hover, &:focus, &:active { + background-color: transparent; + color: $header-link-color-hover; + outline: 0; + + svg { + fill: $header-link-color-hover; } } - } - } - } - .buttons{ - margin-top: 2px; //baseline everything - - ul.navbar-nav{ - li { - svg path{ - fill: $white; + svg { + fill: $header-link-color; + position: relative; + top: 2px; + width: 14px; + height: 14px; + margin-right: 3px; } } } } - .main-links, - .external-links { - li > a { - @include project-a-style(); - } + .buttons { + margin-top: 2px; } } diff --git a/website/source/assets/stylesheets/_home.scss b/website/source/assets/stylesheets/_home.scss old mode 100755 new mode 100644 index 807a8b542..95da9ec34 --- a/website/source/assets/stylesheets/_home.scss +++ b/website/source/assets/stylesheets/_home.scss @@ -1,823 +1,326 @@ -// -// Home -// -------------------------------------------------- - -body.page-home { - h2.tag-line { - font-size: 40px; - } - - #primary-cta{ - position: relative; - margin-top: -30px; - padding-bottom: 40px; - color: $white; - background: $black; - z-index: 99; - - .terra-btn{ - margin-top: 30px; - } - } - - .temp-skew { - position: relative; - height: 240px; - background-color: #000; - @include skewY(-3deg); - margin-top: -100px; - -webkit-backface-visibility: hidden; - border: 2px solid #000; - z-index: 0; - } - - .announcement { - margin-top: 60px; - border: 1px solid rgba(255,255,255,.3); - padding: 25px 10px; - - p { - color: $gray; - line-height: 1.2; - margin-bottom: 0; - - a { - color: $purple; - text-decoration: underline; - // inline-block ensures links doesn't text-wrap; - display: inline-block; - } - } - } - - #customer-logos{ - position: relative; - width: 100%; - margin-top: -100px; - padding: 60px 0; - color: $white; - - >.container { - z-index: 91; - } - - p { - text-transform: uppercase; - letter-spacing: 2px; - } - - #customer-logos-bg{ - z-index: 30; - background: $black; - background-size: 100%; - @include skewY(-3deg); - } - } - - ul.customer-list{ - padding-left: 15px; - - li{ - display: inline-block; - width: 16%; - height: 80px; - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - } - - #nike { - background: transparent image-url("customer-logos/nike.svg") left no-repeat; - background-size: 80px; - } - - #hbo { - background: transparent image-url("customer-logos/hbo.svg") left no-repeat; - background-size: 80px; - } - - #target { - background: transparent image-url("customer-logos/target.svg") left no-repeat; - background-size: 50px; - } - - #capital-one { - background: transparent image-url("customer-logos/capital-one.svg") left no-repeat; - background-size: 100px; - } - - #home-depot { - background: transparent image-url("customer-logos/home-depot.svg") left no-repeat; - background-size: 50px; - } - - #hotels-dot-com { - background: transparent image-url("customer-logos/hotels-dot-com.svg") left no-repeat; - background-size: 100px; - } - } - - #feature-overview{ - position: relative; - padding: 120px 0; - border-bottom: 2px solid #E6E7E8; - z-index: 80; - } - - .feature-card{ - display: block; - height: 200px; - border: 2px solid #E6E7E8; - margin-bottom: 15px; - padding:20px; - font-size: 18px; - - h3{ - margin:0; - padding: 0; - color: $purple; - font-size: 16px; - line-height: 1.2; - font-weight: 400; - text-transform: uppercase; - } - - p{ - color: #000; - font-size: 16px; - line-height: 1.2; - font-weight: 400; - text-transform: uppercase; - letter-spacing: 1px; - } - - &.feature-card-write{ - background: image-url("feature-card-write.svg") left 20px top 70% no-repeat; - background-size: 80%; - } - - &.feature-card-plan{ - background: image-url("feature-card-plan.svg") left 0 top 69% no-repeat; - background-size: 100%; - } - - &.feature-card-create{ - background: image-url("feature-card-create.svg") left 0 top 70% no-repeat; - background-size: 80%; - } - - &:hover { - border: 2px solid $purple; - text-decoration: none; - } - } - - .feature{ - - p.lead{ - max-width: 30em; - } - } - - .skew-item{ - >.container{ - position: relative; - top: 0; - z-index: 11; - } - - .feature-skew{ - position: absolute; - top: 0px; - bottom: 0px; - left: 0px; - width: 100%; - height: 100%; - } - } - - #feature-write{ - position: relative; - padding: 180px 0 120px; - margin-top: -80px; - - - >.container { - z-index: 71; - } - - // This svg appears twice in the markup and swapped for layout purposes. - // Image for small screens. Styles below are for larger screens. - #feature-image-write-sm-screen { - display: block; - position: relative; - margin: 0 auto; - width:80%; - max-width: 400px; - } - - // Image hidden, made visible for larger screens - #feature-image-write-lg-screen { - display: none; - position: absolute; - bottom: 2px; - right: 3%; - width: 581px; - @include skewY(-3deg); - } - - #feature-write-bg{ - background: $white; - z-index: 70; - @include skewY(3deg); - overflow: hidden; - } - } - - #feature-plan{ - position: relative; - color: $white; - background-size: 80%; - position: relative; - padding: 220px 0 180px; - margin-top: -80px; - - >.container { - z-index: 61; - // background: image-url("feature-plan-bg.svg") 0% 45% no-repeat; - background-size: 100%; - } - - // This svg appears twice in the markup and swapped for layout purposes. - // Image for small screens. Styles below are for larger screens. - #feature-image-plan-sm-screen { - display: block; - position: relative; - margin: 0 auto; - width: 100%; - max-width: 400px; - } - - // Image hidden, made visible for larger screens - #feature-image-plan-lg-screen { - display: none; - position: relative; - width: 100%; - } - - #feature-plan-bg{ - background: $purple; - z-index: 60; - @include skewY(-3deg); - } - } - - #feature-create{ - position: relative; - margin-top: -80px; - padding: 240px 0 180px; - - >.container{ - z-index: 51; - } - - #feature-image-create { - display: block; - max-width: 500px; - padding-left: 10px; - margin: 0 auto; - margin-bottom: 40px; - } - - #feature-image-create-lg-screen{ - display: none; - } - - #feature-create-bg{ - @include skewY(3deg); - - z-index: 50; - overflow: hidden; - } - } - - #demos{ - position: relative; - padding: 120px 0 60px; - margin-top: -80px; - - >.container{ - z-index: 41; - } - - #demo-bg{ - background-color: #E6E7E8; - @include skewY(3deg); - z-index: 40; - } - - h2{ - text-align: center; - } - - p { - margin-bottom: 20px; - } - - .terminals{ - margin-bottom: 80px; - - .terminal-item{ - margin-bottom: 80px; - - &.last{ - border-bottom: none; - } - >header{ - .left{ - span.icn{ - display: inline-block; - width: 83px; - height: 74px; - } - } - - .right{ - padding-left: 25px; - } - } - - .terminal{ - - border: 2px solid #1e1e1e; - background: $black; - //border-radius: 4px; - - header{ - position: relative; - text-align: center; - padding: 3px; - border-bottom: 2px solid #1e1e1e; - - h4{ - font-size: 14px; - letter-spacing: 1px; - color: white; - } - - ul.shell-dots{ - position: absolute; - top: 10px; - left: 8px; - padding-left: 0; - - li{ - &.d1{ - background-color: #4a08a7; - } - &.d2{ - background-color: #6517cf; - } - &.d3{ - background-color: #7b29ee; - } - - display: inline-block; - width: 12px; - height: 12px; - border-radius: 6px; - margin-left: 6px; - } - } - } - - .terminal-window{ - min-height: 140px; - padding: 20px; - font-size: 15px; - color: $white; - background-color: transparent; - overflow:auto; - font-weight: 500; - -webkit-font-smoothing: subpixel-antialiased; - - p { - font-family: "Courier New", Monaco, Menlo, Consolas, monospace; - } - - .txt-spe { - color: lighten($blue, 5%); - font-weight: 600; - } - - .txt-var { - color: lighten($purple, 8%); - font-weight: 600; - } - - .txt-str { - color: lighten($green, 2%); - } - - .txt-int { - color: lighten($orange, 2%); - font-weight: 600; - } - - p{ - margin-bottom: 2px; - white-space: pre-wrap; - } - .cursor { - background-color: lighten($purple, 5%); - } - } - } - - .feature-bullets{ - list-style-type: none; - padding-left: 35px; - - li{ - padding: 5px 0 5px 45px; - } - } - } - } - } - - #demo-cta{ - text-align: center; - } - - #latest-announcement{ - position: relative; - margin-top: -80px; - padding: 160px 0 200px; - color: $white; - text-align: left; - - >.container{ - z-index: 51; - } - - h2{ - margin-bottom: 60px; - } - - .latest-col-right{ - position: relative; - padding-left: 60px; - - &:after{ - content: ''; - position: absolute; - left: 30px; - top: 0; - width: 2px; - height: 100%; - background-color: rgba(255, 255, 255, .15); +#page-home { + // Override the main header + #header { + background: $home-header-background-color; + + .navbar-toggle { + .icon-bar { + border: 1px solid $home-header-link-color; } } - .latest-item{ - &.latest-item-text{ - border-bottom: 2px solid rgba(255, 255, 255, .15); + .navbar-brand { + a { + svg.logo { + @extend svg.logo.color; + } + } + } - &:first-child{ - h3{ - margin-top: 0; + ul.nav { + li { + a { + color: $home-header-link-color; + + &:hover, &:focus, &:active { + background-color: transparent; + color: $home-header-link-color-hover; + + svg { + fill: $home-header-link-color-hover; + } + } + + svg { + fill: $home-header-link-color; + } + } + } + } + } + + header { + .hero { + margin: 140px auto 160px auto; + text-align: center; + + .button { + margin: 5px; + + @media (max-width: 768px) { + display: block; + margin-top: 10px; + text-align: center; + } + } + + svg { + max-width: 90%; + } + } + } + + section { + background: $white; + padding: 100px 0; + } + + section.marketing { + h2 { + font-family: $font-family-klavika; + font-size: 36px; + font-weight: $font-weight-bold; + line-height: 1.25; + letter-spacing: -0.02em; + margin: 20px 0 10px 0; + padding: 0; + text-transform: uppercase; + } + + h3 { + color: $black; + font-size: 20px; + font-weight: $font-weight-bold; + line-height: 1.2; + margin: 50px 0 15px 0; + text-transform: uppercase; + } + + p { + font-family: $font-family-open-sans; + font-size: 16px; + letter-spacing: 0.01em; + line-height: 1.5; + margin: 0 0 10px; + } + + p.lead { + font-size: 20px; + margin: 15px 0 30px 0; + } + + span.callout { + background: $black; + color: $white; + display: inline-block; + font-family: $font-family-klavika; + font-size: 18px; + font-weight: $font-weight-bold; + line-height: 1; + margin: 0; + padding: 5px; + letter-spacing: 0.05em; + text-transform: uppercase; + } + + &.purple { + background: $terraform-purple; + + h2 { + color: $white; + } + + p { + color: $white; + } + + span.callout { + background: $white; + color: $terraform-purple; + } + + .button { + border: none; + } + } + + &.black { + background: $black; + + h2 { + color: $white; + } + + p { + color: $white; + } + + span.callout { + background: $white; + color: $black; + } + + .button { + border: none; + } + } + + &#features { + .feature-card { + border: 1px solid $gray-darker; + color: $gray-darker; + display: block; + height: 200px; + font-weight: $font-weight-bold; + padding: 20px; + margin-bottom: 15px; + text-transform: uppercase; + transition: all 0.1s ease-in-out; + + p { + line-height: 1.25em; + } + + span { + color: $terraform-purple; + display: block; + font-weight: $font-weight-bold; + margin-bottom: 10px; + } + + svg { + display: block; + margin-top: 20px; + max-width: 100%; + + path { + transition: all 0.1s ease-in-out; + fill: $gray-dark; } } - &:last-child{ - border-bottom: none; - } - } + &:hover, &:active, &:focus { + border: 1px solid $terraform-purple; + color: $terraform-purple; + text-decoration: none; - img{ - box-shadow: 8px 8px 8px rgba(0,0,0,.25); - margin-bottom: 10px; - max-width: 100%; - } - - h3{ - line-height: 1.2; - font-family: $font-family-open-sans; - text-transform: none; - } - - p{ - margin-bottom: 10px; - } - - a{ - margin-top: 5px; - margin-bottom: 10px; - } - } - } - - #latest-announcement-bg{ - @include skewY(-3deg); - z-index: 30; - background: $purple image-url("latest-announce-bg.svg") bottom left no-repeat; - background-size: cover; - } - - #enterprise-intro{ - position: relative; - padding: 220px 0 180px; - margin-top: -80px; - color: #fff; - - >.container{ - z-index: 31; - } - - h2{ - position: relative; - left: -5px; - margin-bottom: 20px; - background: image-url("terraform-enterprise-logo.svg") top left no-repeat; - background-size: 320px; - overflow: hidden; - - span {margin-left: -200%} - } - - .lead{ - max-width: 30em; - margin-bottom: 40px; - } - - #enterprise-intro-bg{ - background: #000 image-url("enterprise-callout-bg.svg") bottom right no-repeat; - background-size: 80%; - @include skewY(3deg); - z-index: 20; - } - } - - @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { - #demos{ - .terminals{ - .terminal-item{ - .feature-bullets{ - li{ - background-size: 12px 12px; - } - } - } - } - } - } - - @media (min-width: 768px) { - #feature-write{ - // Hide image for small screens - #feature-image-write-sm-screen { - display: none; - } - - // Image hidden, made visible for larger screens - #feature-image-write-lg-screen { - display: block; - } - } - - #feature-plan{ - // Hide image for small screens - #feature-image-plan-sm-screen { - display: none; - } - - // Image hidden, made visible for larger screens - #feature-image-plan-lg-screen { - display: block; - } - } - } - - @media (min-width: 1024px) { - #feature-write{ - #feature-image-write-lg-screen { - right: 10%; - width: 640px; - } - } - } - - @media (min-width: 1440px) { - - #feature-write{ - padding: 280px 0 200px; - margin-top: -120px; - } - - #feature-plan{ - padding: 320px 0 200px; - margin-top: -120px; - } - - #feature-create{ - padding: 320px 0 200px; - margin-top: -120px; - } - - #latest-announcement{ - margin-top: -140px; - padding: 180px 0 240px; - } - - #enterprise-intro{ - margin-top: -140px; - padding: 320px 0 180px; - } - } - - @media (max-width: 992px) { - - #demos{ - .terminals{ - .terminal-item{ - >header{ - .left{ - span.icn{ - } - } - - .right{ - padding-left: 54px; - } - } - } - } - } - - #latest-announcement{ - .latest-col-left{ - .latest-item{ - border-bottom: 2px solid rgba(255, 255, 255, .15); - } - } - - .latest-col-right{ - padding-left: 15px; - - &:after{ - width: 0; - } - } - - .latest-item{ - padding-bottom: 30px; - margin-bottom: 30px; - - &.latest-item-text{ - border-bottom: 2px solid rgba(255, 255, 255, .15); - - &:first-child{ - h3{ - margin-top: 20px; + svg { + path { + fill: $terraform-purple; + transition: all 0.1s ease-in-out; } } } } } - } - @media (max-width: 768px) { - h2{ - margin-bottom: 40px; - font-size: 28px; - line-height: 32px; - letter-spacing: 2px; - text-transform: uppercase; - font-weight: regular; - } + &#plan { + h3 { + color: $white; + } + } - h3{ - margin-bottom: 10px; - font-size: 16px; - line-height: 1.2; - letter-spacing: 1px; - text-transform: uppercase; - font-weight: bold; - } + &#news { + img { + box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.25); + margin: 0 0 20px 0; + } - p{ - font-size: 14px; - } + h2 { + margin-bottom: 50px; + } - p.lead{ - font-size: 17px; - } + h3 { + color: $white; + margin-top: 0; + text-transform: none; + } - #primary-cta{ - padding-bottom: 100px; - } + div.latest-item { + border-bottom: 1px solid rgba(255, 255, 255, 0.5); + margin-bottom: 20px; + padding-bottom: 20px; - #customer-logos{ - padding: 40px 0; + &:last-child { + border: none; + margin-bottom: 0; + padding-bottom: 0; + } - p { - display: block; - position: relative; - width: 100%; - text-align: center; - } + p { + padding: 0 0 10px 0; + } - #customer-logos-bg{ - z-index: 30; - background: $black; - background-size: 100%; - @include skewY(-3deg); + .button { + &:hover { + background: $white; + color: $terraform-purple; + } + } + } + } - } + &#examples { + background: #EDEDED; - ul.customer-list{ - padding-left: 15px; + h1, h2, h3, h4, h5, h6, p { + color: $black; + } + } - li{ - display: inline-block; - width: 16%; - height: 80px; - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - } + &#enterprise { + background-image: image-url('enterprise-callout-bg.svg'); + background-position: right bottom; + background-repeat: no-repeat; + background-size: 80%; + } + } - #nike { - background: transparent image-url("customer-logos/nike.svg") left no-repeat; - background-size: 40px; - } + .terminal { + border: 1px solid $white; + background-color: $black; + box-sizing: border-box; + color: $white; + font-family: $font-family-monospace; + font-size: 16px; + line-height: 1.8; + margin: 20px auto; + padding: 10px 20px 20px 20px; - #hbo { - background: transparent image-url("customer-logos/hbo.svg") left no-repeat; - background-size: 40px; - } + .terminal-content { + margin-top: 15px; + overflow-x: scroll; + width: 100%; + white-space: nowrap; - #target { - background: transparent image-url("customer-logos/target.svg") left no-repeat; - background-size: 30px; - } + span { + display: block; + white-space: pre; - #capital-one { - background: transparent image-url("customer-logos/capital-one.svg") left no-repeat; - background-size: 40px; - } + span { + display: inline; + } - #home-depot { - background: transparent image-url("customer-logos/home-depot.svg") left no-repeat; - background-size: 30px; - } + &.text-pink { + color: lighten($consul-pink, 20%); + } + } + } - #hotels-dot-com { - background: transparent image-url("customer-logos/hotels-dot-com.svg") left no-repeat; - background-size: 40px; - } - } + span.circle { + &:before { + content: '\25CF'; + color: $white; + font-size: 28px; + line-height: 100%; + height: 100%; + } + } - ul.customer-list{ - display: block; - position: relative; - width: 100%; - margin: 0 auto; - padding: 0; - text-align: center; + span.txt-spe { + color: #7190EA; + } - li{ - display: inline-block; - position: relative; - width: 40px; - height: 40px; - margin: 0 2%; - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - } - } - } + span.txt-str { + color: #64E86C; + } + span.txt-int { + color: #E89264; + } - #demos{ - - .terminals{ - .terminal-item{ - >header{ - .left{ - span.icn{ - padding-bottom: 15px; - } - } - - .right{ - padding-left: 15px; - } - } - } - } - } - } + span.txt-var { + color: #9A56f9; + } + } } diff --git a/website/source/assets/stylesheets/_inner.scss b/website/source/assets/stylesheets/_inner.scss new file mode 100644 index 000000000..1fd41e3f3 --- /dev/null +++ b/website/source/assets/stylesheets/_inner.scss @@ -0,0 +1,95 @@ +#inner { + p, li, .alert { + font-size: $font-size; + font-family: $font-family-open-sans; + font-weight: $font-weight-reg; + line-height: 1.84em; + margin: 0 0 $font-size; + -webkit-font-smoothing: antialiased; + } + + .alert p:last-child { + margin-bottom: 0; + } + + pre, + code, + pre code, + tt { + font-family: $font-family-monospace; + font-size: $font-size - 2; + line-height: 1.6; + } + + pre { + padding: 20px; + margin: 0 0 $font-size; + + // This will force the code to scroll horizontally on small screens + // instead of wrapping. + code { + overflow-wrap: normal; + white-space: pre; + } + } + + a { + color: $body-link-color; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + code { + background: inherit; + color: $body-link-color; + } + } + + img { + display: block; + margin: 25px auto; + max-width: 650px; + height: auto; + width: 90%; + } + + h1, + h2, + h3, + h4 { + color: $body-font-color; + margin-top: 54px; + margin-bottom: $font-size; + line-height: 1.3; + } + + h2 { + padding-bottom: 3px; + border-bottom: 1px solid $gray-light; + } + + h1 > code, + h2 > code, + h3 > code, + h4 > code, + h5 > code + h6 > code, + li code, + table code, + p code, + tt, + .alert code { + font-family: $font-family-monospace; + font-size: 90%; + background-color: transparent; + color: inherit; + padding: 0; + } + + table { + @extend .table; + @extend .table-striped; + } +} diff --git a/website/source/assets/stylesheets/_jumbotron.scss b/website/source/assets/stylesheets/_jumbotron.scss deleted file mode 100755 index 52ae80a0f..000000000 --- a/website/source/assets/stylesheets/_jumbotron.scss +++ /dev/null @@ -1,439 +0,0 @@ -// -// Jumbotron -// -------------------------------------------------- - -#jumbotron-mask{ - position:relative; - z-index:0; - height:700px; - margin-top: $negative-hero-margin; - background-color: black; -} - -#jumbotron { - position: relative; - height:700px; - padding-top: 0; - padding-bottom: 0; - color: $jumbotron-color; - - &.static { - background-image:image-url("bg-galaxy.jpg"); - background-position:50% 50%; - background-repeat:no-repeat; - - .jumbotron-content { - background-image:image-url("bg-static.png"); - background-size:cover; - background-position:50% 50%; - background-repeat:no-repeat; - } - - .jumbotron-content:after { - content:''; - display:block; - position:absolute; - top:50%; - left:50%; - background:image-url("logo-static.png"); - - -webkit-background-size:100% 100%; - -moz-background-size:100% 100%; - -ms-background-size:100% 100%; - -o-background-size:100% 100%; - background-size:100% 100%; - - width:360px; - height:360px; - margin:-204px 0 0 -180px; - } - } - - .terraform-canvas { - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - opacity:0; - - -webkit-transition:opacity 2s ease-out; - -moz-transition:opacity 2s ease-out; - -ms-transition:opacity 2s ease-out; - -o-transition:opacity 2s ease-out; - transition:opacity 2s ease-out; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); - } - - .jumbotron-content { - position:absolute; - z-index:999; - top:0; - left:0; - right:0; - bottom:0; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); - } - - .galaxy-bg { - position:absolute; - width:100%; - height:100%; - top:0; - left:0; - - background-image:image-url("bg-galaxy.jpg"); - /* background-size:cover; */ - background-position:50% 50%; - background-repeat: no-repeat; - opacity:0; - - -webkit-transition:opacity 2s ease-out; - -moz-transition:opacity 2s ease-out; - -ms-transition:opacity 2s ease-out; - -o-transition:opacity 2s ease-out; - transition:opacity 2s ease-out; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); - - &.show { - opacity:1; - } - } -} - -.tag-line { - position:absolute; - width:100%; - top:540px; - color:#fff; - visibility:hidden; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); -} - - -.animated-logo { - position:absolute; - z-index:200; - top:50%; - left:50%; - width:140px; - height:140px; - margin:-60px 0 0 -115px; - opacity:1; - - -webkit-transition:-webkit-transform 300ms ease-in-out; - -moz-transition: -moz-transform 300ms ease-in-out; - -ms-transition: -ms-transform 300ms ease-in-out; - -o-transition: -o-transform 300ms ease-in-out; - transition: transform 300ms ease-in-out; - - -webkit-transform-origin:50% 50%; - -moz-transform-origin:50% 50%; - -ms-transform-origin:50% 50%; - -o-transform-origin:50% 50%; - transform-origin:50% 50%; - - -webkit-transform-style:preserve-3d; - -moz-transform-style:preserve-3d; - -ms-transform-style:preserve-3d; - -o-transform-style:preserve-3d; - transform-style:preserve-3d; - - -webkit-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -moz-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -ms-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -o-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); -} - -.state-one .animated-logo { - -webkit-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -moz-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -ms-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - -o-transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); - transform:translate3d(0,0,0) rotateY(0deg) skewY(0deg) scale(1,1); -} - -.state-one.state-two.state-three.state-four .animated-logo { - -webkit-transform-origin:100% 0; - -moz-transform-origin:100% 0; - -ms-transform-origin:100% 0; - -o-transform-origin:100% 0; - transform-origin:100% 0; - - -webkit-transform:translate3d(0,10px,0) rotateY(-45deg) skewY(22deg) scale(1.26,1); - -moz-transform:translate3d(0,10px,0) rotateY(-45deg) skewY(22deg) scale(1.26,1); - -ms-transform:translate3d(0,10px,0) rotateY(-45deg) skewY(22deg) scale(1.26,1); - -o-transform:translate3d(0,10px,0) rotateY(-45deg) skewY(22deg) scale(1.26,1); - transform:translate3d(0,10px,0) rotateY(-45deg) skewY(22deg) scale(1.26,1); -} - -.state-one.state-two.state-three.state-four .white-block { - background-color:rgba(255,255,255,1); -} - -.white-block { - position:absolute; - width:68px; - height:68px; - - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - - /* background-color:rgba(255,0,0,0.3); */ - background-color:#fff; - background-color:rgba(255,255,255,0); - - border:1px solid #fff; - - -webkit-transition: - opacity 300ms ease-out, - -webkit-transform 300ms ease-out, - background-color 300ms ease-out; - -moz-transition: - opacity 300ms ease-out, - -moz-transform 300ms ease-out, - background-color 300ms ease-out; - -ms-transition: - opacity 300ms ease-out, - -ms-transform 300ms ease-out, - background-color 300ms ease-out; - -o-transition: - opacity 300ms ease-out, - -o-transform 300ms ease-out, - background-color 300ms ease-out; - transition: - opacity 300ms ease-out, - transform 300ms ease-out, - background-color 300ms ease-out; -} - -.block-1, -.block-2, -.block-3, -.block-4 { - top:0; - left:72px; - - -webkit-transform-origin:50% 50%; - -moz-transform-origin:50% 50%; - -ms-transform-origin:50% 50%; - -o-transform-origin:50% 50%; - transform-origin:50% 50%; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); -} - -.block-1 { - opacity:0; - - -webkit-transform:translate3d(0,0,0) scale(0,0); - -moz-transform:translate3d(0,0,0) scale(0,0); - -ms-transform:translate3d(0,0,0) scale(0,0); - -o-transform:translate3d(0,0,0) scale(0,0); - transform:translate3d(0,0,0) scale(0,0); -} - -.block-2 { - opacity:0; - top:0; - left:0; - - -webkit-transform:translate3d(0,0,0) scale(0,0); - -moz-transform:translate3d(0,0,0) scale(0,0); - -ms-transform:translate3d(0,0,0) scale(0,0); - -o-transform:translate3d(0,0,0) scale(0,0); - transform:translate3d(0,0,0) scale(0,0); -} - -.block-3 { - opacity:0; - top:72px; - - -webkit-transform:translate3d(0,0,0) scale(0,0); - -moz-transform:translate3d(0,0,0) scale(0,0); - -ms-transform:translate3d(0,0,0) scale(0,0); - -o-transform:translate3d(0,0,0) scale(0,0); - transform:translate3d(0,0,0) scale(0,0); -} - -.block-4 { - -webkit-transform-origin:0 0; - -moz-transform-origin:0 0; - -ms-transform-origin:0 0; - -o-transform-origin:0 0; - transform-origin:0 0; - - -webkit-transform:translate3d(72px,-2px,0) rotateY(90deg) skewY(-22deg) scaleX(1.25); - -moz-transform:translate3d(72px,-2px,0) rotateY(90deg) skewY(-22deg) scaleX(1.25); - -ms-transform:translate3d(72px,-2px,0) rotateY(90deg) skewY(-22deg) scaleX(1.25); - -o-transform:translate3d(72px,-2px,0) rotateY(90deg) skewY(-22deg) scaleX(1.25); - transform:translate3d(72px,-2px,0) rotateY(90deg) skewY(-22deg) scaleX(1.25); -} - -.state-one.state-two .block-1 { - opacity:1; - - -webkit-transform:translate3d(0,0,0) scale(1,1); - -moz-transform:translate3d(0,0,0) scale(1,1); - -ms-transform:translate3d(0,0,0) scale(1,1); - -o-transform:translate3d(0,0,0) scale(1,1); - transform:translate3d(0,0,0) scale(1,1); -} - -.state-one .block-2 { - opacity:1; - - -webkit-transform:translate3d(0,0,0) scale(1,1); - -moz-transform:translate3d(0,0,0) scale(1,1); - -ms-transform:translate3d(0,0,0) scale(1,1); - -o-transform:translate3d(0,0,0) scale(1,1); - transform:translate3d(0,0,0) scale(1,1); -} - -.state-one.state-two.state-three .block-3 { - opacity:1; - - -webkit-transform:translate3d(0,0,0) scale(1,1); - -moz-transform:translate3d(0,0,0) scale(1,1); - -ms-transform:translate3d(0,0,0) scale(1,1); - -o-transform:translate3d(0,0,0) scale(1,1); - transform:translate3d(0,0,0) scale(1,1); -} - -.cursor { - font-weight:bold; - - -webkit-animation:Blink 800ms infinite; - -moz-animation:Blink 800ms infinite; - -ms-animation:Blink 800ms infinite; - -o-animation:Blink 800ms infinite; - animation:Blink 800ms infinite; -} - -@-webkit-keyframes Blink { - 0% { - opacity:1; - } - 50% { - opacity:1; - - } - 51% { - opacity:0; - } - 100% { - opacity:0; - } -} - -@-moz-keyframes Blink { - 0% { - opacity:1; - } - 50% { - opacity:1; - } - 51% { - opacity:0; - } - 100% { - opacity:0; - } -} - -@-ms-keyframes Blink { - 0% { - opacity:1; - - } - 50% { - opacity:1; - } - 51% { - opacity:0; - } - 100% { - opacity:0; - } -} - -@-o-keyframes Blink { - 0% { - opacity:1; - - } - 50% { - opacity:1; - } - 51% { - opacity:0; - } - 100% { - opacity:0; - } -} - -@keyframes Blink { - 0% { - opacity:1; - - } - 50% { - opacity:1; - } - 51% { - opacity:0; - } - 100% { - opacity:0; - } -} - -@media (max-width: 570px) { - .tag-line { - display:none; - } - - #jumbotron .jumbotron-content { - -webkit-transform:translate3d(0, 0, 0) scale(0.8); - -moz-transform:translate3d(0, 0, 0) scale(0.8); - -ms-transform:translate3d(0, 0, 0) scale(0.8); - -o-transform:translate3d(0, 0, 0) scale(0.8); - transform:translate3d(0, 0, 0) scale(0.8); - } - - .animated-logo { - margin:-15px 0 0 -113px; - } - - #jumbotron-mask, - #jumbotron { - height:560px; - } -} diff --git a/website/source/assets/stylesheets/_logos.scss b/website/source/assets/stylesheets/_logos.scss new file mode 100644 index 000000000..6e8f39a48 --- /dev/null +++ b/website/source/assets/stylesheets/_logos.scss @@ -0,0 +1,41 @@ +svg.logo { + &.color { + opacity: 1.0; + + path.text { + fill: $black; + opacity: 1.0; + } + + path.rect-light { + fill: $terraform-purple; + opacity: 1.0; + } + + path.rect-dark { + fill: $terraform-purple-dark; + opacity: 1.0; + } + } + + // The default logo class is the colored version + @extend .color; + + &.white { + opacity: 1.0; + + path.text { + fill: $white; + } + + path.rect-light { + fill: $white; + opacity: 1.0; + } + + path.rect-dark { + fill: $white; + opacity: 0.7; + } + } +} diff --git a/website/source/assets/stylesheets/_mixins.scss b/website/source/assets/stylesheets/_mixins.scss deleted file mode 100755 index f49151e3a..000000000 --- a/website/source/assets/stylesheets/_mixins.scss +++ /dev/null @@ -1,724 +0,0 @@ -// -// Mixins -// -------------------------------------------------- - - -// Utilities -// ------------------------- - -// Clearfix -// Source: http://nicolasgallagher.com/micro-clearfix-hack/ -// -// For modern browsers -// 1. The space content is one way to avoid an Opera bug when the -// contenteditable attribute is included anywhere else in the document. -// Otherwise it causes space to appear at the top and bottom of elements -// that are clearfixed. -// 2. The use of `table` rather than `block` is only necessary if using -// `:before` to contain the top-margins of child elements. -@mixin clearfix() { - &:before, - &:after { - content: " "; /* 1 */ - display: table; /* 2 */ - } - &:after { - clear: both; - } -} - -// Webkit-style focus -@mixin tab-focus() { - // Default - outline: thin dotted #333; - // Webkit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -// Center-align a block level element -@mixin center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// Sizing shortcuts -@mixin size($width, $height) { - width: $width; - height: $height; -} -@mixin square($size) { - @include size($size, $size); -} - -// Placeholder text -@mixin placeholder($color: $input-color-placeholder) { - &:-moz-placeholder { color: $color; } // Firefox 4-18 - &::-moz-placeholder { color: $color; } // Firefox 19+ - &:-ms-input-placeholder { color: $color; } // Internet Explorer 10+ - &::-webkit-input-placeholder { color: $color; } // Safari and Chrome -} - -// Text overflow -// Requires inline-block or block for proper styling -@mixin text-overflow() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -// CSS image replacement -// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 -@mixin hide-text() { - font: #{"0/0"} a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - - - -// CSS3 PROPERTIES -// -------------------------------------------------- - -// Single side border-radius -@mixin border-top-radius($radius) { - border-top-right-radius: $radius; - border-top-left-radius: $radius; -} -@mixin border-right-radius($radius) { - border-bottom-right-radius: $radius; - border-top-right-radius: $radius; -} -@mixin border-bottom-radius($radius) { - border-bottom-right-radius: $radius; - border-bottom-left-radius: $radius; -} -@mixin border-left-radius($radius) { - border-bottom-left-radius: $radius; - border-top-left-radius: $radius; -} - -// Drop shadows -@mixin box-shadow($shadow) { - -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1 - box-shadow: $shadow; -} - -// Transitions -@mixin transition($transition) { - -webkit-transition: $transition; - transition: $transition; -} -@mixin transition-delay($transition-delay) { - -webkit-transition-delay: $transition-delay; - transition-delay: $transition-delay; -} -@mixin transition-duration($transition-duration) { - -webkit-transition-duration: $transition-duration; - transition-duration: $transition-duration; -} -@mixin transition-transform($transition) { - -webkit-transition: -webkit-transform $transition; - -moz-transition: -moz-transform $transition; - -o-transition: -o-transform $transition; - transition: transform $transition; -} - -// Transformations -@mixin rotate($degrees) { - -webkit-transform: rotate($degrees); - -ms-transform: rotate($degrees); // IE9+ - transform: rotate($degrees); -} -@mixin scale($ratio) { - -webkit-transform: scale($ratio); - -ms-transform: scale($ratio); // IE9+ - transform: scale($ratio); -} -@mixin translate($x, $y) { - -webkit-transform: translate($x, $y); - -ms-transform: translate($x, $y); // IE9+ - transform: translate($x, $y); -} -@mixin skew($x, $y) { - -webkit-transform: skew($x, $y); - -ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+ - transform: skew($x, $y); -} -@mixin translate3d($x, $y, $z) { - -webkit-transform: translate3d($x, $y, $z); - transform: translate3d($x, $y, $z); -} - -// Backface visibility -// Prevent browsers from flickering when using CSS 3D transforms. -// Default value is `visible`, but can be changed to `hidden` -// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples -@mixin backface-visibility($visibility) { - -webkit-backface-visibility: $visibility; - -moz-backface-visibility: $visibility; - backface-visibility: $visibility; -} - -// Box sizing -@mixin box-sizing($boxmodel) { - -webkit-box-sizing: $boxmodel; - -moz-box-sizing: $boxmodel; - box-sizing: $boxmodel; -} - -// User select -// For selecting text on the page -@mixin user-select($select) { - -webkit-user-select: $select; - -moz-user-select: $select; - -ms-user-select: $select; // IE10+ - -o-user-select: $select; - user-select: $select; -} - -// Resize anything -@mixin resizable($direction) { - resize: $direction; // Options: horizontal, vertical, both - overflow: auto; // Safari fix -} - -// CSS3 Content Columns -@mixin content-columns($column-count, $column-gap: $grid-gutter-width) { - -webkit-column-count: $column-count; - -moz-column-count: $column-count; - column-count: $column-count; - -webkit-column-gap: $column-gap; - -moz-column-gap: $column-gap; - column-gap: $column-gap; -} - -// Optional hyphenation -@mixin hyphens($mode: auto) { - word-wrap: break-word; - -webkit-hyphens: $mode; - -moz-hyphens: $mode; - -ms-hyphens: $mode; // IE10+ - -o-hyphens: $mode; - hyphens: $mode; -} - -// Opacity -@mixin opacity($opacity) { - opacity: $opacity; - // IE8 filter - $opacity-ie: ($opacity * 100); - filter: #{"alpha(opacity=#{opacity-ie})"}; -} - - - -// GRADIENTS -// -------------------------------------------------- - -#gradient { - - // Horizontal gradient, from left to right - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - @mixin horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { - background-image: -webkit-gradient(linear, $start-percent top, $end-percent top, from($start-color), to($end-color)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(left, color-stop($start-color $start-percent), color-stop($end-color $end-percent)); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // FF 3.6+ - background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10 - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{argb($start-color)}', endColorstr='#{argb($end-color)}', GradientType=1); // IE9 and down - } - - // Vertical gradient, from top to bottom - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - @mixin vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { - background-image: -webkit-gradient(linear, left $start-percent, left $end-percent, from($start-color), to($end-color)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, $start-color, $start-percent, $end-color, $end-percent); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // FF 3.6+ - background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10 - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{argb($start-color)}', endColorstr='#{argb($end-color)}', GradientType=0); // IE9 and down - } - - @mixin directional($start-color: #555, $end-color: #333, $deg: 45deg) { - background-repeat: repeat-x; - background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1+, Chrome 10+ - background-image: -moz-linear-gradient($deg, $start-color, $end-color); // FF 3.6+ - background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10 - } - @mixin horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { - background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from($start-color), color-stop($color-stop, $mid-color), to($end-color)); - background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color); - background-image: -moz-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color); - background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); - background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{argb($start-color)}', endColorstr='#{argb($end-color)}', GradientType=1); // IE9 and down - } - @mixin vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($start-color), color-stop($color-stop, $mid-color), to($end-color)); - background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color); - background-image: -moz-linear-gradient(top, $start-color, $mid-color $color-stop, $end-color); - background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); - background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{argb($start-color)}', endColorstr='#{argb($end-color)}', GradientType=0); // IE9 and down - } - @mixin radial($inner-color: #555, $outer-color: #333) { - background-image: -webkit-gradient(radial, center center, 0, center center, 460, from($inner-color), to($outer-color)); - background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color); - background-image: -moz-radial-gradient(circle, $inner-color, $outer-color); - background-image: radial-gradient(circle, $inner-color, $outer-color); - background-repeat: no-repeat; - } - @mixin striped($color: #555, $angle: 45deg) { - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - } -} - -// Reset filters for IE -// -// When you need to remove a gradient background, do not forget to use this to reset -// the IE filter for IE9 and below. -@mixin reset-filter() { - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - - - -// Retina images -// -// Short retina mixin for setting background-image and -size - -@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { - background-image: image-url("#{$file-1x}"); - background-size: $width-1x $height-1x; - - @media - only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and ( min--moz-device-pixel-ratio: 2), - only screen and ( -o-min-device-pixel-ratio: 2/1), - only screen and ( min-device-pixel-ratio: 2), - only screen and ( min-resolution: 192dpi), - only screen and ( min-resolution: 2dppx) { - background-image: image-url("#{$file-2x}"); - background-size: $width-1x $height-1x; - } -} - - -// Responsive image -// -// Keep images from scaling beyond the width of their parents. - -@mixin img-responsive($display: block) { - display: $display; - max-width: 100%; // Part 1: Set a maximum relative to the parent - height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching -} - - -// COMPONENT MIXINS -// -------------------------------------------------- - -// Horizontal dividers -// ------------------------- -// Dividers (basically an hr) within dropdowns and nav lists -@mixin nav-divider($color: #e5e5e5) { - height: 1px; - margin: (($line-height-computed / 2) - 1) 0; - overflow: hidden; - background-color: $color; -} - -// Panels -// ------------------------- -@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) { - border-color: $border; - & > .panel-heading { - color: $heading-text-color; - background-color: $heading-bg-color; - border-color: $heading-border; - + .panel-collapse .panel-body { - border-top-color: $border; - } - } - & > .panel-footer { - + .panel-collapse .panel-body { - border-bottom-color: $border; - } - } -} - -// Alerts -// ------------------------- -@mixin alert-variant($background, $border, $text-color) { - background-color: $background; - border-color: $border; - color: $text-color; - hr { - border-top-color: darken($border, 5%); - } - .alert-link { - color: darken($text-color, 10%); - } -} - -// Tables -// ------------------------- -@mixin table-row-variant($state, $background, $border) { - // Exact selectors below required to override `.table-striped` and prevent - // inheritance to nested tables. - .table > thead > tr, - .table > tbody > tr, - .table > tfoot > tr { - > td.#{state}, - > th.#{state}, - &.#{state} > td, - &.#{state} > th { - background-color: $background; - border-color: $border; - } - } - - // Hover states for `.table-hover` - // Note: this is not available for cells or rows within `thead` or `tfoot`. - .table-hover > tbody > tr { - > td.#{state}:hover, - > th.#{state}:hover, - &.#{state}:hover > td { - background-color: darken($background, 5%); - border-color: darken($border, 5%); - } - } -} - -// Button variants -// ------------------------- -// Easily pump out default styles, as well as :hover, :focus, :active, -// and disabled options for all buttons -@mixin button-variant($color, $background, $border) { - color: $color; - background-color: $background; - border-color: $border; - - &:hover, - &:focus, - &:active, - &.active, - .open .dropdown-toggle& { - color: $color; - background-color: darken($background, 8%); - border-color: darken($border, 12%); - } - &:active, - &.active, - .open .dropdown-toggle& { - background-image: none; - } - &.disabled, - &[disabled], - fieldset[disabled] & { - &, - &:hover, - &:focus, - &:active, - &.active { - background-color: $background; - border-color: $border - } - } -} - -// Button sizes -// ------------------------- -@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { - padding: $padding-vertical $padding-horizontal; - font-size: $font-size; - line-height: $line-height; - border-radius: $border-radius; -} - -// Pagination -// ------------------------- -@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) { - > li { - > a, - > span { - padding: $padding-vertical $padding-horizontal; - font-size: $font-size; - } - &:first-child { - > a, - > span { - @include border-left-radius($border-radius); - } - } - &:last-child { - > a, - > span { - @include border-right-radius($border-radius); - } - } - } -} - -// Labels -// ------------------------- -@mixin label-variant($color) { - background-color: $color; - &[href] { - &:hover, - &:focus { - background-color: darken($color, 10%); - } - } -} - -// Navbar vertical align -// ------------------------- -// Vertically center elements in the navbar. -// Example: an element has a height of 30px, so write out `@include navbar-vertical-align(30px);` to calculate the appropriate top margin. -@mixin navbar-vertical-align($element-height) { - margin-top: (($navbar-height - $element-height) / 2); - margin-bottom: (($navbar-height - $element-height) / 2); -} - -// Progress bars -// ------------------------- -// @mixin progress-bar-variant($color) { -// background-color: $color; -// .progress-striped & { -// #gradient > @include striped($color); -// } -// } - -// Responsive utilities -// ------------------------- -// More easily include all the states for responsive-utilities.less. -@mixin responsive-visibility() { - display: block !important; - tr& { display: table-row !important; } - th&, - td& { display: table-cell !important; } -} - -@mixin responsive-invisibility() { - display: none !important; - tr& { display: none !important; } - th&, - td& { display: none !important; } -} - -// Grid System -// ----------- - -// Centered container element -@mixin container-fixed() { - margin-right: auto; - margin-left: auto; - padding-left: ($grid-gutter-width / 2); - padding-right: ($grid-gutter-width / 2); - @include clearfix(); -} - -// Creates a wrapper for a series of columns -@mixin make-row($gutter: $grid-gutter-width) { - margin-left: ($gutter / -2); - margin-right: ($gutter / -2); - @include clearfix(); -} - -// Generate the extra small columns -@mixin make-xs-column($columns, $gutter: $grid-gutter-width) { - position: relative; - float: left; - width: percentage(($columns / $grid-columns)); - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: ($gutter / 2); - padding-right: ($gutter / 2); -} - -// Generate the small columns -@mixin make-sm-column($columns, $gutter: $grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: ($gutter / 2); - padding-right: ($gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: $screen-sm) { - float: left; - width: percentage(($columns / $grid-columns)); - } -} - -// Generate the small column offsets -@mixin make-sm-column-offset($columns) { - @media (min-width: $screen-sm) { - margin-left: percentage(($columns / $grid-columns)); - } -} -@mixin make-sm-column-push($columns) { - @media (min-width: $screen-sm) { - left: percentage(($columns / $grid-columns)); - } -} -@mixin make-sm-column-pull($columns) { - @media (min-width: $screen-sm) { - right: percentage(($columns / $grid-columns)); - } -} - -// Generate the medium columns -@mixin make-md-column($columns, $gutter: $grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: ($gutter / 2); - padding-right: ($gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: $screen-md) { - float: left; - width: percentage(($columns / $grid-columns)); - } -} - -// Generate the large column offsets -@mixin make-md-column-offset($columns) { - @media (min-width: $screen-md) { - margin-left: percentage(($columns / $grid-columns)); - } -} -@mixin make-md-column-push($columns) { - @media (min-width: $screen-md) { - left: percentage(($columns / $grid-columns)); - } -} -@mixin make-md-column-pull($columns) { - @media (min-width: $screen-md) { - right: percentage(($columns / $grid-columns)); - } -} - -// Generate the large columns -@mixin make-lg-column($columns, $gutter: $grid-gutter-width) { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: ($gutter / 2); - padding-right: ($gutter / 2); - - // Calculate width based on number of columns available - @media (min-width: $screen-lg) { - float: left; - width: percentage(($columns / $grid-columns)); - } -} - -// Generate the large column offsets -@mixin make-lg-column-offset($columns) { - @media (min-width: $screen-lg) { - margin-left: percentage(($columns / $grid-columns)); - } -} -@mixin make-lg-column-push($columns) { - @media (min-width: $screen-lg) { - left: percentage(($columns / $grid-columns)); - } -} -@mixin make-lg-column-pull($columns) { - @media (min-width: $screen-lg) { - right: percentage(($columns / $grid-columns)); - } -} - - -// Form validation states -// -// Used in forms.less to generate the form validation CSS for warnings, errors, -// and successes. - -@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) { - // Color the label and help text - .help-block, - .control-label { - color: $text-color; - } - // Set the border and box shadow on specific inputs to match - .form-control { - border-color: $border-color; - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work - &:focus { - border-color: darken($border-color, 10%); - $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%); - @include box-shadow($shadow); - } - } - // Set validation states also for addons - .input-group-addon { - color: $text-color; - border-color: $border-color; - background-color: $background-color; - } -} - -// Form control focus state -// -// Generate a customized focus state and for any input with the specified color, -// which defaults to the `$input-focus-border` variable. -// -// We highly encourage you to not customize the default value, but instead use -// this to tweak colors on an as-needed basis. This aesthetic change is based on -// WebKit's default styles, but applicable to a wider range of browsers. Its -// usability and accessibility should be taken into account with any change. -// -// Example usage: change the default blue border and shadow to white for better -// contrast against a dark gray background. - -@mixin form-control-focus($color: $input-border-focus) { - $color-rgba: rgba(red($color), green($color), blue($color), .6); - &:focus { - border-color: $color; - outline: 0; - @include box-shadow(#{"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px #{color-rgba}"}); - } -} - -// Form control sizing -// -// Relative text size, padding, and border-radii changes for form controls. For -// horizontal sizing, wrap controls in the predefined grid classes. `