Skip to content

Commit dcd2b01

Browse files
committed
Add server creation
This patch adds the ability to create a server with the given settings.
1 parent 92553e9 commit dcd2b01

File tree

5 files changed

+124
-1
lines changed

5 files changed

+124
-1
lines changed

online/client.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const (
2626
type Client interface {
2727
Server(id int) (*Server, error)
2828
SetServer(s *Server) error
29+
CreateServer(id int, s *ServerInstall) error
2930

3031
BootRescueMode(serverID int, image string) (*RescueCredentials, error)
3132
BootNormalMode(serverID int) error
@@ -165,6 +166,20 @@ func (c *client) Server(id int) (*Server, error) {
165166
return s, json.Unmarshal(js, s)
166167
}
167168

169+
func (c *client) CreateServer(id int, s *ServerInstall) error {
170+
target := fmt.Sprintf("%s/install/%d", serverEndPoint, id)
171+
var req map[string]string
172+
inreq, _ := json.Marshal(s)
173+
json.Unmarshal(inreq, &req)
174+
175+
_, err := c.doPOST(target, req)
176+
if err != nil {
177+
return err
178+
}
179+
180+
return nil
181+
}
182+
168183
func (c *client) ListRPNv2() ([]*RPNv2, error) {
169184
js, err := c.doGET(rpnv2EndPoint)
170185
if err != nil {

online/mock/mock.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ func (o *OnlineClientMock) SetServer(s *online.Server) error {
2424
return args.Error(0)
2525
}
2626

27+
// CreateServer is a mock call
28+
func (o *OnlineClientMock) CreateServer(id int, s *online.ServerInstall) error {
29+
args := o.Called(id, s)
30+
return args.Error(0)
31+
}
32+
2733
// GetRescueImages is a mock call
2834
func (o *OnlineClientMock) GetRescueImages(serverID int) ([]string, error) {
2935
args := o.Called(serverID)

online/server.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type Server struct {
77
OS interface{} `json:"os"`
88
Power string `json:"power"`
99
BootMode string `json:"boot_mode"`
10+
InstallStatus string `json:"install_status"`
1011
LastReboot string `json:"last_reboot"`
1112
AntiDDOS bool `json:"anti_ddos"`
1213
HardwareWatch bool `json:"hardware_watch"`
@@ -44,6 +45,15 @@ type Server struct {
4445
} `json:"bmc"`
4546
}
4647

48+
type ServerInstall struct {
49+
Hostname string `json:"hostname"`
50+
OS_ID string `json:"os_id"`
51+
UserLogin string `json:"user_login"`
52+
UserPassword string `json:"user_password"`
53+
RootPassword string `json:"root_password"`
54+
PartitioningTemplateRef string `json:"partitioning_template_ref"`
55+
}
56+
4757
type OS struct {
4858
Name string `json:"name"`
4959
Version string `json:"version"`

provider/resource_server.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package provider
33
import (
44
"strconv"
55
"strings"
6+
"time"
67

8+
"github.com/hashicorp/terraform/helper/resource"
79
"github.com/hashicorp/terraform/helper/schema"
810
"github.com/src-d/terraform-provider-online/online"
911
)
@@ -40,6 +42,41 @@ func resourceServer() *schema.Resource {
4042
Elem: resourceInterface(),
4143
Description: "Private interface properties",
4244
},
45+
"os_id": &schema.Schema{
46+
Type: schema.TypeString,
47+
Required: true,
48+
ForceNew: true,
49+
Description: "OS id, use the following command to select one " +
50+
"`curl -s -H \"Authorization: Bearer $ONLINE_TOKEN\" " +
51+
"https://api.online.net/api/v1/server/operatingSystems/{server id}`",
52+
},
53+
"user_login": &schema.Schema{
54+
Type: schema.TypeString,
55+
Required: true,
56+
Description: "User login",
57+
},
58+
"user_password": &schema.Schema{
59+
Type: schema.TypeString,
60+
Required: true,
61+
Description: "User password",
62+
},
63+
"root_password": &schema.Schema{
64+
Type: schema.TypeString,
65+
Required: true,
66+
Description: "Root password",
67+
},
68+
"partitioning_template_ref": &schema.Schema{
69+
Type: schema.TypeString,
70+
Required: true,
71+
ForceNew: true,
72+
Description: "UUID of the partitioning template created from " +
73+
"https://console.online.net/fr/template/partition",
74+
},
75+
"status": &schema.Schema{
76+
Type: schema.TypeString,
77+
Computed: true,
78+
Description: "Install status",
79+
},
4380
},
4481
}
4582
}
@@ -71,9 +108,48 @@ func resourceServerDelete(d *schema.ResourceData, meta interface{}) error {
71108
}
72109

73110
func resourceServerCreate(d *schema.ResourceData, meta interface{}) error {
111+
c := meta.(online.Client)
112+
s := &online.ServerInstall{
113+
Hostname: d.Get("hostname").(string),
114+
OS_ID: d.Get("os_id").(string),
115+
UserLogin: d.Get("user_login").(string),
116+
UserPassword: d.Get("user_password").(string),
117+
RootPassword: d.Get("root_password").(string),
118+
PartitioningTemplateRef: d.Get("partitioning_template_ref").(string),
119+
}
120+
id := d.Get("server_id").(int)
121+
122+
if err := c.CreateServer(id, s); err != nil {
123+
return err
124+
}
125+
126+
stateConf := &resource.StateChangeConf{
127+
Pending: []string{"installing"},
128+
Target: []string{"installed"},
129+
Refresh: waitForServerInstall(c, id),
130+
Timeout: 60 * time.Minute,
131+
Delay: 1 * time.Second,
132+
MinTimeout: 10 * time.Second,
133+
}
134+
135+
_, err := stateConf.WaitForState()
136+
if err != nil {
137+
return err
138+
}
139+
74140
return resourceServerRead(d, meta)
75141
}
76142

143+
func waitForServerInstall(c online.Client, id int) resource.StateRefreshFunc {
144+
return func() (interface{}, string, error) {
145+
s, err := c.Server(id)
146+
if err != nil {
147+
return s, "", err
148+
}
149+
return s, s.InstallStatus, nil
150+
}
151+
}
152+
77153
func resourceServerUpdate(d *schema.ResourceData, meta interface{}) error {
78154
c := meta.(online.Client)
79155
s := &online.Server{
@@ -106,6 +182,7 @@ func resourceServerRead(d *schema.ResourceData, meta interface{}) error {
106182
d.SetId(strconv.Itoa(id))
107183
d.Set("hostname", s.Hostname)
108184
setIP(s, d)
185+
d.Set("status", s.InstallStatus)
109186

110187
return nil
111188
}

provider/resource_server_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ func setupMock() {
1414
Hostname: "mock",
1515
}).Return(nil)
1616
onlineClientMock.On("Server", 123).Return(&online.Server{
17-
Hostname: "mock",
17+
Hostname: "mock",
18+
InstallStatus: "installed",
1819
IP: []*online.Interface{
1920
&online.Interface{
2021
Address: "1.2.3.4",
@@ -29,6 +30,14 @@ func setupMock() {
2930
},
3031
},
3132
}, nil)
33+
onlineClientMock.On("CreateServer", 123, &online.ServerInstall{
34+
Hostname: "mock",
35+
OS_ID: "101",
36+
UserLogin: "user1",
37+
UserPassword: "pass1",
38+
RootPassword: "rootpass",
39+
PartitioningTemplateRef: "81c651de-030b-41f3-8094-36f423375234",
40+
}).Return(nil)
3241
}
3342

3443
func TestResourceServerUnit(t *testing.T) {
@@ -42,6 +51,11 @@ func TestResourceServerUnit(t *testing.T) {
4251
resource "online_server" "test" {
4352
server_id = 123
4453
hostname = "mock"
54+
os_id = "101"
55+
user_login = "user1"
56+
user_password = "pass1"
57+
root_password = "rootpass"
58+
partitioning_template_ref = "81c651de-030b-41f3-8094-36f423375234"
4559
}
4660
`,
4761
Check: resource.ComposeAggregateTestCheckFunc(
@@ -52,6 +66,7 @@ func TestResourceServerUnit(t *testing.T) {
5266
resource.TestCheckResourceAttr("online_server.test", "public_interface.dns", "my.dns.address"),
5367
resource.TestCheckResourceAttr("online_server.test", "private_interface.address", "10.2.3.4"),
5468
resource.TestCheckResourceAttr("online_server.test", "private_interface.mac", "00:bb:cc:dd:ee:ff"),
69+
resource.TestCheckResourceAttr("online_server.test", "status", "installed"),
5570
),
5671
}},
5772
})

0 commit comments

Comments
 (0)