Skip to content

Commit b6f443c

Browse files
committed
Initial commit.
0 parents  commit b6f443c

17 files changed

+709
-0
lines changed

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Compiled Object files, Static and Dynamic libs (Shared Objects)
2+
*.o
3+
*.a
4+
*.so
5+
6+
# Folders
7+
_obj
8+
_test
9+
_bin
10+
11+
# Architecture specific extensions/prefixes
12+
*.[568vq]
13+
[568vq].out
14+
15+
*.cgo1.go
16+
*.cgo2.c
17+
_cgo_defun.c
18+
_cgo_gotypes.go
19+
_cgo_export.*
20+
21+
_testmain.go
22+
23+
*.exe
24+
*.test
25+
*.prof
26+
27+
# Mac
28+
.DS_Store
29+
30+
# Version info
31+
version-info.go
32+
33+
# Test logs
34+
AccTest.log

.gitmodules

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

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Dimension Data Research
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
default: version test build
2+
3+
fmt:
4+
go fmt github.com/DimensionDataResearch/dd-tf-export
5+
6+
# Peform a development (current-platform-only) build.
7+
dev: fmt
8+
go build -o _bin/dd-tf-export
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/dd-tf-export.exe
15+
16+
build-linux64:
17+
GOOS=linux GOARCH=amd64 go build -o _bin/linux-amd64/dd-tf-export
18+
19+
build-mac64:
20+
GOOS=darwin GOARCH=amd64 go build -o _bin/darwin-amd64/dd-tf-export
21+
22+
# Produce archives for a GitHub release.
23+
dist: build
24+
zip -9 _bin/windows-amd64.zip _bin/windows-amd64/dd-tf-export.exe
25+
zip -9 _bin/linux-amd64.zip _bin/linux-amd64/dd-tf-export
26+
zip -9 _bin/darwin-amd64.zip _bin/darwin-amd64/dd-tf-export
27+
28+
test: fmt
29+
go test -v github.com/DimensionDataResearch/dd-tf-export
30+
31+
version:
32+
echo "package main\n\n// ProgramVersion is the current version of the DD Cloud Compute terraform exporter.\nconst ProgramVersion = \"v0.1 (`git rev-parse HEAD`)\"" > ./version-info.go

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# dd-tf-export
2+
Tool that generates [Terraform](https://terraform.io/) configuration from existing resources in Dimension Data cloud compute.

client.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"compute-api/compute"
5+
"fmt"
6+
"os"
7+
)
8+
9+
const (
10+
// EnvComputeUser is the name of the DD_COMPUTE_USER environment variable.
11+
EnvComputeUser = "DD_COMPUTE_USER"
12+
13+
// EnvComputePassword is the name of the DD_COMPUTE_PASSWORD environment variable.
14+
EnvComputePassword = "DD_COMPUTE_PASSWORD"
15+
)
16+
17+
func createClient(options programOptions) (client *compute.Client, err error) {
18+
username := os.Getenv(EnvComputeUser)
19+
if isEmpty(username) {
20+
err = fmt.Errorf("The %s environment variable is not defined. Please set it to the CloudControl user name you wish to use.", EnvComputeUser)
21+
22+
return
23+
}
24+
25+
password := os.Getenv(EnvComputePassword)
26+
if isEmpty(password) {
27+
err = fmt.Errorf("The %s environment variable is not defined. Please set it to the CloudControl password you wish to use.", EnvComputePassword)
28+
29+
return
30+
}
31+
32+
client = compute.NewClient(options.Region, username, password)
33+
34+
return
35+
}

export.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"compute-api/compute"
5+
"fmt"
6+
)
7+
8+
// Exporter is used to export CloudControl resources to Terraform configuration.
9+
type Exporter struct {
10+
APIClient *compute.Client
11+
}
12+
13+
const configurationTemplateProvider = `provider "ddcloud" {
14+
region = "%s"
15+
}
16+
17+
`
18+
19+
// ExportProviderConfiguration exports the configuration for the ddcloud provider.
20+
func (exporter *Exporter) ExportProviderConfiguration(region string) {
21+
fmt.Printf(configurationTemplateProvider, region)
22+
}
23+
24+
func createExporter(options programOptions) (exporter *Exporter, err error) {
25+
var apiClient *compute.Client
26+
apiClient, err = createClient(options)
27+
if err != nil {
28+
return
29+
}
30+
31+
exporter = &Exporter{
32+
APIClient: apiClient,
33+
}
34+
35+
return
36+
}

export_firewall_rule.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package main
2+
3+
import (
4+
"compute-api/compute"
5+
"fmt"
6+
"strings"
7+
)
8+
9+
func makeFirewallRuleResourceName(uniquenessKey int) string {
10+
return fmt.Sprintf("firewall_rule%02d", uniquenessKey)
11+
}
12+
13+
const configurationTemplateFirewallRule = `
14+
resource "ddcloud_firewall_rule" "%s" {
15+
name = "%s"
16+
placement = "first"
17+
action = "%s"
18+
enabled = %t
19+
20+
ip_version = "%s"
21+
protocol = "%s"
22+
23+
%s= "%s"
24+
source_port = "%s"
25+
26+
%s= "%s"
27+
destination_port = "%s"
28+
29+
networkdomain = "%s"
30+
}
31+
`
32+
33+
// ExportFirewallRule exports a ddcloud_firewallRule resource to Terraform configuration.
34+
func (exporter *Exporter) ExportFirewallRule(firewallRule compute.FirewallRule, networkDomainID string, uniquenessKey int) error {
35+
if firewallRule.RuleType == "DEFAULT_RULE" {
36+
return nil // Ignore built-in rules.
37+
}
38+
39+
var (
40+
sourceLabel string
41+
source string
42+
sourcePort string
43+
destinationLabel string
44+
destination string
45+
destinationPort string
46+
)
47+
if firewallRule.Source.Port != nil {
48+
sourcePort = fmt.Sprintf("%d", firewallRule.Source.Port.Begin)
49+
} else {
50+
sourcePort = "any"
51+
}
52+
53+
sourceAddress := firewallRule.Source.IPAddress
54+
if sourceAddress != nil {
55+
if sourceAddress.PrefixSize != nil {
56+
sourceLabel = "source_network "
57+
source = fmt.Sprintf("%s/%d", sourceAddress.Address, *sourceAddress.PrefixSize)
58+
} else {
59+
sourceLabel = "source_address "
60+
source = strings.ToLower(firewallRule.Source.IPAddress.Address)
61+
}
62+
}
63+
if firewallRule.Destination.Port != nil {
64+
destinationPort = fmt.Sprintf("%d", firewallRule.Destination.Port.Begin)
65+
} else {
66+
destinationPort = "any"
67+
}
68+
destinationAddress := firewallRule.Destination.IPAddress
69+
if destinationAddress != nil {
70+
if destinationAddress.PrefixSize != nil {
71+
destinationLabel = "destination_network "
72+
destination = fmt.Sprintf("%s/%d", destinationAddress.Address, *destinationAddress.PrefixSize)
73+
} else {
74+
destinationLabel = "destination_address "
75+
destination = strings.ToLower(firewallRule.Destination.IPAddress.Address)
76+
}
77+
}
78+
79+
configuration := strings.TrimSpace(
80+
fmt.Sprintf(configurationTemplateFirewallRule,
81+
makeFirewallRuleResourceName(uniquenessKey),
82+
firewallRule.Name,
83+
convertFirewallAction(firewallRule.Action),
84+
firewallRule.Enabled,
85+
firewallRule.IPVersion,
86+
firewallRule.Protocol,
87+
sourceLabel,
88+
source,
89+
sourcePort,
90+
destinationLabel,
91+
destination,
92+
destinationPort,
93+
networkDomainID,
94+
),
95+
)
96+
fmt.Println(configuration)
97+
98+
return nil
99+
}
100+
101+
func convertFirewallAction(action string) string {
102+
switch action {
103+
case "ACCEPT_DECISIVELY":
104+
return "accept"
105+
case "DROP":
106+
return "DROP"
107+
default:
108+
return "UNKNOWN"
109+
}
110+
}

export_nat.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"compute-api/compute"
5+
"fmt"
6+
"strings"
7+
)
8+
9+
func makeNATResourceName(uniquenessKey int) string {
10+
return fmt.Sprintf("nat%02d", uniquenessKey)
11+
}
12+
13+
const configurationTemplateNAT = `
14+
resource "ddcloud_nat" "%s" {
15+
networkdomain = "%s"
16+
private_ipv4 = "%s"
17+
18+
# public_ipv4 = "%s"%s
19+
}
20+
`
21+
22+
const configurationTemplateNATDependsOnVLAN = `
23+
24+
depends_on = ["ddcloud_vlan.%s"]`
25+
26+
// ExportNAT exports a ddcloud_nat resource to Terraform configuration.
27+
func (exporter *Exporter) ExportNAT(natRule compute.NATRule, networkDomainID string, vlanResourceName string, serverResourceName string, uniquenessKey int) error {
28+
natDependsOnVLANConfiguration := ""
29+
if vlanResourceName != "" {
30+
natDependsOnVLANConfiguration = fmt.Sprintf(configurationTemplateNATDependsOnVLAN, vlanResourceName)
31+
}
32+
33+
natInternalAddress := natRule.InternalIPAddress
34+
if serverResourceName != "" {
35+
natInternalAddress = fmt.Sprintf("${ddcloud_server.%s.id}", serverResourceName)
36+
}
37+
38+
configuration := strings.TrimSpace(
39+
fmt.Sprintf(configurationTemplateNAT,
40+
makeNATResourceName(uniquenessKey),
41+
networkDomainID,
42+
natInternalAddress,
43+
natRule.ExternalIPAddress,
44+
natDependsOnVLANConfiguration,
45+
),
46+
)
47+
fmt.Println(configuration)
48+
49+
return nil
50+
}

0 commit comments

Comments
 (0)