Terraform provider ProfitBricks - Data Sources (#11520)
* Terraform ProfitBricks Builder * make fmt * Merge remote-tracking branch 'upstream/master' into terraform-provider-profitbricks # Conflicts: # command/internal_plugin_list.go * Addressing PR remarks * Removed importers * Added ProfitBricks Data Sources * Added documentation * Updated to REST v3: - nat parameter for Nics - availabilityZone for Volumes Minor code clean up * Minor code clean up * Fixed typo in volume documentation * make fmt * Addressing requested changes * Added a step in load balancer tests in CheckDestroy where we are making sure that the test doesn't leave dangling resources in ProfitBricks * Changed expected image name * Fixed data center test Code clean up
This commit is contained in:
parent
c8a2d40c82
commit
b862cd2ccb
|
@ -7,6 +7,7 @@ import (
|
|||
type Config struct {
|
||||
Username string
|
||||
Password string
|
||||
Endpoint string
|
||||
Retries int
|
||||
}
|
||||
|
||||
|
@ -14,6 +15,8 @@ type Config struct {
|
|||
func (c *Config) Client() (*Config, error) {
|
||||
profitbricks.SetAuth(c.Username, c.Password)
|
||||
profitbricks.SetDepth("5")
|
||||
|
||||
if len(c.Endpoint) > 0 {
|
||||
profitbricks.SetEndpoint(c.Endpoint)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func dataSourceDataCenter() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataSourceDataCenterRead,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceDataCenterRead(d *schema.ResourceData, meta interface{}) error {
|
||||
datacenters := profitbricks.ListDatacenters()
|
||||
|
||||
if datacenters.StatusCode > 299 {
|
||||
return fmt.Errorf("An error occured while fetching datacenters %s", datacenters.Response)
|
||||
}
|
||||
|
||||
name := d.Get("name").(string)
|
||||
location, locationOk := d.GetOk("location")
|
||||
|
||||
results := []profitbricks.Datacenter{}
|
||||
|
||||
for _, dc := range datacenters.Items {
|
||||
if dc.Properties.Name == name || strings.Contains(dc.Properties.Name, name) {
|
||||
results = append(results, dc)
|
||||
}
|
||||
}
|
||||
|
||||
if locationOk {
|
||||
log.Printf("[INFO] searching dcs by location***********")
|
||||
locationResults := []profitbricks.Datacenter{}
|
||||
for _, dc := range results {
|
||||
if dc.Properties.Location == location.(string) {
|
||||
locationResults = append(locationResults, dc)
|
||||
}
|
||||
}
|
||||
results = locationResults
|
||||
}
|
||||
log.Printf("[INFO] Results length %d *************", len(results))
|
||||
|
||||
if len(results) > 1 {
|
||||
log.Printf("[INFO] Results length greater than 1")
|
||||
return fmt.Errorf("There is more than one datacenters that match the search criteria")
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
return fmt.Errorf("There are no datacenters that match the search criteria")
|
||||
}
|
||||
|
||||
d.SetId(results[0].Id)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccDataSourceDatacenter_matching(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
|
||||
Config: testAccDataSourceProfitBricksDataCenter_matching,
|
||||
},
|
||||
{
|
||||
|
||||
Config: testAccDataSourceProfitBricksDataCenter_matchingWithDataSource,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("data.profitbricks_datacenter.foobar", "name", "test_name"),
|
||||
resource.TestCheckResourceAttr("data.profitbricks_datacenter.foobar", "location", "us/las"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const testAccDataSourceProfitBricksDataCenter_matching = `
|
||||
resource "profitbricks_datacenter" "foobar" {
|
||||
name = "test_name"
|
||||
location = "us/las"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccDataSourceProfitBricksDataCenter_matchingWithDataSource = `
|
||||
resource "profitbricks_datacenter" "foobar" {
|
||||
name = "test_name"
|
||||
location = "us/las"
|
||||
}
|
||||
|
||||
data "profitbricks_datacenter" "foobar" {
|
||||
name = "${profitbricks_datacenter.foobar.name}"
|
||||
location = "us/las"
|
||||
}`
|
|
@ -0,0 +1,102 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func dataSourceImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataSourceImageRead,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"location": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceImageRead(d *schema.ResourceData, meta interface{}) error {
|
||||
profitbricks.SetDepth("5")
|
||||
|
||||
images := profitbricks.ListImages()
|
||||
|
||||
if images.StatusCode > 299 {
|
||||
return fmt.Errorf("An error occured while fetching ProfitBricks locations %s", images.Response)
|
||||
}
|
||||
|
||||
name := d.Get("name").(string)
|
||||
imageType, imageTypeOk := d.GetOk("type")
|
||||
location, locationOk := d.GetOk("location")
|
||||
version, versionOk := d.GetOk("version")
|
||||
|
||||
results := []profitbricks.Image{}
|
||||
|
||||
// if version value is present then concatenate name - version
|
||||
// otherwise search by name or part of the name
|
||||
if versionOk {
|
||||
name_ver := fmt.Sprintf("%s-%s", name, version.(string))
|
||||
for _, img := range images.Items {
|
||||
if strings.Contains(strings.ToLower(img.Properties.Name), strings.ToLower(name_ver)) {
|
||||
results = append(results, img)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, img := range images.Items {
|
||||
if strings.Contains(strings.ToLower(img.Properties.Name), strings.ToLower(name)) {
|
||||
results = append(results, img)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if imageTypeOk {
|
||||
imageTypeResults := []profitbricks.Image{}
|
||||
for _, img := range results {
|
||||
if img.Properties.ImageType == imageType.(string) {
|
||||
imageTypeResults = append(imageTypeResults, img)
|
||||
}
|
||||
|
||||
}
|
||||
results = imageTypeResults
|
||||
}
|
||||
|
||||
if locationOk {
|
||||
locationResults := []profitbricks.Image{}
|
||||
for _, img := range results {
|
||||
if img.Properties.Location == location.(string) {
|
||||
locationResults = append(locationResults, img)
|
||||
}
|
||||
|
||||
}
|
||||
results = locationResults
|
||||
}
|
||||
|
||||
if len(results) > 1 {
|
||||
return fmt.Errorf("There is more than one image that match the search criteria")
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
return fmt.Errorf("There are no images that match the search criteria")
|
||||
}
|
||||
|
||||
d.Set("name", results[0].Properties.Name)
|
||||
|
||||
d.SetId(results[0].Id)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccDataSourceImage_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
|
||||
Config: testAccDataSourceProfitBricksImage_basic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("data.profitbricks_image.img", "location", "us/las"),
|
||||
resource.TestCheckResourceAttr("data.profitbricks_image.img", "name", "Ubuntu-16.04-LTS-server-2017-02-01"),
|
||||
resource.TestCheckResourceAttr("data.profitbricks_image.img", "type", "HDD"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const testAccDataSourceProfitBricksImage_basic = `
|
||||
data "profitbricks_image" "img" {
|
||||
name = "Ubuntu"
|
||||
type = "HDD"
|
||||
version = "16"
|
||||
location = "us/las"
|
||||
}
|
||||
`
|
|
@ -0,0 +1,73 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func dataSourceLocation() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataSourceLocationRead,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"feature": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceLocationRead(d *schema.ResourceData, meta interface{}) error {
|
||||
locations := profitbricks.ListLocations()
|
||||
|
||||
if locations.StatusCode > 299 {
|
||||
return fmt.Errorf("An error occured while fetching ProfitBricks locations %s", locations.Response)
|
||||
}
|
||||
|
||||
name, nameOk := d.GetOk("name")
|
||||
feature, featureOk := d.GetOk("features")
|
||||
|
||||
if !nameOk && !featureOk {
|
||||
return fmt.Errorf("Either 'name' or 'feature' must be provided.")
|
||||
}
|
||||
results := []profitbricks.Location{}
|
||||
|
||||
for _, loc := range locations.Items {
|
||||
if loc.Properties.Name == name.(string) || strings.Contains(loc.Properties.Name, name.(string)) {
|
||||
results = append(results, loc)
|
||||
}
|
||||
}
|
||||
|
||||
if featureOk {
|
||||
locationResults := []profitbricks.Location{}
|
||||
for _, loc := range results {
|
||||
for _, f := range loc.Properties.Features {
|
||||
if f == feature.(string) {
|
||||
locationResults = append(locationResults, loc)
|
||||
}
|
||||
}
|
||||
}
|
||||
results = locationResults
|
||||
}
|
||||
log.Printf("[INFO] Results length %d *************", len(results))
|
||||
|
||||
if len(results) > 1 {
|
||||
log.Printf("[INFO] Results length greater than 1")
|
||||
return fmt.Errorf("There is more than one location that match the search criteria")
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
return fmt.Errorf("There are no locations that match the search criteria")
|
||||
}
|
||||
|
||||
d.SetId(results[0].Id)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccDataSourceLocation_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
|
||||
Config: testAccDataSourceProfitBricksLocation_basic,
|
||||
Check: resource.ComposeTestCheckFunc(resource.TestCheckResourceAttr("data.profitbricks_location.loc", "id", "de/fkb"),
|
||||
resource.TestCheckResourceAttr("data.profitbricks_location.loc", "name", "karlsruhe"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const testAccDataSourceProfitBricksLocation_basic = `
|
||||
data "profitbricks_location" "loc" {
|
||||
name = "karlsruhe"
|
||||
feature = "SSD"
|
||||
}
|
||||
`
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
)
|
||||
|
||||
// Provider returns a schema.Provider for DigitalOcean.
|
||||
|
@ -22,6 +23,12 @@ func Provider() terraform.ResourceProvider {
|
|||
DefaultFunc: schema.EnvDefaultFunc("PROFITBRICKS_PASSWORD", nil),
|
||||
Description: "Profitbricks password for API operations.",
|
||||
},
|
||||
"endpoint": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("PROFITBRICKS_API_URL", profitbricks.Endpoint),
|
||||
Description: "Profitbricks REST API URL.",
|
||||
},
|
||||
"retries": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
|
@ -39,7 +46,11 @@ func Provider() terraform.ResourceProvider {
|
|||
"profitbricks_server": resourceProfitBricksServer(),
|
||||
"profitbricks_volume": resourceProfitBricksVolume(),
|
||||
},
|
||||
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"profitbricks_datacenter": dataSourceDataCenter(),
|
||||
"profitbricks_location": dataSourceLocation(),
|
||||
"profitbricks_image": dataSourceImage(),
|
||||
},
|
||||
ConfigureFunc: providerConfigure,
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +68,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
|||
config := Config{
|
||||
Username: d.Get("username").(string),
|
||||
Password: d.Get("password").(string),
|
||||
Endpoint: d.Get("endpoint").(string),
|
||||
Retries: d.Get("retries").(int),
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
"log"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -38,9 +39,6 @@ func resourceProfitBricksDatacenter() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksDatacenterCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
datacenter := profitbricks.Datacenter{
|
||||
Properties: profitbricks.DatacenterProperties{
|
||||
Name: d.Get("name").(string),
|
||||
|
@ -69,9 +67,6 @@ func resourceProfitBricksDatacenterCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
func resourceProfitBricksDatacenterRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
datacenter := profitbricks.GetDatacenter(d.Id())
|
||||
if datacenter.StatusCode > 299 {
|
||||
return fmt.Errorf("Error while fetching a data center ID %s %s", d.Id(), datacenter.Response)
|
||||
|
@ -84,10 +79,6 @@ func resourceProfitBricksDatacenterRead(d *schema.ResourceData, meta interface{}
|
|||
}
|
||||
|
||||
func resourceProfitBricksDatacenterUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
obj := profitbricks.DatacenterProperties{}
|
||||
|
||||
if d.HasChange("name") {
|
||||
|
@ -107,9 +98,6 @@ func resourceProfitBricksDatacenterUpdate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
func resourceProfitBricksDatacenterDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
dcid := d.Id()
|
||||
resp := profitbricks.DeleteDatacenter(dcid)
|
||||
|
||||
|
@ -126,9 +114,12 @@ func resourceProfitBricksDatacenterDelete(d *schema.ResourceData, meta interface
|
|||
|
||||
func waitTillProvisioned(meta interface{}, path string) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
waitCount := 50
|
||||
|
||||
for i := 0; i < config.Retries; i++ {
|
||||
if config.Retries != 0 {
|
||||
waitCount = config.Retries
|
||||
}
|
||||
for i := 0; i < waitCount; i++ {
|
||||
request := profitbricks.GetRequestStatus(path)
|
||||
pc, _, _, ok := runtime.Caller(1)
|
||||
details := runtime.FuncForPC(pc)
|
||||
|
@ -182,3 +173,8 @@ func getImageId(dcId string, imageName string, imageType string) string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func IsValidUUID(uuid string) bool {
|
||||
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$")
|
||||
return r.MatchString(uuid)
|
||||
}
|
||||
|
|
|
@ -81,9 +81,6 @@ func resourceProfitBricksFirewall() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksFirewallCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
fw := profitbricks.FirewallRule{
|
||||
Properties: profitbricks.FirewallruleProperties{
|
||||
Protocol: d.Get("protocol").(string),
|
||||
|
@ -131,9 +128,6 @@ func resourceProfitBricksFirewallCreate(d *schema.ResourceData, meta interface{}
|
|||
}
|
||||
|
||||
func resourceProfitBricksFirewallRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
fw := profitbricks.GetFirewallRule(d.Get("datacenter_id").(string), d.Get("server_id").(string), d.Get("nic_id").(string), d.Id())
|
||||
|
||||
if fw.StatusCode > 299 {
|
||||
|
@ -155,9 +149,6 @@ func resourceProfitBricksFirewallRead(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
func resourceProfitBricksFirewallUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
properties := profitbricks.FirewallruleProperties{}
|
||||
|
||||
if d.HasChange("name") {
|
||||
|
@ -215,9 +206,6 @@ func resourceProfitBricksFirewallUpdate(d *schema.ResourceData, meta interface{}
|
|||
}
|
||||
|
||||
func resourceProfitBricksFirewallDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
resp := profitbricks.DeleteFirewallRule(d.Get("datacenter_id").(string), d.Get("server_id").(string), d.Get("nic_id").(string), d.Id())
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
|
|
|
@ -34,9 +34,6 @@ func resourceProfitBricksIPBlock() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksIPBlockCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
ipblock := profitbricks.IpBlock{
|
||||
Properties: profitbricks.IpBlockProperties{
|
||||
Size: d.Get("size").(int),
|
||||
|
@ -59,9 +56,6 @@ func resourceProfitBricksIPBlockCreate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
func resourceProfitBricksIPBlockRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
ipblock := profitbricks.GetIpBlock(d.Id())
|
||||
|
||||
if ipblock.StatusCode > 299 {
|
||||
|
@ -78,9 +72,6 @@ func resourceProfitBricksIPBlockRead(d *schema.ResourceData, meta interface{}) e
|
|||
}
|
||||
|
||||
func resourceProfitBricksIPBlockDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
resp := profitbricks.ReleaseIpBlock(d.Id())
|
||||
if resp.StatusCode > 299 {
|
||||
return fmt.Errorf("An error occured while releasing an ipblock ID: %s %s", d.Id(), string(resp.Body))
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func resourceProfitBricksLan() *schema.Resource {
|
||||
|
@ -32,9 +33,6 @@ func resourceProfitBricksLan() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksLanCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
profitbricks.SetDepth("5")
|
||||
request := profitbricks.Lan{
|
||||
Properties: profitbricks.LanProperties{
|
||||
Public: d.Get("public").(bool),
|
||||
|
@ -64,9 +62,6 @@ func resourceProfitBricksLanCreate(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
func resourceProfitBricksLanRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
lan := profitbricks.GetLan(d.Get("datacenter_id").(string), d.Id())
|
||||
|
||||
if lan.StatusCode > 299 {
|
||||
|
@ -80,9 +75,6 @@ func resourceProfitBricksLanRead(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
func resourceProfitBricksLanUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
properties := &profitbricks.LanProperties{}
|
||||
if d.HasChange("public") {
|
||||
_, newValue := d.GetChange("public")
|
||||
|
@ -107,10 +99,15 @@ func resourceProfitBricksLanUpdate(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
func resourceProfitBricksLanDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
resp := profitbricks.DeleteLan(d.Get("datacenter_id").(string), d.Id())
|
||||
if resp.StatusCode > 299 {
|
||||
//try again in 20 seconds
|
||||
time.Sleep(60 * time.Second)
|
||||
resp = profitbricks.DeleteLan(d.Get("datacenter_id").(string), d.Id())
|
||||
if resp.StatusCode > 299 && resp.StatusCode != 404 {
|
||||
return fmt.Errorf("An error occured while deleting a lan dcId %s ID %s %s", d.Get("datacenter_id").(string), d.Id(), string(resp.Body))
|
||||
}
|
||||
}
|
||||
|
||||
if resp.Headers.Get("Location") != "" {
|
||||
err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
|
||||
|
|
|
@ -40,9 +40,6 @@ func resourceProfitBricksLoadbalancer() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksLoadbalancerCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
lb := profitbricks.Loadbalancer{
|
||||
Properties: profitbricks.LoadbalancerProperties{
|
||||
Name: d.Get("name").(string),
|
||||
|
@ -86,9 +83,6 @@ func resourceProfitBricksLoadbalancerRead(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
func resourceProfitBricksLoadbalancerUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
properties := profitbricks.LoadbalancerProperties{}
|
||||
if d.HasChange("name") {
|
||||
_, new := d.GetChange("name")
|
||||
|
@ -129,9 +123,6 @@ func resourceProfitBricksLoadbalancerUpdate(d *schema.ResourceData, meta interfa
|
|||
}
|
||||
|
||||
func resourceProfitBricksLoadbalancerDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
resp := profitbricks.DeleteLoadbalancer(d.Get("datacenter_id").(string), d.Id())
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
|
|
|
@ -48,7 +48,11 @@ func testAccCheckDProfitBricksLoadbalancerDestroyCheck(s *terraform.State) error
|
|||
resp := profitbricks.GetLoadbalancer(rs.Primary.Attributes["datacenter_id"], rs.Primary.ID)
|
||||
|
||||
if resp.StatusCode < 299 {
|
||||
return fmt.Errorf("Firewall still exists %s %s", rs.Primary.ID, resp.Response)
|
||||
resp := profitbricks.DeleteDatacenter(rs.Primary.Attributes["datacenter_id"])
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
return fmt.Errorf("Firewall still exists %s %s", rs.Primary.ID, string(resp.Body))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,15 +16,15 @@ func resourceProfitBricksNic() *schema.Resource {
|
|||
Delete: resourceProfitBricksNicDelete,
|
||||
Schema: map[string]*schema.Schema{
|
||||
|
||||
"lan": &schema.Schema{
|
||||
"lan": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"name": &schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"dhcp": &schema.Schema{
|
||||
"dhcp": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
|
@ -32,10 +32,19 @@ func resourceProfitBricksNic() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"ips": {
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Computed: true,
|
||||
},
|
||||
"firewall_active": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"nat": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"server_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
|
@ -49,9 +58,6 @@ func resourceProfitBricksNic() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksNicCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
nic := profitbricks.Nic{
|
||||
Properties: profitbricks.NicProperties{
|
||||
Lan: d.Get("lan").(int),
|
||||
|
@ -69,6 +75,14 @@ func resourceProfitBricksNicCreate(d *schema.ResourceData, meta interface{}) err
|
|||
ips := strings.Split(raw, ",")
|
||||
nic.Properties.Ips = ips
|
||||
}
|
||||
if _, ok := d.GetOk("firewall_active"); ok {
|
||||
raw := d.Get("firewall_active").(bool)
|
||||
nic.Properties.FirewallActive = raw
|
||||
}
|
||||
if _, ok := d.GetOk("nat"); ok {
|
||||
raw := d.Get("nat").(bool)
|
||||
nic.Properties.Nat = raw
|
||||
}
|
||||
|
||||
nic = profitbricks.CreateNic(d.Get("datacenter_id").(string), d.Get("server_id").(string), nic)
|
||||
if nic.StatusCode > 299 {
|
||||
|
@ -93,27 +107,20 @@ func resourceProfitBricksNicCreate(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
func resourceProfitBricksNicRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
profitbricks.SetDepth("5")
|
||||
|
||||
nic := profitbricks.GetNic(d.Get("datacenter_id").(string), d.Get("server_id").(string), d.Id())
|
||||
if nic.StatusCode > 299 {
|
||||
return fmt.Errorf("Error occured while fetching a nic ID %s %s", d.Id(), nic.Response)
|
||||
}
|
||||
log.Printf("[INFO] LAN ON NIC: %q", nic.Properties.Lan)
|
||||
log.Printf("[INFO] LAN ON NIC: %d", nic.Properties.Lan)
|
||||
d.Set("dhcp", nic.Properties.Dhcp)
|
||||
d.Set("lan", nic.Properties.Lan)
|
||||
d.Set("name", nic.Properties.Name)
|
||||
d.Set("ip", nic.Properties.Ips)
|
||||
d.Set("ips", nic.Properties.Ips)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceProfitBricksNicUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
properties := profitbricks.NicProperties{}
|
||||
|
||||
if d.HasChange("name") {
|
||||
|
@ -134,6 +141,11 @@ func resourceProfitBricksNicUpdate(d *schema.ResourceData, meta interface{}) err
|
|||
ips := strings.Split(raw.(string), ",")
|
||||
properties.Ips = ips
|
||||
}
|
||||
if d.HasChange("nat") {
|
||||
_, raw := d.GetChange("nat")
|
||||
nat := raw.(bool)
|
||||
properties.Nat = nat
|
||||
}
|
||||
|
||||
nic := profitbricks.PatchNic(d.Get("datacenter_id").(string), d.Get("server_id").(string), d.Id(), properties)
|
||||
|
||||
|
@ -148,9 +160,6 @@ func resourceProfitBricksNicUpdate(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
func resourceProfitBricksNicDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
resp := profitbricks.DeleteNic(d.Get("datacenter_id").(string), d.Get("server_id").(string), d.Id())
|
||||
err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
|
||||
if err != nil {
|
||||
|
|
|
@ -66,6 +66,10 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"primary_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"datacenter_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
|
@ -97,7 +101,8 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
Optional: true,
|
||||
},
|
||||
"ssh_key_path": {
|
||||
Type: schema.TypeString,
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Optional: true,
|
||||
},
|
||||
"bus": {
|
||||
|
@ -108,6 +113,10 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"availability_zone": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -133,6 +142,15 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"ips": {
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Computed: true,
|
||||
},
|
||||
"nat": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"firewall_active": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
|
@ -167,6 +185,11 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"ips": {
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Optional: true,
|
||||
},
|
||||
"port_range_start": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
|
@ -207,9 +230,6 @@ func resourceProfitBricksServer() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
request := profitbricks.Server{
|
||||
Properties: profitbricks.ServerProperties{
|
||||
Name: d.Get("name").(string),
|
||||
|
@ -233,15 +253,21 @@ func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{})
|
|||
|
||||
for _, raw := range volumeRaw {
|
||||
rawMap := raw.(map[string]interface{})
|
||||
var imagePassword, sshkey_path string
|
||||
var image, licenceType string
|
||||
var imagePassword string
|
||||
//Can be one file or a list of files
|
||||
var sshkey_path []interface{}
|
||||
var image, licenceType, availabilityZone string
|
||||
|
||||
if rawMap["image_name"] != nil {
|
||||
image = getImageId(d.Get("datacenter_id").(string), rawMap["image_name"].(string), rawMap["disk_type"].(string))
|
||||
if image == "" {
|
||||
dc := profitbricks.GetDatacenter(d.Get("datacenter_id").(string))
|
||||
return fmt.Errorf("Image '%s' doesn't exist. in location %s", rawMap["image_name"], dc.Properties.Location)
|
||||
if !IsValidUUID(rawMap["image_name"].(string)) {
|
||||
image = getImageId(d.Get("datacenter_id").(string), rawMap["image_name"].(string), rawMap["disk_type"].(string))
|
||||
if image == "" {
|
||||
dc := profitbricks.GetDatacenter(d.Get("datacenter_id").(string))
|
||||
return fmt.Errorf("Image '%s' doesn't exist. in location %s", rawMap["image_name"], dc.Properties.Location)
|
||||
|
||||
}
|
||||
} else {
|
||||
image = rawMap["image_name"].(string)
|
||||
}
|
||||
}
|
||||
if rawMap["licence_type"] != nil {
|
||||
|
@ -252,24 +278,27 @@ func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{})
|
|||
imagePassword = rawMap["image_password"].(string)
|
||||
}
|
||||
if rawMap["ssh_key_path"] != nil {
|
||||
sshkey_path = rawMap["ssh_key_path"].(string)
|
||||
sshkey_path = rawMap["ssh_key_path"].([]interface{})
|
||||
}
|
||||
if rawMap["image_name"] != nil {
|
||||
if imagePassword == "" && sshkey_path == "" {
|
||||
return fmt.Errorf("'image_password' and 'ssh_key_path' are not provided.")
|
||||
if imagePassword == "" && len(sshkey_path) == 0 {
|
||||
return fmt.Errorf("Either 'image_password' or 'ssh_key_path' must be provided.")
|
||||
}
|
||||
}
|
||||
var publicKey string
|
||||
var err error
|
||||
if sshkey_path != "" {
|
||||
log.Println("[DEBUG] GETTING THE KEY")
|
||||
_, publicKey, err = getSshKey(d, sshkey_path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error fetching sshkeys (%s)", err)
|
||||
var publicKeys []string
|
||||
if len(sshkey_path) != 0 {
|
||||
for _, path := range sshkey_path {
|
||||
log.Printf("[DEBUG] Reading file %s", path)
|
||||
publicKey, err := readPublicKey(path.(string))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error fetching sshkey from file (%s) (%s)", path, err.Error())
|
||||
}
|
||||
publicKeys = append(publicKeys, publicKey)
|
||||
}
|
||||
d.Set("sshkey", publicKey)
|
||||
}
|
||||
|
||||
if rawMap["availability_zone"] != nil {
|
||||
availabilityZone = rawMap["availability_zone"].(string)
|
||||
}
|
||||
if image == "" && licenceType == "" {
|
||||
return fmt.Errorf("Either 'image', or 'licenceType' must be set.")
|
||||
}
|
||||
|
@ -277,27 +306,26 @@ func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{})
|
|||
request.Entities = &profitbricks.ServerEntities{
|
||||
Volumes: &profitbricks.Volumes{
|
||||
Items: []profitbricks.Volume{
|
||||
profitbricks.Volume{
|
||||
{
|
||||
Properties: profitbricks.VolumeProperties{
|
||||
Name: rawMap["name"].(string),
|
||||
Size: rawMap["size"].(int),
|
||||
Type: rawMap["disk_type"].(string),
|
||||
ImagePassword: imagePassword,
|
||||
Image: image,
|
||||
Bus: rawMap["bus"].(string),
|
||||
LicenceType: licenceType,
|
||||
Name: rawMap["name"].(string),
|
||||
Size: rawMap["size"].(int),
|
||||
Type: rawMap["disk_type"].(string),
|
||||
ImagePassword: imagePassword,
|
||||
Image: image,
|
||||
Bus: rawMap["bus"].(string),
|
||||
LicenceType: licenceType,
|
||||
AvailabilityZone: availabilityZone,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] PUBLIC KEY %s", publicKey)
|
||||
|
||||
if publicKey == "" {
|
||||
if len(publicKeys) == 0 {
|
||||
request.Entities.Volumes.Items[0].Properties.SshKeys = nil
|
||||
} else {
|
||||
request.Entities.Volumes.Items[0].Properties.SshKeys = []string{publicKey}
|
||||
request.Entities.Volumes.Items[0].Properties.SshKeys = publicKeys
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,6 +356,9 @@ func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{})
|
|||
nic.Properties.Ips = ips
|
||||
}
|
||||
}
|
||||
if rawMap["nat"] != nil {
|
||||
nic.Properties.Nat = rawMap["nat"].(bool)
|
||||
}
|
||||
request.Entities.Nics = &profitbricks.Nics{
|
||||
Items: []profitbricks.Nic{
|
||||
nic,
|
||||
|
@ -416,9 +447,6 @@ func resourceProfitBricksServerCreate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
func resourceProfitBricksServerRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
|
||||
server := profitbricks.GetServer(dcId, d.Id())
|
||||
|
@ -456,9 +484,6 @@ func resourceProfitBricksServerRead(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
func resourceProfitBricksServerUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
|
||||
request := profitbricks.ServerProperties{}
|
||||
|
@ -484,7 +509,6 @@ func resourceProfitBricksServerUpdate(d *schema.ResourceData, meta interface{})
|
|||
request.CpuFamily = n.(string)
|
||||
}
|
||||
server := profitbricks.PatchServer(dcId, d.Id(), request)
|
||||
log.Println("[INFO] hlab hlab", request)
|
||||
|
||||
//Volume stuff
|
||||
if d.HasChange("volume") {
|
||||
|
@ -508,7 +532,6 @@ func resourceProfitBricksServerUpdate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
volume = profitbricks.PatchVolume(d.Get("datacenter_id").(string), server.Entities.Volumes.Items[0].Id, properties)
|
||||
log.Println("[INFO] blah blah", properties)
|
||||
|
||||
if volume.StatusCode > 299 {
|
||||
return fmt.Errorf("Error patching volume (%s) (%s)", d.Id(), volume.Response)
|
||||
|
@ -553,10 +576,12 @@ func resourceProfitBricksServerUpdate(d *schema.ResourceData, meta interface{})
|
|||
if rawMap["dhcp"] != nil {
|
||||
properties.Dhcp = rawMap["dhcp"].(bool)
|
||||
}
|
||||
if rawMap["nat"] != nil {
|
||||
properties.Nat = rawMap["nat"].(bool)
|
||||
}
|
||||
}
|
||||
|
||||
nic = profitbricks.PatchNic(d.Get("datacenter_id").(string), server.Id, server.Entities.Nics.Items[0].Id, properties)
|
||||
log.Println("[INFO] blah blah", properties)
|
||||
|
||||
if nic.StatusCode > 299 {
|
||||
return fmt.Errorf(
|
||||
|
@ -577,9 +602,6 @@ func resourceProfitBricksServerUpdate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
func resourceProfitBricksServerDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
|
||||
server := profitbricks.GetServer(dcId, d.Id())
|
||||
|
@ -605,6 +627,19 @@ func resourceProfitBricksServerDelete(d *schema.ResourceData, meta interface{})
|
|||
return nil
|
||||
}
|
||||
|
||||
//Reads public key from file and returns key string iff valid
|
||||
func readPublicKey(path string) (key string, err error) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pubKey, _, _, _, err := ssh.ParseAuthorizedKey(bytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(ssh.MarshalAuthorizedKey(pubKey)[:]), nil
|
||||
}
|
||||
|
||||
func getSshKey(d *schema.ResourceData, path string) (privatekey string, publickey string, err error) {
|
||||
pemBytes, err := ioutil.ReadFile(path)
|
||||
|
||||
|
@ -623,7 +658,6 @@ func getSshKey(d *schema.ResourceData, path string) (privatekey string, publicke
|
|||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
priv_blk := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Headers: nil,
|
||||
|
|
|
@ -141,6 +141,12 @@ resource "profitbricks_datacenter" "foobar" {
|
|||
location = "us/las"
|
||||
}
|
||||
|
||||
resource "profitbricks_lan" "webserver_lan" {
|
||||
datacenter_id = "${profitbricks_datacenter.foobar.id}"
|
||||
public = true
|
||||
name = "public"
|
||||
}
|
||||
|
||||
resource "profitbricks_server" "webserver" {
|
||||
name = "updated"
|
||||
datacenter_id = "${profitbricks_datacenter.foobar.id}"
|
||||
|
@ -156,7 +162,7 @@ resource "profitbricks_server" "webserver" {
|
|||
image_password = "test1234"
|
||||
}
|
||||
nic {
|
||||
lan = "1"
|
||||
lan = "${profitbricks_lan.webserver_lan.id}"
|
||||
dhcp = true
|
||||
firewall_active = true
|
||||
firewall {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package profitbricks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/profitbricks/profitbricks-sdk-go"
|
||||
|
@ -37,7 +36,8 @@ func resourceProfitBricksVolume() *schema.Resource {
|
|||
Optional: true,
|
||||
},
|
||||
"ssh_key_path": {
|
||||
Type: schema.TypeString,
|
||||
Type: schema.TypeList,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Optional: true,
|
||||
},
|
||||
"sshkey": {
|
||||
|
@ -52,6 +52,10 @@ func resourceProfitBricksVolume() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"availability_zone": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"server_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
|
@ -65,20 +69,17 @@ func resourceProfitBricksVolume() *schema.Resource {
|
|||
}
|
||||
|
||||
func resourceProfitBricksVolumeCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
var err error
|
||||
var ssh_keypath []interface{}
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
serverId := d.Get("server_id").(string)
|
||||
|
||||
imagePassword := d.Get("image_password").(string)
|
||||
sshkey := d.Get("ssh_key_path").(string)
|
||||
ssh_keypath = d.Get("ssh_key_path").([]interface{})
|
||||
image_name := d.Get("image_name").(string)
|
||||
|
||||
if image_name != "" {
|
||||
if imagePassword == "" && sshkey == "" {
|
||||
return fmt.Errorf("'image_password' and 'sshkey' are not provided.")
|
||||
if imagePassword == "" && len(ssh_keypath) == 0 {
|
||||
return fmt.Errorf("Either 'image_password' or 'sshkey' must be provided.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,19 +89,24 @@ func resourceProfitBricksVolumeCreate(d *schema.ResourceData, meta interface{})
|
|||
return fmt.Errorf("Either 'image_name', or 'licenceType' must be set.")
|
||||
}
|
||||
|
||||
var publicKey string
|
||||
|
||||
if sshkey != "" {
|
||||
_, publicKey, err = getSshKey(d, sshkey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error fetching sshkeys (%s)", err)
|
||||
var publicKeys []string
|
||||
if len(ssh_keypath) != 0 {
|
||||
for _, path := range ssh_keypath {
|
||||
log.Printf("[DEBUG] Reading file %s", path)
|
||||
publicKey, err := readPublicKey(path.(string))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error fetching sshkey from file (%s) (%s)", path, err.Error())
|
||||
}
|
||||
publicKeys = append(publicKeys, publicKey)
|
||||
}
|
||||
d.Set("sshkey", publicKey)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] public key: %s", publicKey)
|
||||
|
||||
image := getImageId(d.Get("datacenter_id").(string), image_name, d.Get("disk_type").(string))
|
||||
var image string
|
||||
if !IsValidUUID(image_name) {
|
||||
image = getImageId(d.Get("datacenter_id").(string), image_name, d.Get("disk_type").(string))
|
||||
} else {
|
||||
image = image_name
|
||||
}
|
||||
|
||||
volume := profitbricks.Volume{
|
||||
Properties: profitbricks.VolumeProperties{
|
||||
|
@ -114,14 +120,17 @@ func resourceProfitBricksVolumeCreate(d *schema.ResourceData, meta interface{})
|
|||
},
|
||||
}
|
||||
|
||||
if publicKey != "" {
|
||||
volume.Properties.SshKeys = []string{publicKey}
|
||||
if len(publicKeys) != 0 {
|
||||
volume.Properties.SshKeys = publicKeys
|
||||
|
||||
} else {
|
||||
volume.Properties.SshKeys = nil
|
||||
}
|
||||
jsn, _ := json.Marshal(volume)
|
||||
log.Printf("[INFO] volume: %s", string(jsn))
|
||||
|
||||
if _, ok := d.GetOk("availability_zone"); ok {
|
||||
raw := d.Get("availability_zone").(string)
|
||||
volume.Properties.AvailabilityZone = raw
|
||||
}
|
||||
|
||||
volume = profitbricks.CreateVolume(dcId, volume)
|
||||
|
||||
|
@ -169,9 +178,6 @@ func resourceProfitBricksVolumeRead(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
func resourceProfitBricksVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
properties := profitbricks.VolumeProperties{}
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
|
||||
|
@ -191,6 +197,10 @@ func resourceProfitBricksVolumeUpdate(d *schema.ResourceData, meta interface{})
|
|||
_, newValue := d.GetChange("bus")
|
||||
properties.Bus = newValue.(string)
|
||||
}
|
||||
if d.HasChange("availability_zone") {
|
||||
_, newValue := d.GetChange("availability_zone")
|
||||
properties.AvailabilityZone = newValue.(string)
|
||||
}
|
||||
|
||||
volume := profitbricks.PatchVolume(dcId, d.Id(), properties)
|
||||
err := waitTillProvisioned(meta, volume.Headers.Get("Location"))
|
||||
|
@ -216,9 +226,6 @@ func resourceProfitBricksVolumeUpdate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
func resourceProfitBricksVolumeDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
profitbricks.SetAuth(config.Username, config.Password)
|
||||
|
||||
dcId := d.Get("datacenter_id").(string)
|
||||
|
||||
resp := profitbricks.DeleteVolume(dcId, d.Id())
|
||||
|
|
|
@ -151,6 +151,12 @@ resource "profitbricks_datacenter" "foobar" {
|
|||
location = "us/las"
|
||||
}
|
||||
|
||||
resource "profitbricks_lan" "webserver_lan" {
|
||||
datacenter_id = "${profitbricks_datacenter.foobar.id}"
|
||||
public = true
|
||||
name = "public"
|
||||
}
|
||||
|
||||
resource "profitbricks_server" "webserver" {
|
||||
name = "webserver"
|
||||
datacenter_id = "${profitbricks_datacenter.foobar.id}"
|
||||
|
@ -166,7 +172,7 @@ resource "profitbricks_server" "webserver" {
|
|||
image_password = "test1234"
|
||||
}
|
||||
nic {
|
||||
lan = "1"
|
||||
lan = "${profitbricks_lan.webserver_lan.id}"
|
||||
dhcp = true
|
||||
firewall_active = true
|
||||
firewall {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package profitbricks
|
||||
|
||||
// Endpoint is the base url for REST requests .
|
||||
var Endpoint = "https://api.profitbricks.com/rest/v2"
|
||||
// Endpoint is the base url for REST requests.
|
||||
var Endpoint = "https://api.profitbricks.com/cloudapi/v3"
|
||||
|
||||
// Username for authentication .
|
||||
var Username string
|
||||
|
@ -21,3 +21,7 @@ func SetAuth(u, p string) {
|
|||
Username = u
|
||||
Passwd = p
|
||||
}
|
||||
|
||||
func SetUserAgent(userAgent string) {
|
||||
AgentHeader = userAgent
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ type Locations struct {
|
|||
}
|
||||
|
||||
type Properties struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Features []string `json:"features,omitempty"`
|
||||
}
|
||||
|
||||
// ListLocations returns location collection data
|
||||
|
|
|
@ -25,6 +25,7 @@ type NicProperties struct {
|
|||
Dhcp bool `json:"dhcp,omitempty"`
|
||||
Lan int `json:"lan,omitempty"`
|
||||
FirewallActive bool `json:"firewallActive,omitempty"`
|
||||
Nat bool `json:"nat,omitempty"`
|
||||
}
|
||||
|
||||
type NicEntities struct {
|
||||
|
|
|
@ -45,31 +45,11 @@ func location_path(locid string) string {
|
|||
return location_col_path() + slash(locid)
|
||||
}
|
||||
|
||||
// request_col_path returns the string "/requests"
|
||||
func request_col_path() string {
|
||||
return slash("requests")
|
||||
}
|
||||
|
||||
// request_path returns the string "/requests/<requestid>"
|
||||
func request_path(requestid string) string {
|
||||
return request_col_path() + slash(requestid)
|
||||
}
|
||||
|
||||
// request_status_path returns the string "/requests<requestid>/status"
|
||||
func request_status_path(requestid string) string {
|
||||
return request_path(requestid) + slash("status")
|
||||
}
|
||||
|
||||
// snapshot_col_path returns the string "/snapshots"
|
||||
func snapshot_col_path() string {
|
||||
return slash("snapshots")
|
||||
}
|
||||
|
||||
// snapshot_path returns the string "/snapshots/<snapid>"
|
||||
func snapshot_path(snapid string) string {
|
||||
return snapshot_col_path() + slash(snapid)
|
||||
}
|
||||
|
||||
// lan_col_path returns the string "/datacenters/<dcid>/lans"
|
||||
func lan_col_path(dcid string) string {
|
||||
return dc_path(dcid) + slash("lans")
|
||||
|
@ -115,12 +95,6 @@ func volume_path(dcid, volid string) string {
|
|||
return volume_col_path(dcid) + slash(volid)
|
||||
}
|
||||
|
||||
// lan_nic_col_path returns the string /datacenters/<dcid>/lans/<lanid>/nics
|
||||
func lan_nic_col(dcid, lanid string) string {
|
||||
return lan_path(dcid, lanid) + slash("nics")
|
||||
|
||||
}
|
||||
|
||||
// balnic_col_path returns the string "/loadbalancers/<lbalid>/balancednics"
|
||||
func balnic_col_path(dcid, lbalid string) string {
|
||||
return lbal_path(dcid, lbalid) + slash("balancednics")
|
||||
|
|
|
@ -9,10 +9,12 @@ import (
|
|||
)
|
||||
|
||||
//FullHeader is the standard header to include with all http requests except is_patch and is_command
|
||||
const FullHeader = "application/vnd.profitbricks.resource+json"
|
||||
const FullHeader = "application/json"
|
||||
|
||||
var AgentHeader = "profitbricks-sdk-go/3.0.1"
|
||||
|
||||
//PatchHeader is used with is_patch .
|
||||
const PatchHeader = "application/vnd.profitbricks.partial-properties+json"
|
||||
const PatchHeader = "application/json"
|
||||
|
||||
//CommandHeader is used with is_command
|
||||
const CommandHeader = "application/x-www-form-urlencoded"
|
||||
|
@ -32,7 +34,8 @@ func SetDepth(newdepth string) string {
|
|||
func mk_url(path string) string {
|
||||
if strings.HasPrefix(path, "http") {
|
||||
//REMOVE AFTER TESTING
|
||||
path := strings.Replace(path, "https://api.profitbricks.com/rest/v2", Endpoint, 1)
|
||||
//FIXME @jasmin Is this still relevant?
|
||||
path := strings.Replace(path, "https://api.profitbricks.com/cloudapi/v3", Endpoint, 1)
|
||||
// END REMOVE
|
||||
return path
|
||||
}
|
||||
|
@ -48,6 +51,7 @@ func mk_url(path string) string {
|
|||
func do(req *http.Request) Resp {
|
||||
client := &http.Client{}
|
||||
req.SetBasicAuth(Username, Passwd)
|
||||
req.Header.Add("User-Agent", AgentHeader)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -67,6 +71,7 @@ func is_delete(path string) Resp {
|
|||
url := mk_url(path)
|
||||
req, _ := http.NewRequest("DELETE", url, nil)
|
||||
req.Header.Add("Content-Type", FullHeader)
|
||||
req.Header.Add("User-Agent", AgentHeader)
|
||||
return do(req)
|
||||
}
|
||||
|
||||
|
@ -76,5 +81,6 @@ func is_command(path string, jason string) Resp {
|
|||
body := json.RawMessage(jason)
|
||||
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(body))
|
||||
req.Header.Add("Content-Type", CommandHeader)
|
||||
req.Header.Add("User-Agent", AgentHeader)
|
||||
return do(req)
|
||||
}
|
||||
|
|
|
@ -15,13 +15,6 @@ func MkJson(i interface{}) string {
|
|||
return string(jason)
|
||||
}
|
||||
|
||||
// MetaData is a map for metadata returned in a Resp.Body
|
||||
type StringMap map[string]string
|
||||
|
||||
type StringIfaceMap map[string]interface{}
|
||||
|
||||
type StringCollectionMap map[string]Collection
|
||||
|
||||
// Resp is the struct returned by all Rest request functions
|
||||
type Resp struct {
|
||||
Req *http.Request
|
||||
|
@ -36,26 +29,4 @@ func (r *Resp) PrintHeaders() {
|
|||
fmt.Println(key, " : ", value[0])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type Id_Type_Href struct {
|
||||
Id string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Href string `json:"href"`
|
||||
}
|
||||
|
||||
type MetaData StringIfaceMap
|
||||
|
||||
type Instance struct {
|
||||
Id_Type_Href
|
||||
MetaData StringMap `json:"metaData,omitempty"`
|
||||
Properties StringIfaceMap `json:"properties,omitempty"`
|
||||
Entities StringCollectionMap `json:"entities,omitempty"`
|
||||
Resp Resp `json:"-"`
|
||||
}
|
||||
|
||||
type Collection struct {
|
||||
Id_Type_Href
|
||||
Items []Instance `json:"items,omitempty"`
|
||||
Resp Resp `json:"-"`
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ package profitbricks
|
|||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"strings"
|
||||
"os"
|
||||
)
|
||||
|
||||
func mkdcid(name string) string {
|
||||
|
@ -55,18 +57,49 @@ func mknic(lbal_dcid, serverid string) string {
|
|||
fmt.Println("created a nic with id " + resp.Id)
|
||||
fmt.Println(resp.StatusCode)
|
||||
fmt.Println("===========================")
|
||||
waitTillProvisioned(resp.Headers.Get("Location"))
|
||||
return resp.Id
|
||||
}
|
||||
|
||||
func waitTillProvisioned(path string) {
|
||||
waitCount := 20
|
||||
waitCount := 120
|
||||
fmt.Println(path)
|
||||
for i := 0; i < waitCount; i++ {
|
||||
request := GetRequestStatus(path)
|
||||
if request.Metadata.Status == "DONE" {
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
time.Sleep(1 * time.Second)
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func getImageId(location string, imageName string, imageType string) string {
|
||||
if imageName == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
SetAuth(os.Getenv("PROFITBRICKS_USERNAME"), os.Getenv("PROFITBRICKS_PASSWORD"))
|
||||
|
||||
images := ListImages()
|
||||
if images.StatusCode > 299 {
|
||||
fmt.Printf("Error while fetching the list of images %s", images.Response)
|
||||
}
|
||||
|
||||
if len(images.Items) > 0 {
|
||||
for _, i := range images.Items {
|
||||
imgName := ""
|
||||
if i.Properties.Name != "" {
|
||||
imgName = i.Properties.Name
|
||||
}
|
||||
|
||||
if imageType == "SSD" {
|
||||
imageType = "HDD"
|
||||
}
|
||||
if imgName != "" && strings.Contains(strings.ToLower(imgName), strings.ToLower(imageName)) && i.Properties.ImageType == imageType && i.Properties.Location == location && i.Properties.Public == true {
|
||||
return i.Id
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type VolumeProperties struct {
|
|||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
AvailabilityZone string `json:"availabilityZone,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
ImagePassword string `json:"imagePassword,omitempty"`
|
||||
SshKeys []string `json:"sshKeys,omitempty"`
|
||||
|
|
|
@ -2331,10 +2331,10 @@
|
|||
"revisionTime": "2016-10-29T09:36:37Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "atkFfe1CrxF+Cz4p4Z78RMXC0Kg=",
|
||||
"checksumSHA1": "WPDz/Ed0OwaP7F/HvzZQ8OwT3fM=",
|
||||
"path": "github.com/profitbricks/profitbricks-sdk-go",
|
||||
"revision": "ccbdd70b24ec5c6cd000a34aba264d708c106af9",
|
||||
"revisionTime": "2016-07-28T11:13:56Z"
|
||||
"revision": "b279e1adcaf1c9cae4d6520c1bdbbf4674e7806e",
|
||||
"revisionTime": "2017-01-11T22:35:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "hcyoctYs0NjsvAXXVRc4mVt+FBg=",
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
layout: "profitbricks"
|
||||
page_title: "ProfitBricks : profitbricks_datacenter"
|
||||
sidebar_current: "docs-profitbricks-datasource-datacenter"
|
||||
description: |-
|
||||
Get information on a ProfitBricks Data Centers
|
||||
---
|
||||
|
||||
# profitbricks\_datacenter
|
||||
|
||||
The data centers data source can be used to search for and return an existing Virtual Data Center. You can provide a string for the name and location parameters which will be compared with provisioned Virtual Data Centers. If a single match is found, it will be returned. If your search results in multiple matches, an error will be generated. When this happens, please refine your search string so that it is specific enough to return only one result.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
data "profitbricks_datacenter" "dc_example" {
|
||||
name = "test_dc"
|
||||
location = "us"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
* `name` - (Required) Name or part of the name of an existing Virtual Data Center that you want to search for.
|
||||
* `location` - (Optional) Id of the existing Virtual Data Center's location.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
* `id` - UUID of the Virtual Data Center
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
layout: "profitbricks"
|
||||
page_title: "ProfitBricks : profitbrick_image"
|
||||
sidebar_current: "docs-profitbricks-datasource-image"
|
||||
description: |-
|
||||
Get information on a ProfitBricks Images
|
||||
---
|
||||
|
||||
# profitbricks\_image
|
||||
|
||||
The images data source can be used to search for and return an existing image which can then be used to provision a server.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
data "profitbricks_image" "image_example" {
|
||||
name = "Ubuntu"
|
||||
type = "HDD"
|
||||
version = "14"
|
||||
location = "location_id"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
* `name` - (Required) Name or part of the name of an existing image that you want to search for.
|
||||
* `version` - (Optional) Version of the image (see details below).
|
||||
* `location` - (Optional) Id of the existing image's location.
|
||||
* `type` - (Optional) The image type, HDD or CD-ROM.
|
||||
|
||||
If both "name" and "version" are provided the plugin will concatenate the two strings in this format [name]-[version].
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
* `id` - UUID of the image
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
layout: "profitbricks"
|
||||
page_title: "ProfitBricks : profitbrick_location"
|
||||
sidebar_current: "docs-profitbricks-datasource-location"
|
||||
description: |-
|
||||
Get information on a ProfitBricks Locations
|
||||
---
|
||||
|
||||
# profitbricks\_location
|
||||
|
||||
The locations data source can be used to search for and return an existing location which can then be used elsewhere in the configuration.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
data "profitbricks_location" "loc1" {
|
||||
name = "karlsruhe"
|
||||
feature = "SSD"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
* `name` - (Required) Name or part of the location name to search for.
|
||||
* `feature` - (Optional) A desired feature that the location must be able to provide.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
* `id` - UUID of the location
|
|
@ -31,4 +31,4 @@ resource "profitbricks_nic" "example" {
|
|||
* `dhcp` - (Optional) [boolean]
|
||||
* `ip` - (Optional) [string] IP assigned to the NIC.
|
||||
* `firewall_active` - (Optional) [boolean] If this resource is set to true and is nested under a server resource firewall, with open SSH port, resource must be nested under the nic.
|
||||
|
||||
* `nat` - (Optional) [boolean] Boolean value indicating if the private IP address has outbound access to the public internet.
|
||||
|
|
|
@ -21,7 +21,7 @@ resource "profitbricks_volume" "example" {
|
|||
image_name = "${var.ubuntu}"
|
||||
size = 5
|
||||
disk_type = "HDD"
|
||||
sshkey_path = "${var.private_key_path}"
|
||||
ssh_key_path = "${var.private_key_path}"
|
||||
bus = "VIRTIO"
|
||||
}
|
||||
```
|
||||
|
@ -33,7 +33,9 @@ resource "profitbricks_volume" "example" {
|
|||
* `disk_type` - (Required) [string] The volume type, HDD or SSD.
|
||||
* `bus` - (Required) [boolean] The bus type of the volume.
|
||||
* `size` - (Required)[integer] The size of the volume in GB.
|
||||
* `ssh_key_path` - (Required)[list] List of paths to files containing a public SSH key that will be injected into ProfitBricks provided Linux images. Required if `image_password` is not provided.
|
||||
* `image_password` - [string] Required if `sshkey_path` is not provided.
|
||||
* `image_name` - [string] The image or snapshot ID. It is required if `licence_type` is not provided.
|
||||
* `licence_type` - [string] Required if `image_name` is not provided.
|
||||
* `name` - (Optional) [string] The name of the volume.
|
||||
* `name` - (Optional) [string] The name of the volume.
|
||||
* `availability_zone` - (Optional) [string] The storage availability zone assigned to the volume. AUTO, ZONE_1, ZONE_2, or ZONE_3
|
Loading…
Reference in New Issue