Skip to content

Commit ac99702

Browse files
committed
Initial implementation.
1 parent 2c83e8d commit ac99702

File tree

9 files changed

+785
-0
lines changed

9 files changed

+785
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Folders
77
_obj
88
_test
9+
_bin
910

1011
# Architecture specific extensions/prefixes
1112
*.[568vq]
@@ -22,3 +23,6 @@ _testmain.go
2223
*.exe
2324
*.test
2425
*.prof
26+
27+
# Version info
28+
version-info.go

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "vendor/github.com/DimensionDataResearch/go-dd-cloud-compute"]
2+
path = vendor/github.com/DimensionDataResearch/go-dd-cloud-compute
3+
url = https://github.com/DimensionDataResearch/go-dd-cloud-compute.git

Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
default: fmt build test
2+
3+
fmt:
4+
go fmt github.com/DimensionDataResearch/docker-machine-driver-ddcloud/...
5+
6+
# Peform a development (current-platform-only) build.
7+
dev: version fmt
8+
go build -o _bin/docker-machine-driver-ddcloud
9+
10+
# Perform a full (all-platforms) build.
11+
build: version build-windows64 build-linux64 build-mac64
12+
13+
build-windows64:
14+
GOOS=windows GOARCH=amd64 go build -o _bin/windows-amd64/docker-machine-driver-ddcloud.exe
15+
16+
build-linux64:
17+
GOOS=linux GOARCH=amd64 go build -o _bin/linux-amd64/docker-machine-driver-ddcloud
18+
19+
build-mac64:
20+
GOOS=darwin GOARCH=amd64 go build -o _bin/darwin-amd64/docker-machine-driver-ddcloud
21+
22+
# Produce archives for a GitHub release.
23+
dist: build
24+
zip -9 _bin/windows-amd64.zip _bin/windows-amd64/docker-machine-driver-ddcloud.exe
25+
zip -9 _bin/linux-amd64.zip _bin/linux-amd64/docker-machine-driver-ddcloud
26+
zip -9 _bin/darwin-amd64.zip _bin/darwin-amd64/docker-machine-driver-ddcloud
27+
28+
test: fmt
29+
go test -v github.com/DimensionDataResearch/docker-machine-driver-ddcloud/...
30+
31+
version:
32+
echo "package main\n\n// ProviderVersion is the current version of the CloudControl driver for Docker Machine.\nconst ProviderVersion = \"v0.1 (`git rev-parse HEAD`)\"" > ./version-info.go

client.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"github.com/DimensionDataResearch/go-dd-cloud-compute/compute"
7+
"github.com/docker/machine/libmachine/log"
8+
"time"
9+
)
10+
11+
// Get the CloudControl API client used by the driver.
12+
func (driver *Driver) getCloudControlClient() (client *compute.Client, err error) {
13+
client = driver.client
14+
if client != nil {
15+
return
16+
}
17+
18+
if driver.CloudControlUser == "" {
19+
err = errors.New("Cannot connect to CloudControl API (user name has not been configured)")
20+
21+
return
22+
}
23+
24+
if driver.CloudControlPassword == "" {
25+
err = errors.New("Cannot connect to CloudControl API (password has not been configured)")
26+
27+
return
28+
}
29+
30+
if driver.CloudControlRegion == "" {
31+
err = errors.New("Cannot connect to CloudControl API (region not been configured)")
32+
33+
return
34+
}
35+
36+
driver.client = compute.NewClient(driver.CloudControlRegion, driver.CloudControlUser, driver.CloudControlPassword)
37+
38+
return
39+
}
40+
41+
// Determine whether the target server has been created.
42+
func (driver *Driver) isServerCreated() bool {
43+
return driver.ServerID != ""
44+
}
45+
46+
// Retrieve the target server (must have been created, or an error is returned).
47+
func (driver *Driver) getServer() (*compute.Server, error) {
48+
if !driver.isServerCreated() {
49+
return nil, errors.New("Server has not been created")
50+
}
51+
52+
client, err := driver.getCloudControlClient()
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return client.GetServer(driver.ServerID)
58+
}
59+
60+
// Retrieve the target network domain.
61+
func (driver *Driver) getNetworkDomain() (*compute.NetworkDomain, error) {
62+
if driver.NetworkDomainID == "" {
63+
return nil, errors.New("Network domain Id has not been configured")
64+
}
65+
66+
client, err := driver.getCloudControlClient()
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
return client.GetNetworkDomain(driver.ServerID)
72+
}
73+
74+
// Retrieve the target VLAN.
75+
func (driver *Driver) getVLAN() (*compute.VLAN, error) {
76+
if driver.VLANID == "" {
77+
return nil, errors.New("VLAN Id has not been configured")
78+
}
79+
80+
client, err := driver.getCloudControlClient()
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
return client.GetVLAN(driver.VLANID)
86+
}
87+
88+
// Resolve (find) the target OS image.
89+
func (driver *Driver) resolveOSImage() error {
90+
if driver.ImageID != "" {
91+
return nil
92+
}
93+
94+
networkDomain, err := driver.getNetworkDomain()
95+
if err != nil {
96+
return err
97+
}
98+
99+
client, err := driver.getCloudControlClient()
100+
if err != nil {
101+
return err
102+
}
103+
104+
// Find target OS image.
105+
log.Info("Searching for image '%s' in data centre '%s'...", driver.ImageName, networkDomain.DatacenterID)
106+
107+
image, err := client.FindOSImage(driver.ImageName, networkDomain.DatacenterID)
108+
if err == nil {
109+
return err
110+
}
111+
if image == nil {
112+
log.Errorf("OS image '%s' was not found in data centre '%s'.", driver.ImageName, networkDomain.DatacenterID)
113+
114+
return fmt.Errorf("OS image '%s' was not found in data centre '%s'", driver.ImageName, networkDomain.DatacenterID)
115+
}
116+
117+
driver.ImageID = image.ID
118+
119+
return nil
120+
}
121+
122+
// Retrieve the target OS image.
123+
func (driver *Driver) getOSImage() (*compute.OSImage, error) {
124+
if driver.ImageID == "" {
125+
return nil, errors.New("Image Id has not been resolved")
126+
}
127+
128+
client, err := driver.getCloudControlClient()
129+
if err != nil {
130+
return nil, err
131+
}
132+
133+
return client.GetOSImage(driver.ImageID)
134+
}
135+
136+
func (driver *Driver) deployServer() (*compute.Server, error) {
137+
if driver.isServerCreated() {
138+
return nil, fmt.Errorf("Server '%s' already exists (Id = '%s')", driver.MachineName, driver.ServerID)
139+
}
140+
141+
serverConfiguration, err := driver.buildDeploymentConfiguration()
142+
if err != nil {
143+
return nil, err
144+
}
145+
146+
client, err := driver.getCloudControlClient()
147+
if err != nil {
148+
return nil, err
149+
}
150+
151+
driver.ServerID, err = client.DeployServer(serverConfiguration)
152+
if err != nil {
153+
return nil, err
154+
}
155+
156+
log.Debug("Deploying server '%s' ('%s')...", driver.ServerID, driver.MachineName)
157+
158+
log.Info("Server '%s' is being provisioned...")
159+
resource, err := client.WaitForDeploy(compute.ResourceTypeServer, driver.ServerID, 15*time.Minute)
160+
if err != nil {
161+
return nil, err
162+
}
163+
server := resource.(*compute.Server)
164+
log.Debug("Server '%s' ('%s') has been successfully provisioned...", driver.ServerID, server.Name)
165+
166+
driver.IPAddress = *server.Network.PrimaryAdapter.PrivateIPv4Address
167+
log.Info("Server '%s' has private IP '%s'.", server.Name, driver.IPAddress)
168+
169+
return server, nil
170+
}
171+
172+
// Build a deployment configuration for the target server.
173+
func (driver *Driver) buildDeploymentConfiguration() (deploymentConfiguration compute.ServerDeploymentConfiguration, err error) {
174+
var image *compute.OSImage
175+
image, err = driver.getOSImage()
176+
if err != nil {
177+
return
178+
}
179+
if image == nil {
180+
err = fmt.Errorf("OS image '%s' not found", driver.ImageID)
181+
182+
return
183+
}
184+
185+
deploymentConfiguration = compute.ServerDeploymentConfiguration{
186+
Name: driver.MachineName,
187+
Description: fmt.Sprintf("%s (created by Docker Machine).", driver.MachineName),
188+
AdministratorPassword: driver.SSHBootstrapPassword,
189+
190+
Network: compute.VirtualMachineNetwork{
191+
NetworkDomainID: driver.NetworkDomainID,
192+
PrimaryAdapter: compute.VirtualMachineNetworkAdapter{
193+
VLANID: &driver.VLANID,
194+
},
195+
},
196+
PrimaryDNS: "8.8.8.8",
197+
SecondaryDNS: "8.8.4.4",
198+
199+
Start: true,
200+
}
201+
deploymentConfiguration.ApplyOSImage(image)
202+
203+
return
204+
}

0 commit comments

Comments
 (0)