github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/ovh/resource_ovh_publiccloud_private_network.go (about) 1 package ovh 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 "github.com/ovh/go-ovh/ovh" 12 ) 13 14 func resourcePublicCloudPrivateNetwork() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourcePublicCloudPrivateNetworkCreate, 17 Read: resourcePublicCloudPrivateNetworkRead, 18 Update: resourcePublicCloudPrivateNetworkUpdate, 19 Delete: resourcePublicCloudPrivateNetworkDelete, 20 Importer: &schema.ResourceImporter{ 21 State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { 22 return []*schema.ResourceData{d}, nil 23 }, 24 }, 25 26 Schema: map[string]*schema.Schema{ 27 "project_id": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 DefaultFunc: schema.EnvDefaultFunc("OVH_PROJECT_ID", nil), 32 }, 33 "name": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: false, 37 }, 38 "vlan_id": &schema.Schema{ 39 Type: schema.TypeInt, 40 Optional: true, 41 ForceNew: true, 42 Default: 0, 43 }, 44 "regions": &schema.Schema{ 45 Type: schema.TypeSet, 46 Optional: true, 47 Computed: true, 48 ForceNew: true, 49 Elem: &schema.Schema{Type: schema.TypeString}, 50 Set: schema.HashString, 51 }, 52 53 "regions_status": &schema.Schema{ 54 Type: schema.TypeSet, 55 Computed: true, 56 Elem: &schema.Resource{ 57 Schema: map[string]*schema.Schema{ 58 "status": &schema.Schema{ 59 Type: schema.TypeString, 60 Required: true, 61 }, 62 63 "region": &schema.Schema{ 64 Type: schema.TypeString, 65 Computed: true, 66 }, 67 }, 68 }, 69 }, 70 "status": &schema.Schema{ 71 Type: schema.TypeString, 72 Computed: true, 73 }, 74 "type": &schema.Schema{ 75 Type: schema.TypeString, 76 Computed: true, 77 }, 78 }, 79 } 80 } 81 82 func resourcePublicCloudPrivateNetworkCreate(d *schema.ResourceData, meta interface{}) error { 83 config := meta.(*Config) 84 85 projectId := d.Get("project_id").(string) 86 params := &PublicCloudPrivateNetworkCreateOpts{ 87 ProjectId: d.Get("project_id").(string), 88 VlanId: d.Get("vlan_id").(int), 89 Name: d.Get("name").(string), 90 Regions: regionsOptsFromSchema(d), 91 } 92 93 r := &PublicCloudPrivateNetworkResponse{} 94 95 log.Printf("[DEBUG] Will create public cloud private network: %s", params) 96 97 endpoint := fmt.Sprintf("/cloud/project/%s/network/private", params.ProjectId) 98 99 err := config.OVHClient.Post(endpoint, params, r) 100 if err != nil { 101 return fmt.Errorf("calling %s with params %s:\n\t %q", endpoint, params, err) 102 } 103 104 log.Printf("[DEBUG] Waiting for Private Network %s:", r) 105 106 stateConf := &resource.StateChangeConf{ 107 Pending: []string{"BUILDING"}, 108 Target: []string{"ACTIVE"}, 109 Refresh: waitForPublicCloudPrivateNetworkActive(config.OVHClient, projectId, r.Id), 110 Timeout: 10 * time.Minute, 111 Delay: 10 * time.Second, 112 MinTimeout: 3 * time.Second, 113 } 114 115 _, err = stateConf.WaitForState() 116 if err != nil { 117 return fmt.Errorf("waiting for private network (%s): %s", params, err) 118 } 119 log.Printf("[DEBUG] Created Private Network %s", r) 120 121 //set id 122 d.SetId(r.Id) 123 124 return nil 125 } 126 127 func resourcePublicCloudPrivateNetworkRead(d *schema.ResourceData, meta interface{}) error { 128 config := meta.(*Config) 129 130 projectId := d.Get("project_id").(string) 131 132 r := &PublicCloudPrivateNetworkResponse{} 133 134 log.Printf("[DEBUG] Will read public cloud private network for project: %s, id: %s", projectId, d.Id()) 135 136 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, d.Id()) 137 138 d.Partial(true) 139 err := config.OVHClient.Get(endpoint, r) 140 if err != nil { 141 return fmt.Errorf("Error calling %s:\n\t %q", endpoint, err) 142 } 143 144 err = readPublicCloudPrivateNetwork(config, d, r) 145 if err != nil { 146 return err 147 } 148 d.Partial(false) 149 150 log.Printf("[DEBUG] Read Public Cloud Private Network %s", r) 151 return nil 152 } 153 154 func resourcePublicCloudPrivateNetworkUpdate(d *schema.ResourceData, meta interface{}) error { 155 config := meta.(*Config) 156 157 projectId := d.Get("project_id").(string) 158 params := &PublicCloudPrivateNetworkUpdateOpts{ 159 Name: d.Get("name").(string), 160 } 161 162 log.Printf("[DEBUG] Will update public cloud private network: %s", params) 163 164 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, d.Id()) 165 166 err := config.OVHClient.Put(endpoint, params, nil) 167 if err != nil { 168 return fmt.Errorf("calling %s with params %s:\n\t %q", endpoint, params, err) 169 } 170 171 log.Printf("[DEBUG] Updated Public cloud %s Private Network %s:", projectId, d.Id()) 172 173 return resourcePublicCloudPrivateNetworkRead(d, meta) 174 } 175 176 func resourcePublicCloudPrivateNetworkDelete(d *schema.ResourceData, meta interface{}) error { 177 config := meta.(*Config) 178 179 projectId := d.Get("project_id").(string) 180 id := d.Id() 181 182 log.Printf("[DEBUG] Will delete public cloud private network for project: %s, id: %s", projectId, id) 183 184 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, id) 185 186 err := config.OVHClient.Delete(endpoint, nil) 187 if err != nil { 188 return fmt.Errorf("calling %s:\n\t %q", endpoint, err) 189 } 190 191 stateConf := &resource.StateChangeConf{ 192 Pending: []string{"DELETING"}, 193 Target: []string{"DELETED"}, 194 Refresh: waitForPublicCloudPrivateNetworkDelete(config.OVHClient, projectId, id), 195 Timeout: 10 * time.Minute, 196 Delay: 10 * time.Second, 197 MinTimeout: 3 * time.Second, 198 } 199 200 _, err = stateConf.WaitForState() 201 if err != nil { 202 return fmt.Errorf("deleting for private network (%s): %s", id, err) 203 } 204 205 d.SetId("") 206 207 log.Printf("[DEBUG] Deleted Public Cloud %s Private Network %s", projectId, id) 208 return nil 209 } 210 211 func regionsOptsFromSchema(d *schema.ResourceData) []string { 212 var regions []string 213 if v := d.Get("regions"); v != nil { 214 rs := v.(*schema.Set).List() 215 if len(rs) > 0 { 216 for _, v := range v.(*schema.Set).List() { 217 regions = append(regions, v.(string)) 218 } 219 } 220 } 221 return regions 222 } 223 224 func readPublicCloudPrivateNetwork(config *Config, d *schema.ResourceData, r *PublicCloudPrivateNetworkResponse) error { 225 d.Set("name", r.Name) 226 d.Set("status", r.Status) 227 d.Set("type", r.Type) 228 d.Set("vlan_id", r.Vlanid) 229 230 regions_status := make([]map[string]interface{}, 0) 231 regions := make([]string, 0) 232 233 for i := range r.Regions { 234 region := make(map[string]interface{}) 235 region["region"] = r.Regions[i].Region 236 region["status"] = r.Regions[i].Status 237 regions_status = append(regions_status, region) 238 regions = append(regions, fmt.Sprintf(r.Regions[i].Region)) 239 } 240 d.Set("regions_status", regions_status) 241 d.Set("regions", regions) 242 243 d.SetId(r.Id) 244 return nil 245 } 246 247 func publicCloudPrivateNetworkExists(projectId, id string, c *ovh.Client) error { 248 r := &PublicCloudPrivateNetworkResponse{} 249 250 log.Printf("[DEBUG] Will read public cloud private network for project: %s, id: %s", projectId, id) 251 252 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, id) 253 254 err := c.Get(endpoint, r) 255 if err != nil { 256 return fmt.Errorf("calling %s:\n\t %q", endpoint, err) 257 } 258 log.Printf("[DEBUG] Read public cloud private network: %s", r) 259 260 return nil 261 } 262 263 // AttachmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 264 // an Attachment Task. 265 func waitForPublicCloudPrivateNetworkActive(c *ovh.Client, projectId, PublicCloudPrivateNetworkId string) resource.StateRefreshFunc { 266 return func() (interface{}, string, error) { 267 r := &PublicCloudPrivateNetworkResponse{} 268 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, PublicCloudPrivateNetworkId) 269 err := c.Get(endpoint, r) 270 if err != nil { 271 return r, "", err 272 } 273 274 log.Printf("[DEBUG] Pending Private Network: %s", r) 275 return r, r.Status, nil 276 } 277 } 278 279 // AttachmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 280 // an Attachment Task. 281 func waitForPublicCloudPrivateNetworkDelete(c *ovh.Client, projectId, PublicCloudPrivateNetworkId string) resource.StateRefreshFunc { 282 return func() (interface{}, string, error) { 283 r := &PublicCloudPrivateNetworkResponse{} 284 endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, PublicCloudPrivateNetworkId) 285 err := c.Get(endpoint, r) 286 if err != nil { 287 if err.(*ovh.APIError).Code == 404 { 288 log.Printf("[DEBUG] private network id %s on project %s deleted", PublicCloudPrivateNetworkId, projectId) 289 return r, "DELETED", nil 290 } else { 291 return r, "", err 292 } 293 } 294 log.Printf("[DEBUG] Pending Private Network: %s", r) 295 return r, r.Status, nil 296 } 297 }