Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.

Commit cb07f10

Browse files
authored
Cisco UCS InfraKit plugin (#743)
- Vendoring for UCS pkg requirements - Simple plugin code (only login implemented, whilst waiting for a environment) Signed-off-by: Dan Finneran <[email protected]>
1 parent a8cb7e2 commit cb07f10

File tree

20 files changed

+2391
-0
lines changed

20 files changed

+2391
-0
lines changed

cmd/infrakit/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import (
6363
_ "github.com/docker/infrakit/pkg/run/v0/tailer"
6464
_ "github.com/docker/infrakit/pkg/run/v0/terraform"
6565
_ "github.com/docker/infrakit/pkg/run/v0/time"
66+
_ "github.com/docker/infrakit/pkg/run/v0/ucs"
6667
_ "github.com/docker/infrakit/pkg/run/v0/vagrant"
6768
_ "github.com/docker/infrakit/pkg/run/v0/vanilla"
6869
_ "github.com/docker/infrakit/pkg/run/v0/vars"

pkg/provider/ucs/plugin.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package ucs
2+
3+
import (
4+
"fmt"
5+
"math/rand"
6+
"os"
7+
"time"
8+
9+
logutil "github.com/docker/infrakit/pkg/log"
10+
"github.com/docker/infrakit/pkg/spi"
11+
"github.com/docker/infrakit/pkg/spi/instance"
12+
"github.com/docker/infrakit/pkg/types"
13+
"github.com/micdoher/terraform-provider-ucs/ucsclient"
14+
)
15+
16+
var log = logutil.New("module", "cli/x")
17+
18+
// Options capture the config parameters required to create the plugin
19+
type Options struct {
20+
UCSUrl string
21+
UCSUser string
22+
UCSPass string
23+
UCSCookie string
24+
}
25+
26+
//miniFSM for managing the provisioning -> provisioned state
27+
type provisioningFSM struct {
28+
countdown int64 // ideally will be a counter of minutes / seconds
29+
tags map[string]string // tags that will be passed back per a describe function
30+
instanceName string // name that we will use as a lookup to the actual backend that is privisioning
31+
}
32+
33+
// Spec is just whatever that can be unmarshalled into a generic JSON map
34+
type Spec map[string]interface{}
35+
36+
// This contains the the details for the oneview instance
37+
type plugin struct {
38+
fsm []provisioningFSM
39+
client *ucsclient.UCSClient
40+
}
41+
42+
func init() {
43+
rand.Seed(time.Now().UTC().UnixNano())
44+
}
45+
46+
// NewUCSInstancePlugin will take the cmdline/env configuration
47+
func NewUCSInstancePlugin(ucsOptions Options) instance.Plugin {
48+
49+
ucsConfig := ucsclient.Config{
50+
AppName: "UCS",
51+
IpAddress: ucsOptions.UCSUrl,
52+
Username: ucsOptions.UCSUser,
53+
Password: ucsOptions.UCSPass,
54+
TslInsecureSkipVerify: true, // TODO - Make configurable
55+
LogFilename: "./ucs.log",
56+
LogLevel: 0,
57+
}
58+
59+
client := ucsConfig.Client()
60+
err := client.Login()
61+
// Exit with an error if we can't connect to Cisco UCS Domain
62+
if err != nil {
63+
log.Crit("Error Logging into Cisco UCS Domain")
64+
os.Exit(-1)
65+
}
66+
67+
log.Info("Succesfully logged in to UCS Domain")
68+
69+
return &plugin{
70+
client: client,
71+
}
72+
}
73+
74+
// Info returns a vendor specific name and version
75+
func (p *plugin) VendorInfo() *spi.VendorInfo {
76+
return &spi.VendorInfo{
77+
InterfaceSpec: spi.InterfaceSpec{
78+
Name: "infrakit-instance-ucs",
79+
Version: "0.6.0",
80+
},
81+
URL: "https://github.com/docker/infrakit",
82+
}
83+
}
84+
85+
// ExampleProperties returns the properties / config of this plugin
86+
func (p *plugin) ExampleProperties() *types.Any {
87+
any, err := types.AnyValue(Spec{
88+
"exampleString": "a_string",
89+
"exampleBool": true,
90+
"exampleInt": 1,
91+
})
92+
if err != nil {
93+
return nil
94+
}
95+
return any
96+
}
97+
98+
// Validate performs local validation on a provision request.
99+
func (p *plugin) Validate(req *types.Any) error {
100+
log.Debug("validate", req.String())
101+
102+
spec := Spec{}
103+
if err := req.Decode(&spec); err != nil {
104+
return err
105+
}
106+
107+
log.Debug("Validated:", spec)
108+
return nil
109+
}
110+
111+
// Provision creates a new instance based on the spec.
112+
func (p *plugin) Provision(spec instance.Spec) (*instance.ID, error) {
113+
114+
var properties map[string]interface{}
115+
116+
if spec.Properties != nil {
117+
if err := spec.Properties.Decode(&properties); err != nil {
118+
return nil, fmt.Errorf("Invalid instance properties: %s", err)
119+
}
120+
}
121+
122+
instanceName := instance.ID(fmt.Sprintf("InfraKit-%d", rand.Int63()))
123+
124+
return &instanceName, nil
125+
}
126+
127+
// Label labels the instance
128+
func (p *plugin) Label(instance instance.ID, labels map[string]string) error {
129+
return fmt.Errorf("Cisco UCS label updates are not implemented yet")
130+
}
131+
132+
// Destroy terminates an existing instance.
133+
func (p *plugin) Destroy(instance instance.ID, context instance.Context) error {
134+
log.Info("Currently running %s on instance: %v", context, instance)
135+
return nil
136+
}
137+
138+
// DescribeInstances returns descriptions of all instances matching all of the provided tags.
139+
// TODO - need to define the fitlering of tags => AND or OR of matches?
140+
func (p *plugin) DescribeInstances(tags map[string]string, properties bool) ([]instance.Description, error) {
141+
log.Debug("describe-instances", tags)
142+
results := []instance.Description{}
143+
144+
return results, nil
145+
}

pkg/run/v0/ucs/ucs.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package ucs
2+
3+
import (
4+
"strings"
5+
6+
"github.com/docker/infrakit/pkg/launch/inproc"
7+
logutil "github.com/docker/infrakit/pkg/log"
8+
"github.com/docker/infrakit/pkg/plugin"
9+
"github.com/docker/infrakit/pkg/provider/ucs"
10+
"github.com/docker/infrakit/pkg/run"
11+
"github.com/docker/infrakit/pkg/run/local"
12+
"github.com/docker/infrakit/pkg/run/scope"
13+
"github.com/docker/infrakit/pkg/spi/instance"
14+
"github.com/docker/infrakit/pkg/types"
15+
)
16+
17+
var log = logutil.New("module", "cli/x")
18+
19+
const (
20+
// Kind is the canonical name of the plugin for starting up, etc.
21+
Kind = "ucs"
22+
23+
// EnvNamespaceTags is the env to set for namespace tags. It's k=v,...
24+
EnvNamespaceTags = "INFRAKIT_UCS_NAMESPACE_TAGS"
25+
26+
// EnvUCSURL is the env for setting the Cisco UCS URL to connect to
27+
EnvUCSURL = "INFRAKIT_UCS_URL"
28+
29+
// EnvUCSUser is the Cisco UCS Username
30+
EnvUCSUser = "INFRAKIT_UCS_USER"
31+
32+
// EnvUCSPass is the Cisco UCS Password
33+
EnvUCSPass = "INFRAKIT_UCS_PASS"
34+
35+
// EnvUCSCookie is the Cisco UCS Auth Cookie
36+
EnvUCSCookie = "INFRAKIT_UCS_UCSCOOKIE"
37+
)
38+
39+
func init() {
40+
inproc.Register(Kind, Run, DefaultOptions)
41+
}
42+
43+
// Options capture the options for starting up the plugin.
44+
type Options struct {
45+
// Namespace is a set of kv pairs for tags that namespaces the resource instances
46+
// TODO - this is currently implemented in AWS and other cloud providers but not
47+
// in UCS
48+
Namespace map[string]string
49+
50+
// UCSs is a collection of UCS Domains - each corresponds to config of a plugin instance
51+
UCSs []ucs.Options
52+
}
53+
54+
func defaultNamespace() map[string]string {
55+
t := map[string]string{}
56+
list := local.Getenv(EnvNamespaceTags, "")
57+
for _, v := range strings.Split(list, ",") {
58+
p := strings.Split(v, "=")
59+
if len(p) == 2 {
60+
t[p[0]] = p[1]
61+
}
62+
}
63+
return t
64+
}
65+
66+
func defaultUCSOptions() ucs.Options {
67+
return ucs.Options{
68+
UCSUrl: local.Getenv(EnvUCSURL, "https://username:password@VCaddress/sdk"),
69+
UCSUser: local.Getenv(EnvUCSUser, ""),
70+
UCSPass: local.Getenv(EnvUCSPass, ""),
71+
UCSCookie: local.Getenv(EnvUCSCookie, ""),
72+
}
73+
}
74+
75+
// DefaultOptions return an Options with default values filled in.
76+
var DefaultOptions = Options{
77+
Namespace: defaultNamespace(),
78+
UCSs: []ucs.Options{
79+
defaultUCSOptions(),
80+
},
81+
}
82+
83+
// Run runs the plugin, blocking the current thread. Error is returned immediately
84+
// if the plugin cannot be started.
85+
func Run(scope scope.Scope, name plugin.Name,
86+
config *types.Any) (transport plugin.Transport, impls map[run.PluginCode]interface{}, onStop func(), err error) {
87+
88+
options := DefaultOptions
89+
err = config.Decode(&options)
90+
if err != nil {
91+
return
92+
}
93+
94+
bareMetal := map[string]instance.Plugin{}
95+
96+
for _, ucsDomain := range options.UCSs {
97+
bareMetal[ucsDomain.UCSUrl] = ucs.NewUCSInstancePlugin(ucsDomain)
98+
}
99+
100+
transport.Name = name
101+
impls = map[run.PluginCode]interface{}{
102+
run.Instance: bareMetal,
103+
}
104+
return
105+
}

vendor.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,8 @@ github.com/thebsdbox/go-tftp/server b3e1ec2
172172
github.com/whyrusleeping/go-tftp/packet 454ade9
173173
github.com/HewlettPackard/oneview-golang d0f1e96
174174
github.com/docker/machine/libmachine/log f10584e
175+
github.com/micdoher/terraform-provider-ucs/ucsclient 50940f9
176+
github.com/micdoher/terraform-provider-ucs/ucsclient/ucsinternal e82c113
177+
github.com/micdoher/GoUtils 799bb49
178+
gopkg.in/xmlpath.v2 860cbec
179+

vendor/github.com/micdoher/GoUtils/LICENSE

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/micdoher/GoUtils/Makefile

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/micdoher/GoUtils/README.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/micdoher/GoUtils/fixtures.go

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/micdoher/GoUtils/logger.go

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)