func resourceCLCPublicIPCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*clc.Client)
	sid := d.Get("server_id").(string)
	priv := d.Get("internal_ip_address").(string)
	ports, sources := parseIPSpec(d)
	req := server.PublicIP{
		Ports:              *ports,
		SourceRestrictions: *sources,
	}

	// since the API doesn't tell us the public IP it allocated,
	// track what was added after the call.
	ips := make(map[string]string)
	prev, err := client.Server.Get(sid)
	if err != nil {
		return fmt.Errorf("Failed finding server %v: %v", sid, err)
	}
	for _, i := range prev.Details.IPaddresses {
		ips[i.Internal] = i.Public
	}

	a, _ := json.Marshal(ips)
	LOG.Println(string(a))

	if priv != "" {
		// use existing private ip
		if _, present := ips[priv]; !present {
			return fmt.Errorf("Failed finding internal ip to use %v", priv)
		}
		req.InternalIP = priv
	}
	// execute the request
	resp, err := client.Server.AddPublicIP(sid, req)
	if err != nil {
		return fmt.Errorf("Failed reserving public ip: %v", err)
	}
	b, _ := json.Marshal(resp)
	LOG.Println(string(b))

	waitStatus(client, resp.ID)

	server, err := client.Server.Get(sid)
	if err != nil {
		return fmt.Errorf("Failed refreshing server for public ip: %v", err)
	}
	for _, i := range server.Details.IPaddresses {
		if priv != "" && i.Internal == priv {
			// bind
			LOG.Printf("Public IP bound on existing internal:%v - %v", i.Internal, i.Public)
			d.SetId(i.Public)
			break
		} else if ips[i.Internal] == "" && i.Public != "" {
			// allocate
			LOG.Printf("Public IP allocated on new internal:%v - %v", i.Internal, i.Public)
			d.SetId(i.Public)
			break
		}
	}
	return resourceCLCPublicIPRead(d, meta)
}
Example #2
0
func TestUpdatePublicIP(t *testing.T) {
	assert := assert.New(t)

	client := NewMockClient()
	client.On("Put", "http://localhost/v2/servers/test/va1testserver01/publicIPAddresses/10.0.0.1", mock.Anything, mock.Anything).Return(nil)
	service := server.New(client)

	addr := "10.0.0.1"
	name := "va1testserver01"
	ip := server.PublicIP{}
	ip.InternalIP = addr
	ip.Ports = []server.Port{server.Port{Protocol: "TCP", Port: 443}}

	resp, err := service.UpdatePublicIP(name, addr, ip)

	assert.Nil(err)
	assert.Equal("status", resp.Rel)
	client.AssertExpectations(t)
}