Skip to content

Commit 8ab11b7

Browse files
committed
Finish and test opennebula_template resource implementation
1 parent 672c4d6 commit 8ab11b7

File tree

9 files changed

+457
-493
lines changed

9 files changed

+457
-493
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ _testmain.go
2424
*.prof
2525

2626
tmp/
27-
.env
27+
.env
28+
test.go

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ func main() {
99
plugin.Serve(&plugin.ServeOpts{
1010
ProviderFunc: opennebula.Provider,
1111
})
12-
}
12+
}

opennebula/client.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package opennebula
2+
3+
import (
4+
"fmt"
5+
"github.com/kolo/xmlrpc"
6+
"log"
7+
"strconv"
8+
)
9+
10+
type Client struct {
11+
Rcp xmlrpc.Client
12+
session string
13+
Username string
14+
Password string
15+
}
16+
17+
func NewClient(endpoint, username, password string) (*Client, error) {
18+
client, err := xmlrpc.NewClient(endpoint, nil)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
return &Client{
24+
Rcp: *client,
25+
session: fmt.Sprintf("%s:%s", username, password),
26+
Username: username,
27+
Password: password,
28+
}, nil
29+
}
30+
31+
func (c *Client) Call(command string, args ...interface{}) (string, error) {
32+
var result []interface{}
33+
34+
args = append([]interface{}{c.session}, args...)
35+
36+
if err := c.Rcp.Call(command, args, &result); err != nil {
37+
return "", err
38+
}
39+
40+
res, err := c.IsSuccess(result)
41+
if err != nil {
42+
return "", err
43+
}
44+
45+
return res, nil
46+
}
47+
48+
func (c *Client) IsSuccess(result []interface{}) (res string, err error) {
49+
if !result[0].(bool) {
50+
err = fmt.Errorf("%s", result[1].(string))
51+
return
52+
}
53+
54+
if w, ok := result[1].(int64); ok {
55+
res = strconv.FormatInt(w, 10)
56+
} else if w, ok := result[1].(string); ok {
57+
res = w
58+
}
59+
60+
return
61+
}
62+
63+
func intId(id string) int {
64+
i, err := strconv.Atoi(id)
65+
if err != nil {
66+
log.Fatalf("Unexpected ID %s received from OpenNebula. Expected an integer", id)
67+
}
68+
69+
return i
70+
}

opennebula/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
type Config struct {
99
Endpoint string
10-
User string
10+
User string
1111
Password string
1212
}
1313

@@ -22,4 +22,4 @@ func (c *Config) Client() (*api.Rpc, error) {
2222
log.Printf("[INFO] OpenNebula Client configured for URL: %s", c.Endpoint)
2323

2424
return api.NewClient(config)
25-
}
25+
}

opennebula/permissions.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package opennebula
2+
3+
import (
4+
"strconv"
5+
"strings"
6+
)
7+
8+
type Permissions struct {
9+
Owner_U int `xml:"OWNER_U"`
10+
Owner_M int `xml:"OWNER_M"`
11+
Owner_A int `xml:"OWNER_A"`
12+
Group_U int `xml:"GROUP_U"`
13+
Group_M int `xml:"GROUP_M"`
14+
Group_A int `xml:"GROUP_A"`
15+
Other_U int `xml:"OTHER_U"`
16+
Other_M int `xml:"OTHER_M"`
17+
Other_A int `xml:"OTHER_A"`
18+
}
19+
20+
func permissionString(p *Permissions) string {
21+
owner := p.Owner_U<<2 | p.Owner_M<<1 | p.Owner_A
22+
group := p.Group_U<<2 | p.Group_M<<1 | p.Group_A
23+
other := p.Other_U<<2 | p.Other_M<<1 | p.Other_A
24+
return strconv.Itoa(owner*100 + group*10 + other)
25+
}
26+
27+
func permission(p string) *Permissions {
28+
perms := strings.Split(p, "")
29+
owner, _ := strconv.Atoi(perms[0])
30+
group, _ := strconv.Atoi(perms[1])
31+
other, _ := strconv.Atoi(perms[2])
32+
33+
return &Permissions{
34+
Owner_U: owner & 4 >> 2,
35+
Owner_M: owner & 2 >> 1,
36+
Owner_A: owner & 1,
37+
Group_U: group & 4 >> 2,
38+
Group_M: group & 2 >> 1,
39+
Group_A: group & 1,
40+
Other_U: other & 4 >> 2,
41+
Other_M: other & 2 >> 1,
42+
Other_A: other & 1,
43+
}
44+
}

opennebula/provider.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ func Provider() terraform.ResourceProvider {
1212
Type: schema.TypeString,
1313
Required: true,
1414
Description: "The URL to your public or private OpenNebula",
15+
DefaultFunc: schema.EnvDefaultFunc("OPENNEBULA_ENDPOINT", nil),
1516
},
16-
"user": {
17+
"username": {
1718
Type: schema.TypeString,
1819
Required: true,
1920
Description: "The ID of the user to identify as",
21+
DefaultFunc: schema.EnvDefaultFunc("OPENNEBULA_USERNAME", nil),
2022
},
2123
"password": {
2224
Type: schema.TypeString,
2325
Required: true,
2426
Description: "The password for the user",
27+
DefaultFunc: schema.EnvDefaultFunc("OPENNEBULA_PASSWORD", nil),
2528
},
2629
},
2730

@@ -34,10 +37,9 @@ func Provider() terraform.ResourceProvider {
3437
}
3538

3639
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
37-
config := Config{
38-
Endpoint: d.Get("endpoint").(string),
39-
User: d.Get("user").(string),
40-
Password: d.Get("password").(string),
41-
}
42-
return config.Client()
40+
return NewClient(
41+
d.Get("endpoint").(string),
42+
d.Get("username").(string),
43+
d.Get("password").(string),
44+
)
4345
}

opennebula/provider_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package opennebula
22

33
import (
4-
"testing"
54
"github.com/hashicorp/terraform/helper/schema"
65
"github.com/hashicorp/terraform/terraform"
6+
"os"
7+
"testing"
78
)
89

910
func TestProvider(t *testing.T) {
@@ -14,4 +15,26 @@ func TestProvider(t *testing.T) {
1415

1516
func TestProvider_impl(t *testing.T) {
1617
var _ terraform.ResourceProvider = Provider()
17-
}
18+
}
19+
20+
var testAccProviders map[string]terraform.ResourceProvider
21+
var testAccProvider *schema.Provider
22+
23+
func init() {
24+
testAccProvider = Provider().(*schema.Provider)
25+
testAccProviders = map[string]terraform.ResourceProvider{
26+
"opennebula": testAccProvider,
27+
}
28+
}
29+
30+
func testAccPreCheck(t *testing.T) {
31+
testEnvIsSet("OPENNEBULA_ENDPOINT", t)
32+
testEnvIsSet("OPENNEBULA_USERNAME", t)
33+
testEnvIsSet("OPENNEBULA_PASSWORD", t)
34+
}
35+
36+
func testEnvIsSet(k string, t *testing.T) {
37+
if v := os.Getenv(k); v == "" {
38+
t.Fatalf("%s must be set for acceptance tests", k)
39+
}
40+
}

0 commit comments

Comments
 (0)