From 7d61d5304d6a3c618e5b973a4adb81b3a6c887ed Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Fri, 22 Oct 2021 08:05:01 +0200 Subject: [PATCH 01/12] update dependency --- go.mod | 5 +++-- go.sum | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 7479528..9ff071b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.14 require ( github.com/docker/docker v1.13.1 // indirect github.com/docker/machine v0.16.2 - github.com/google/uuid v1.1.1 - github.com/sirupsen/logrus v1.5.0 + github.com/google/uuid v1.3.0 + github.com/sirupsen/logrus v1.8.1 github.com/terraform-providers/terraform-provider-nutanix v1.1.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index d407528..7677b83 100644 --- a/go.sum +++ b/go.sum @@ -83,6 +83,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -169,6 +170,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= @@ -358,6 +361,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -506,6 +511,8 @@ golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190927073244-c990c680b611 h1:q9u40nxWT5zRClI/uU9dHCiYGottAg6Nzz4YUQyHxdA= golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -583,6 +590,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From d769b1d01409c07c23796d52ab481462d7992bf5 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Fri, 22 Oct 2021 10:21:34 +0200 Subject: [PATCH 02/12] cloud-init support --- machine/driver/driver.go | 62 ++++++++++++++++++++++++++++++-- machine/driver/yaml.go | 78 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 machine/driver/yaml.go diff --git a/machine/driver/driver.go b/machine/driver/driver.go index c237b9d..56ac74d 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -2,6 +2,7 @@ package driver import ( "encoding/base64" + "errors" "fmt" "io/ioutil" "net" @@ -15,6 +16,7 @@ import ( "github.com/docker/machine/libmachine/ssh" "github.com/docker/machine/libmachine/state" log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" "github.com/terraform-providers/terraform-provider-nutanix/client" v3 "github.com/terraform-providers/terraform-provider-nutanix/client/v3" @@ -48,6 +50,7 @@ type NutanixDriver struct { Categories string StorageContainer string DiskSize int + CloudInit string } // NewDriver create new instance @@ -240,8 +243,57 @@ func (d *NutanixDriver) Create() error { // CloudInit preparation - // vmConfig.VMCustomizationConfig.DataSourceType = "CONFIG_DRIVE_V2" - userdata := []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + var userdata []byte + + if d.CloudInit != "" { + t := yaml.Node{Kind: yaml.DocumentNode, HeadComment: "cloud-config"} + + if !strings.HasPrefix(d.CloudInit, "#cloud-config") { + return errors.New("cloud-init syntax error") + } + + err = yaml.Unmarshal([]byte(d.CloudInit), &t) + if err != nil { + log.Fatalf("Cloud-init syntax error: %v", err) + return err + } + + if t.Content == nil { + log.Infof("Use default Cloud-init") + userdata = []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + } else { + log.Infof("Cloud-init merge") + + usersNode := iterateNode(&t, "users") + + if usersNode == nil { + rootNode := t.Content[0] + rootNode.Content = append(rootNode.Content, buildScalarNodes("users")...) + usersNode = &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"} + rootNode.Content = append(rootNode.Content, usersNode) + } + + rancherNode := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"} + rancherNode.Content = append(rancherNode.Content, buildStringNodes("name", "root", "")...) + rancherNode.Content = append(rancherNode.Content, buildStringNodes("sudo", "ALL=(ALL) NOPASSWD:ALL", "")...) + rancherNode.Content = append(rancherNode.Content, buildScalarNodes("ssh-authorized-keys")...) + + sshSeqNode := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"} + sshSeqNode.Content = append(sshSeqNode.Content, buildScalarNodes(string(pubKey))...) + + rancherNode.Content = append(rancherNode.Content, sshSeqNode) + usersNode.Content = append(usersNode.Content, rancherNode) + + userdata, err = yaml.Marshal(&t) + if err != nil { + log.Fatal(err) + } + log.Infof(string(userdata)) + } + } else { + log.Infof("Use default Cloud-init") + userdata = []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + } cloudInit := &v3.GuestCustomizationCloudInit{ UserData: utils.StringPtr(base64.StdEncoding.EncodeToString(userdata)), @@ -398,6 +450,11 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "The size of the attached disk", Value: 0, }, + mcnflag.StringFlag{ + EnvVar: "NUTANIX_CLOUD_INIT", + Name: "nutanix-cloud-init", + Usage: "Cloud-init configuration", + }, } } @@ -546,6 +603,7 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { return fmt.Errorf("nutanix-vm-image cannot be empty") } d.ImageSize = opts.Int("nutanix-vm-image-size") + d.CloudInit = opts.String("nutanix-cloud-init") return nil } diff --git a/machine/driver/yaml.go b/machine/driver/yaml.go new file mode 100644 index 0000000..33bbd67 --- /dev/null +++ b/machine/driver/yaml.go @@ -0,0 +1,78 @@ +package driver + +import "gopkg.in/yaml.v3" + +func iterateNode(node *yaml.Node, identifier string) *yaml.Node { + returnNode := false + for _, n := range node.Content { + if n.Value == identifier { + returnNode = true + continue + } + if returnNode { + return n + } + if len(n.Content) > 0 { + ac_node := iterateNode(n, identifier) + if ac_node != nil { + return ac_node + } + } + } + return nil +} + +// deleteAllContents will remove all the contents of a node +// Mark sure to pass the correct node in otherwise bad things will happen +// func deleteAllContents(node *yaml.Node) { +// node.Content = []*yaml.Node{} +// } + +// buildStringNodes builds Nodes for a single key: value instance +func buildStringNodes(key, value, comment string) []*yaml.Node { + keyNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: key, + HeadComment: comment, + } + valueNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: value, + } + return []*yaml.Node{keyNode, valueNode} +} + +func buildScalarNodes(key string) []*yaml.Node { + keyNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: key, + } + return []*yaml.Node{keyNode} +} + +// buildMapNodes builds Nodes for a key: map instance +// func buildMapNodes(key string) (*yaml.Node, *yaml.Node) { +// n1, n2 := &yaml.Node{ +// Kind: yaml.ScalarNode, +// Tag: "!!str", +// Value: key, +// }, &yaml.Node{Kind: yaml.MappingNode, +// Tag: "!!map", +// } +// return n1, n2 +// } + +// buildSeqNodes builds Nodes for a key: map instance +// func buildSeqNodes(key string) (*yaml.Node, *yaml.Node) { +// n1, n2 := &yaml.Node{ +// Kind: yaml.ScalarNode, +// Tag: "!!str", +// Value: key, +// }, &yaml.Node{Kind: yaml.SequenceNode, +// Tag: "!!seq", +// } +// return n1, n2 +// } From 3c6b86666b9c8c65921f51c56236a13026db0e0f Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Fri, 29 Oct 2021 16:26:19 +0200 Subject: [PATCH 03/12] implement multi category as slice --- machine/driver/driver.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/machine/driver/driver.go b/machine/driver/driver.go index 56ac74d..b26ee83 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -47,7 +47,7 @@ type NutanixDriver struct { VMId string SessionAuth bool ProxyURL string - Categories string + Categories []string StorageContainer string DiskSize int CloudInit string @@ -155,12 +155,12 @@ func (d *NutanixDriver) Create() error { return fmt.Errorf("network %s not found in cluster %s", d.Subnet, d.Cluster) } - if d.Categories != "" { - selectedCategories := strings.Split(d.Categories, ",") + if len(d.Categories) != 0 { + log.Infof("Categories provided: %s", d.Categories) metadata.Categories = make(map[string]string) - for _, group := range selectedCategories { - category := strings.Split(group, ":") + for _, group := range d.Categories { + category := strings.Split(group, "=") if len(category) < 2 { log.Errorf("Malformed group %s", group) @@ -432,11 +432,9 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "Increase the size of the template image", Value: 0, }, - mcnflag.StringFlag{ - EnvVar: "NUTANIX_VM_CATEGORIES", - Name: "nutanix-vm-categories", - Usage: "The name of the categories who will be applied to the newly created VM", - Value: "", + mcnflag.StringSliceFlag{ + Name: "nutanix-vm-categories", + Usage: "The name of the categories who will be applied to the newly created VM", }, mcnflag.StringFlag{ EnvVar: "NUTANIX_STORAGE_CONTAINER", @@ -581,7 +579,7 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { d.Insecure = opts.Bool("nutanix-insecure") - d.Categories = opts.String("nutanix-vm-categories") + d.Categories = opts.StringSlice("nutanix-vm-categories") d.Cluster = opts.String("nutanix-cluster") if d.Cluster == "" { From 67f62f3f5a821ec15e1d5a9a9220a160e45d505f Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sat, 30 Oct 2021 09:30:44 +0200 Subject: [PATCH 04/12] change network as slice --- machine/driver/driver.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/machine/driver/driver.go b/machine/driver/driver.go index b26ee83..b33817d 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -41,7 +41,7 @@ type NutanixDriver struct { VMCores int VMMem int SSHPass string - Subnet string + Subnet []string Image string ImageSize int VMId string @@ -113,16 +113,15 @@ func (d *NutanixDriver) Create() error { } // Search target subnet - selectedSubnets := strings.Split(d.Subnet, ",") - for index, subnet := range selectedSubnets { + for index, subnet := range d.Subnet { // Trim extraneous whitespace - selectedSubnets[index] = strings.TrimSpace(subnet) + d.Subnet[index] = strings.TrimSpace(subnet) } subnetFilter := "" - for _, subnet := range selectedSubnets { + for _, subnet := range d.Subnet { if len(subnetFilter) != 0 { subnetFilter += "," } @@ -136,7 +135,7 @@ func (d *NutanixDriver) Create() error { return err } - for _, query := range selectedSubnets { + for _, query := range d.Subnet { for _, subnet := range subnets.Entities { if *subnet.Status.Name == query && *subnet.Status.ClusterReference.UUID == *spec.ClusterReference.UUID { n := &v3.VMNic{ @@ -416,10 +415,9 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "Number of cores per VCPU of the VM to be created", Value: defaultCores, }, - mcnflag.StringFlag{ - EnvVar: "NUTANIX_VM_NETWORK", - Name: "nutanix-vm-network", - Usage: "The name of the network to attach to the newly created VM", + mcnflag.StringSliceFlag{ + Name: "nutanix-vm-network", + Usage: "The name of the network to attach to the newly created VM", }, mcnflag.StringFlag{ EnvVar: "NUTANIX_VM_IMAGE", @@ -592,8 +590,8 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { d.VMMem = opts.Int("nutanix-vm-mem") d.VMVCPUs = opts.Int("nutanix-vm-cpus") d.VMCores = opts.Int("nutanix-vm-cores") - d.Subnet = opts.String("nutanix-vm-network") - if d.Subnet == "" { + d.Subnet = opts.StringSlice("nutanix-vm-network") + if len(d.Subnet) == 0 { return fmt.Errorf("nutanix-vm-network cannot be empty") } d.Image = opts.String("nutanix-vm-image") From 8c914d59c5ab13c2813675718b69d2f0e975b673 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sat, 30 Oct 2021 16:23:58 +0200 Subject: [PATCH 05/12] update dependecy --- go.mod | 5 +++++ go.sum | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/go.mod b/go.mod index 9ff071b..e71be49 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,12 @@ module nutanix go 1.14 +replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible + +replace github.com/terraform-providers/terraform-provider-nutanix => github.com/nutanix/terraform-provider-nutanix v1.2.2-0.20211029075448-e21f85ac2cf7 + require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/docker/docker v1.13.1 // indirect github.com/docker/machine v0.16.2 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 7677b83..1b96e5f 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v36.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= @@ -35,6 +37,7 @@ github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJM github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= @@ -91,6 +94,8 @@ github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQ github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/engine v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible h1:nnCzIfwUkdP7f5ZYf8el5qKoWSwuQxEeTcDwWHLKsKg= +github.com/docker/engine v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= github.com/docker/machine v0.16.2 h1:jyF9k3Zg+oIGxxSdYKPScyj3HqFZ6FjgA/3sblcASiU= github.com/docker/machine v0.16.2/go.mod h1:I8mPNDeK1uH+JTcUU7X0ZW8KiYz0jyAgNaeSJ1rCfDI= github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= @@ -142,6 +147,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= @@ -190,12 +196,15 @@ github.com/hashicorp/go-azure-helpers v0.10.0/go.mod h1:YuAtHxm2v74s+IjQwUG88dHB github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa/go.mod h1:6ij3Z20p+OhOkCSrA0gImAWoHYQRGbnlcuk6XYTiaRw= github.com/hashicorp/go-msgpack v0.5.4/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= github.com/hashicorp/go-retryablehttp v0.5.2/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= @@ -215,14 +224,22 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8= github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= github.com/hashicorp/terraform v0.12.28 h1:mBA+A9dvMXk1xDpflKEP5mL/KOD0sXap+M4F4Vlgnvc= github.com/hashicorp/terraform v0.12.28/go.mod h1:CBxNAiTW0pLap44/3GU4j7cYE2bMhkKZNlHPcr4P55U= +github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= +github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= +github.com/hashicorp/terraform-plugin-sdk v1.7.0 h1:B//oq0ZORG+EkVrIJy0uPGSonvmXqxSzXe8+GhknoW0= +github.com/hashicorp/terraform-plugin-sdk v1.7.0/go.mod h1:OjgQmey5VxnPej/buEhe+YqKm0KNvV3QqU4hkqHqPCY= +github.com/hashicorp/terraform-plugin-test v1.2.0/go.mod h1:QIJHYz8j+xJtdtLrFTlzQVC0ocr3rf/OjIpgZLK56Hs= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= @@ -304,6 +321,7 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/panicwrap v1.0.0/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA= github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= @@ -313,6 +331,10 @@ github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5w github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= +github.com/nutanix/terraform-provider-nutanix v1.2.1 h1:iBzrhdbRQ+SKHwZe26NriMf9PdG+0carFwjRt7jfkq4= +github.com/nutanix/terraform-provider-nutanix v1.2.1/go.mod h1:XNd4Ph1C07UCzVdGq9IJ98nsRLq4gQwmiZ2fJo6Vhlg= +github.com/nutanix/terraform-provider-nutanix v1.2.2-0.20211029075448-e21f85ac2cf7 h1:XSW7lfLeXiwu1wT8qchccK76lyco9MdSuch5RYjeaZA= +github.com/nutanix/terraform-provider-nutanix v1.2.2-0.20211029075448-e21f85ac2cf7/go.mod h1:XNd4Ph1C07UCzVdGq9IJ98nsRLq4gQwmiZ2fJo6Vhlg= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -323,6 +345,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -388,6 +411,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= github.com/tencentcloud/tencentcloud-sdk-go v3.0.82+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= @@ -440,6 +464,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -495,6 +521,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -513,6 +540,8 @@ golang.org/x/sys v0.0.0-20190927073244-c990c680b611 h1:q9u40nxWT5zRClI/uU9dHCiYG golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -566,6 +595,7 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -590,6 +620,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 2603bfa5b999ea5c150ba7f16905ab280cd89e44 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 09:24:26 +0100 Subject: [PATCH 06/12] add CPU passthrough --- machine/driver/driver.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/machine/driver/driver.go b/machine/driver/driver.go index b33817d..4bd0e04 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -39,6 +39,7 @@ type NutanixDriver struct { Cluster string VMVCPUs int VMCores int + VMCPUPassthrough bool VMMem int SSHPass string Subnet []string @@ -95,6 +96,10 @@ func (d *NutanixDriver) Create() error { res.NumSockets = utils.Int64Ptr(int64(d.VMVCPUs)) res.NumVcpusPerSocket = utils.Int64Ptr(int64(d.VMCores)) + if d.VMCPUPassthrough { + res.EnableCPUPassthrough = utils.BoolPtr(d.VMCPUPassthrough) + } + // Search target cluster clusterFilter := fmt.Sprintf("name==%s", d.Cluster) clusters, err := conn.V3.ListAllCluster(clusterFilter) @@ -415,6 +420,11 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "Number of cores per VCPU of the VM to be created", Value: defaultCores, }, + mcnflag.BoolFlag{ + EnvVar: "NUTANIX_VM_CPU_PASSTHROUGH", + Name: "nutanix-vm-cpu-passthrough", + Usage: "Enable passthrough the host’s CPU features to the newly created VM", + }, mcnflag.StringSliceFlag{ Name: "nutanix-vm-network", Usage: "The name of the network to attach to the newly created VM", @@ -590,6 +600,9 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { d.VMMem = opts.Int("nutanix-vm-mem") d.VMVCPUs = opts.Int("nutanix-vm-cpus") d.VMCores = opts.Int("nutanix-vm-cores") + + d.VMCPUPassthrough = opts.Bool("nutanix-vm-cpu-passthrough") + d.Subnet = opts.StringSlice("nutanix-vm-network") if len(d.Subnet) == 0 { return fmt.Errorf("nutanix-vm-network cannot be empty") From e749ffd6dce45e510baa13f87a86ca9b9d0d3944 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 09:30:10 +0100 Subject: [PATCH 07/12] Cloud init support (#11) Add Cloud-init support allow provide a cloud-init config who will be merged with the docker-machine settings --- go.mod | 5 +-- go.sum | 9 +++++ machine/driver/driver.go | 62 ++++++++++++++++++++++++++++++-- machine/driver/yaml.go | 78 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 machine/driver/yaml.go diff --git a/go.mod b/go.mod index 7479528..9ff071b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.14 require ( github.com/docker/docker v1.13.1 // indirect github.com/docker/machine v0.16.2 - github.com/google/uuid v1.1.1 - github.com/sirupsen/logrus v1.5.0 + github.com/google/uuid v1.3.0 + github.com/sirupsen/logrus v1.8.1 github.com/terraform-providers/terraform-provider-nutanix v1.1.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index d407528..7677b83 100644 --- a/go.sum +++ b/go.sum @@ -83,6 +83,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -169,6 +170,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= @@ -358,6 +361,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -506,6 +511,8 @@ golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190927073244-c990c680b611 h1:q9u40nxWT5zRClI/uU9dHCiYGottAg6Nzz4YUQyHxdA= golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -583,6 +590,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/machine/driver/driver.go b/machine/driver/driver.go index c237b9d..56ac74d 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -2,6 +2,7 @@ package driver import ( "encoding/base64" + "errors" "fmt" "io/ioutil" "net" @@ -15,6 +16,7 @@ import ( "github.com/docker/machine/libmachine/ssh" "github.com/docker/machine/libmachine/state" log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" "github.com/terraform-providers/terraform-provider-nutanix/client" v3 "github.com/terraform-providers/terraform-provider-nutanix/client/v3" @@ -48,6 +50,7 @@ type NutanixDriver struct { Categories string StorageContainer string DiskSize int + CloudInit string } // NewDriver create new instance @@ -240,8 +243,57 @@ func (d *NutanixDriver) Create() error { // CloudInit preparation - // vmConfig.VMCustomizationConfig.DataSourceType = "CONFIG_DRIVE_V2" - userdata := []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + var userdata []byte + + if d.CloudInit != "" { + t := yaml.Node{Kind: yaml.DocumentNode, HeadComment: "cloud-config"} + + if !strings.HasPrefix(d.CloudInit, "#cloud-config") { + return errors.New("cloud-init syntax error") + } + + err = yaml.Unmarshal([]byte(d.CloudInit), &t) + if err != nil { + log.Fatalf("Cloud-init syntax error: %v", err) + return err + } + + if t.Content == nil { + log.Infof("Use default Cloud-init") + userdata = []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + } else { + log.Infof("Cloud-init merge") + + usersNode := iterateNode(&t, "users") + + if usersNode == nil { + rootNode := t.Content[0] + rootNode.Content = append(rootNode.Content, buildScalarNodes("users")...) + usersNode = &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"} + rootNode.Content = append(rootNode.Content, usersNode) + } + + rancherNode := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"} + rancherNode.Content = append(rancherNode.Content, buildStringNodes("name", "root", "")...) + rancherNode.Content = append(rancherNode.Content, buildStringNodes("sudo", "ALL=(ALL) NOPASSWD:ALL", "")...) + rancherNode.Content = append(rancherNode.Content, buildScalarNodes("ssh-authorized-keys")...) + + sshSeqNode := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"} + sshSeqNode.Content = append(sshSeqNode.Content, buildScalarNodes(string(pubKey))...) + + rancherNode.Content = append(rancherNode.Content, sshSeqNode) + usersNode.Content = append(usersNode.Content, rancherNode) + + userdata, err = yaml.Marshal(&t) + if err != nil { + log.Fatal(err) + } + log.Infof(string(userdata)) + } + } else { + log.Infof("Use default Cloud-init") + userdata = []byte("#cloud-config\r\nusers:\r\n - name: root\r\n ssh_authorized_keys:\r\n - " + string(pubKey)) + } cloudInit := &v3.GuestCustomizationCloudInit{ UserData: utils.StringPtr(base64.StdEncoding.EncodeToString(userdata)), @@ -398,6 +450,11 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "The size of the attached disk", Value: 0, }, + mcnflag.StringFlag{ + EnvVar: "NUTANIX_CLOUD_INIT", + Name: "nutanix-cloud-init", + Usage: "Cloud-init configuration", + }, } } @@ -546,6 +603,7 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { return fmt.Errorf("nutanix-vm-image cannot be empty") } d.ImageSize = opts.Int("nutanix-vm-image-size") + d.CloudInit = opts.String("nutanix-cloud-init") return nil } diff --git a/machine/driver/yaml.go b/machine/driver/yaml.go new file mode 100644 index 0000000..33bbd67 --- /dev/null +++ b/machine/driver/yaml.go @@ -0,0 +1,78 @@ +package driver + +import "gopkg.in/yaml.v3" + +func iterateNode(node *yaml.Node, identifier string) *yaml.Node { + returnNode := false + for _, n := range node.Content { + if n.Value == identifier { + returnNode = true + continue + } + if returnNode { + return n + } + if len(n.Content) > 0 { + ac_node := iterateNode(n, identifier) + if ac_node != nil { + return ac_node + } + } + } + return nil +} + +// deleteAllContents will remove all the contents of a node +// Mark sure to pass the correct node in otherwise bad things will happen +// func deleteAllContents(node *yaml.Node) { +// node.Content = []*yaml.Node{} +// } + +// buildStringNodes builds Nodes for a single key: value instance +func buildStringNodes(key, value, comment string) []*yaml.Node { + keyNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: key, + HeadComment: comment, + } + valueNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: value, + } + return []*yaml.Node{keyNode, valueNode} +} + +func buildScalarNodes(key string) []*yaml.Node { + keyNode := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: key, + } + return []*yaml.Node{keyNode} +} + +// buildMapNodes builds Nodes for a key: map instance +// func buildMapNodes(key string) (*yaml.Node, *yaml.Node) { +// n1, n2 := &yaml.Node{ +// Kind: yaml.ScalarNode, +// Tag: "!!str", +// Value: key, +// }, &yaml.Node{Kind: yaml.MappingNode, +// Tag: "!!map", +// } +// return n1, n2 +// } + +// buildSeqNodes builds Nodes for a key: map instance +// func buildSeqNodes(key string) (*yaml.Node, *yaml.Node) { +// n1, n2 := &yaml.Node{ +// Kind: yaml.ScalarNode, +// Tag: "!!str", +// Value: key, +// }, &yaml.Node{Kind: yaml.SequenceNode, +// Tag: "!!seq", +// } +// return n1, n2 +// } From 8f03487d9457360d33a598ec4dc805fa6f697402 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 09:33:27 +0100 Subject: [PATCH 08/12] Enhanced categories (#12) Support multi categories as slice --- machine/driver/driver.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/machine/driver/driver.go b/machine/driver/driver.go index 56ac74d..b26ee83 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -47,7 +47,7 @@ type NutanixDriver struct { VMId string SessionAuth bool ProxyURL string - Categories string + Categories []string StorageContainer string DiskSize int CloudInit string @@ -155,12 +155,12 @@ func (d *NutanixDriver) Create() error { return fmt.Errorf("network %s not found in cluster %s", d.Subnet, d.Cluster) } - if d.Categories != "" { - selectedCategories := strings.Split(d.Categories, ",") + if len(d.Categories) != 0 { + log.Infof("Categories provided: %s", d.Categories) metadata.Categories = make(map[string]string) - for _, group := range selectedCategories { - category := strings.Split(group, ":") + for _, group := range d.Categories { + category := strings.Split(group, "=") if len(category) < 2 { log.Errorf("Malformed group %s", group) @@ -432,11 +432,9 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "Increase the size of the template image", Value: 0, }, - mcnflag.StringFlag{ - EnvVar: "NUTANIX_VM_CATEGORIES", - Name: "nutanix-vm-categories", - Usage: "The name of the categories who will be applied to the newly created VM", - Value: "", + mcnflag.StringSliceFlag{ + Name: "nutanix-vm-categories", + Usage: "The name of the categories who will be applied to the newly created VM", }, mcnflag.StringFlag{ EnvVar: "NUTANIX_STORAGE_CONTAINER", @@ -581,7 +579,7 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { d.Insecure = opts.Bool("nutanix-insecure") - d.Categories = opts.String("nutanix-vm-categories") + d.Categories = opts.StringSlice("nutanix-vm-categories") d.Cluster = opts.String("nutanix-cluster") if d.Cluster == "" { From 1eb94309069e658ea8ab94add4cbccc66c527218 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 09:36:59 +0100 Subject: [PATCH 09/12] Enhanced network (#13) implement multi network support as slice --- machine/driver/driver.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/machine/driver/driver.go b/machine/driver/driver.go index b26ee83..b33817d 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -41,7 +41,7 @@ type NutanixDriver struct { VMCores int VMMem int SSHPass string - Subnet string + Subnet []string Image string ImageSize int VMId string @@ -113,16 +113,15 @@ func (d *NutanixDriver) Create() error { } // Search target subnet - selectedSubnets := strings.Split(d.Subnet, ",") - for index, subnet := range selectedSubnets { + for index, subnet := range d.Subnet { // Trim extraneous whitespace - selectedSubnets[index] = strings.TrimSpace(subnet) + d.Subnet[index] = strings.TrimSpace(subnet) } subnetFilter := "" - for _, subnet := range selectedSubnets { + for _, subnet := range d.Subnet { if len(subnetFilter) != 0 { subnetFilter += "," } @@ -136,7 +135,7 @@ func (d *NutanixDriver) Create() error { return err } - for _, query := range selectedSubnets { + for _, query := range d.Subnet { for _, subnet := range subnets.Entities { if *subnet.Status.Name == query && *subnet.Status.ClusterReference.UUID == *spec.ClusterReference.UUID { n := &v3.VMNic{ @@ -416,10 +415,9 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { Usage: "Number of cores per VCPU of the VM to be created", Value: defaultCores, }, - mcnflag.StringFlag{ - EnvVar: "NUTANIX_VM_NETWORK", - Name: "nutanix-vm-network", - Usage: "The name of the network to attach to the newly created VM", + mcnflag.StringSliceFlag{ + Name: "nutanix-vm-network", + Usage: "The name of the network to attach to the newly created VM", }, mcnflag.StringFlag{ EnvVar: "NUTANIX_VM_IMAGE", @@ -592,8 +590,8 @@ func (d *NutanixDriver) SetConfigFromFlags(opts drivers.DriverOptions) error { d.VMMem = opts.Int("nutanix-vm-mem") d.VMVCPUs = opts.Int("nutanix-vm-cpus") d.VMCores = opts.Int("nutanix-vm-cores") - d.Subnet = opts.String("nutanix-vm-network") - if d.Subnet == "" { + d.Subnet = opts.StringSlice("nutanix-vm-network") + if len(d.Subnet) == 0 { return fmt.Errorf("nutanix-vm-network cannot be empty") } d.Image = opts.String("nutanix-vm-image") From 60ab2e3f0f180c3de1ad3ecb4d6f1d04146065ee Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 16:50:55 +0100 Subject: [PATCH 10/12] update doc --- README.md | 72 ++++++++++++++++++++++++++++++++++------ machine/README.md | 43 ------------------------ machine/driver/driver.go | 2 +- 3 files changed, 63 insertions(+), 54 deletions(-) delete mode 100755 machine/README.md diff --git a/README.md b/README.md index a54a7dd..4b7a740 100755 --- a/README.md +++ b/README.md @@ -1,20 +1,72 @@ -# Nutanix Docker Machine driver +# Nutanix Rancher Node Driver -## Build, Quality Status +This repository contains the Rancher Node Driver for Nutanix. Nutanix Node driver are used to provision hosts on Nutanix Enterprise Cloud, which Rancher uses to launch and manage Kubernetes clusters. - [![Go Report Card](https://goreportcard.com/badge/github.com/tuxtof/nutanix-docker-machine)](https://goreportcard.com/report/github.com/tuxtof/nutanix-docker-machine) - -|Master | -| --------------- | -| ![Integration](https://github.com/nutanix/docker-machine/workflows/Integration/badge.svg) | +--- +[![Go Report Card](https://goreportcard.com/badge/github.com/nutanix/docker-machine)](https://goreportcard.com/report/github.com/nutanix/docker-machine) +![CI](https://github.com/nutanix/docker-machine/actions/workflows/integration.yml/badge.svg) +![Release](https://github.com/nutanix/docker-machine/actions/workflows/release.yml/badge.svg) +[![release](https://img.shields.io/github/release-pre/nutanix/docker-machine.svg)](https://github.com/nutanix/docker-machine/releases) +[![License](https://img.shields.io/badge/License-MPL%202.0-blue.svg)](https://github.com/nutanix/docker-machine/blob/master/LICENSE) +![Proudly written in Golang](https://img.shields.io/badge/written%20in-Golang-92d1e7.svg) +[![Releases](https://img.shields.io/github/downloads/nutanix/docker-machine/total.svg)](https://github.com/nutanix/docker-machine/releases) -This repository contains Nutanix docker machine driver +--- + +Features +--------- + +1. Ability to select VM's Main Memory in Megabytes +2. Ability to select VM's vCPU count +3. Ability to set a custom name for the newly created VM +4. Ability to set the number of cores per vCPU +5. Ability to specify the network(s) of the VM +6. Ability to specify the template disk in the VM by image name and modify his size (increase only) +7. Ability to specify categories to applied to the VM ( flow, leap, ...) +8. Ability to add one additional disk by specifying disk-size and storage-container +9. Enable passthrough the host's CPU features to the newly created VM + + +Installation +-------------------- + +If you want to use Nutanix Node Driver, you need add it in order to start using them to create node templates and eventually node pools for your Kubernetes cluster. + +1. From the Home view, choose *Cluster Management* > *Drivers* in the navigation bar. From the Drivers page, select the *Node Drivers* tab. +2. Click *Add Node Driver*. +3. Complete the Add Node Driver form. Then click Create. + +Driver Args +----------- +|Arg |Description |Required |Default | +|--------------------------------|:------------------------------------------------------------------------|:-----------------|--------| +| `--nutanix-endpoint` |The hostname/ip-address of the Prism Central |yes || +| `--nutanix-username` |The username of the nutanix management account |yes || +| `--nutanix-password` |The password of the nutanix management account |yes || +| `--nutanix-insecure` |Set to true to force SSL insecure connection |no |false| +| `--nutanix-cluster` |The name of the cluster where deploy the VM (case sensitive) |yes || +| `--nutanix-vm-mem` |The amount of RAM of the newly created VM (MB) |no | 2 GB| +| `--nutanix-vm-cpus` |The number of cpus in the newly created VM (core) |no | 2| +| `--nutanix-vm-cores` |The number of cores per vCPU |no | 1| +| `--nutanix-vm-network` |The network(s) to which the VM is attached to |yes || +| `--nutanix-vm-image` |The name of the Image we use as a template for the newly created VM |yes || +| `--nutanix-vm-image-size` |The new size of the Image we use as a template (in GiB) |no || +| `--nutanix-vm-categories` |The name of the categories who will be applied to the newly created VM |no || +| `--nutanix-disk-size` |The size of the additional disk to add to the VM (in GiB) |no || +| `--nutanix-storage-container` |The storage container UUID of the additional disk to add to the VM |no || +| `--nutanix-vm-cpu-passthrough` |Enable passthrough the host's CPU features to the newly created VM |no |false| + +Build Instructions +-------------------- + +build linux/amd64 binary => `make` +build local binary => `make local` +## History * v1 is the original Nutanix docker machine driver that connect to Prism Element * v2.x add Rancher 2.0 support -* v3.x is the latest branch version that connect to Prism Central +* v3.x is a rewrite of the driver that connect to Prism Central diff --git a/machine/README.md b/machine/README.md deleted file mode 100755 index 5199442..0000000 --- a/machine/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Nutanix Docker Machine Driver - -This repository contains the docker machine driver for nutanix. - -The driver can create VMs in a nutanix managed cluster, and setup docker on it. It uses the MGMT API to achieve this goal. - -Build Instructions --------------------- - -make sure the vendored (code from the vendor directory) version of docker-machine code is in $GOPATH - -`go build -o docker-machine-driver-nutanix main.go` - -Features ---------- - -1. Ability to select VM's Main Memory in Megabytes -2. Ability to select VM's vCPU count -3. Ability to set a custom name for the newly created VM -4. Ability to set the number of cores per vCPU -5. Ability to specify the network(s) of the VM -6. Ability to specify the template disk in the VM by image name and modify his size (increase only) -7. Ability to specify categories to applied to the VM ( flow, leap, ...) -8. Ability to add one additional disk by specifying disk-size and storage-container - -Driver Args ------------ -|Arg |Description |Required | -|--------------------------------|:------------------------------------------------------------------------|:-----------------| -| `--nutanix-endpoint` |The hostname/ip-address of the Prism Central |yes | -| `--nutanix-username` |The username of the nutanix management account |yes | -| `--nutanix-password` |The password of the nutanix management account |yes | -| `--nutanix-insecure` |Set to true to force SSL insecure connection |no (default=false)| -| `--nutanix-cluster` |The name of the cluster where deploy the VM (case sensitive) |yes | -| `--nutanix-vm-mem` |The amount of RAM of the newly created VM |no (default=2G) | -| `--nutanix-vm-cpus` |The number of cpus in the newly created VM |no (default=2) | -| `--nutanix-vm-cores` |The number of cores per vCPU |no (default=1) | -| `--nutanix-vm-network` |The network(s) to which the VM is attached to, support multiple network (separated by a comma)|yes | -| `--nutanix-vm-image` |The name of the Image we use as a template for the newly created VM |yes | -| `--nutanix-vm-image-size` |The new size of the Image we use as a template (in GiB) |no | -| `--nutanix-vm-categories` |The name of the categories who will be applied to the newly created VM |no | -| `--nutanix-disk-size` |The size of the additional disk to add to the VM (in GiB) |no | -| `--nutanix-storage-container` |The storage container UUID of the additional disk to add to the VM |no | diff --git a/machine/driver/driver.go b/machine/driver/driver.go index 4bd0e04..9b18cde 100755 --- a/machine/driver/driver.go +++ b/machine/driver/driver.go @@ -423,7 +423,7 @@ func (d *NutanixDriver) GetCreateFlags() []mcnflag.Flag { mcnflag.BoolFlag{ EnvVar: "NUTANIX_VM_CPU_PASSTHROUGH", Name: "nutanix-vm-cpu-passthrough", - Usage: "Enable passthrough the host’s CPU features to the newly created VM", + Usage: "Enable passthrough the host's CPU features to the newly created VM", }, mcnflag.StringSliceFlag{ Name: "nutanix-vm-network", From 83a23153ad97b72ddb04cf709d0ee81dd7d30099 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 16:52:14 +0100 Subject: [PATCH 11/12] add picture --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4b7a740..1532c64 100755 --- a/README.md +++ b/README.md @@ -39,6 +39,9 @@ If you want to use Nutanix Node Driver, you need add it in order to start using 2. Click *Add Node Driver*. 3. Complete the Add Node Driver form. Then click Create. +![image](https://user-images.githubusercontent.com/180613/139591695-ec43a6e1-f351-4221-afda-90ae07961be4.png) + + Driver Args ----------- |Arg |Description |Required |Default | From 85b49af44fa4425f09832f11247b40123cc607ff Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Sun, 31 Oct 2021 16:56:04 +0100 Subject: [PATCH 12/12] update go to 1.17 --- .github/workflows/integration.yml | 6 +++--- .github/workflows/release.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index db7e9f4..2622482 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: '^1.16' + go-version: '^1.17' - name: Checkout Code uses: actions/checkout@v2 @@ -29,7 +29,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: '^1.16' + go-version: '^1.17' - name: Checkout Code uses: actions/checkout@v2 @@ -44,7 +44,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: '^1.16' + go-version: '^1.17' - name: Check out code into the Go module directory uses: actions/checkout@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6bee080..ec50226 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: '^1.16' + go-version: '^1.17' - name: Create release on GitHub uses: goreleaser/goreleaser-action@v2