From 2b40a4b046f17e69633b9c732ceaa004b8709a09 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Thu, 15 Apr 2021 10:24:41 +0200 Subject: [PATCH 01/23] Getting MAAS locations props --- data/tosca/yorc-maas-types.yml | 17 +++++++++ prov/maas/executor.go | 66 ++++++++++++++++++++++++++++++++++ prov/maas/init.go | 25 +++++++++++++ server/plugins.go | 8 ++--- 4 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 data/tosca/yorc-maas-types.yml create mode 100644 prov/maas/executor.go create mode 100644 prov/maas/init.go diff --git a/data/tosca/yorc-maas-types.yml b/data/tosca/yorc-maas-types.yml new file mode 100644 index 000000000..0cf8db7d3 --- /dev/null +++ b/data/tosca/yorc-maas-types.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: yorc_tosca_simple_yaml_1_0 + +metadata: + template_name: yorc-maas-types + template_author: yorc + template_version: 1.0.0 + +imports: + - yorc: + +node_types: + yorc.nodes.maas.Compute: + derived_from: yorc.nodes.Compute + properties: + capabilities: + host: + type: tosca.capabilities.Container diff --git a/prov/maas/executor.go b/prov/maas/executor.go new file mode 100644 index 000000000..287880488 --- /dev/null +++ b/prov/maas/executor.go @@ -0,0 +1,66 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "context" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/locations" +) + +const infrastructureType = "maas" + +type defaultExecutor struct { +} + +func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configuration, taskID, deploymentID, nodeName, delegateOperation string) error { + + var locationProps config.DynamicMap + locationMgr, err := locations.GetManager(cfg) + if err == nil { + locationProps, err = locationMgr.GetLocationPropertiesForNode(ctx, deploymentID, nodeName, infrastructureType) + } + if err != nil { + return err + } + + tmp := locationProps.GetString("api_token") + fmt.Println("HERE :: " + tmp) + + operation := strings.ToLower(delegateOperation) + switch { + case operation == "install": + err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation) + // case operation == "uninstall": + // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) + default: + return errors.Errorf("Unsupported operation %q", delegateOperation) + } + return err +} + +func (e *defaultExecutor) installNode(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName string, operation string) error { + // infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation) + // if err != nil { + // return err + // } + + // return e.createInfrastructure(ctx, cfg, locationProps, deploymentID, nodeName, infra) + return nil +} diff --git a/prov/maas/init.go b/prov/maas/init.go new file mode 100644 index 000000000..bdd5d8bf6 --- /dev/null +++ b/prov/maas/init.go @@ -0,0 +1,25 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "github.com/ystia/yorc/v4/registry" +) + +func init() { + reg := registry.GetRegistry() + reg.RegisterDelegates([]string{`yorc\.nodes\.maas\..*`}, &defaultExecutor{}, registry.BuiltinOrigin) + +} diff --git a/server/plugins.go b/server/plugins.go index 83bbd544d..3ac2d20e0 100644 --- a/server/plugins.go +++ b/server/plugins.go @@ -30,24 +30,22 @@ import ( _ "github.com/ystia/yorc/v4/prov/slurm" // Registering hosts pool delegate executor in the registry _ "github.com/ystia/yorc/v4/prov/hostspool" + // Registering maas delegate executor in the registry + _ "github.com/ystia/yorc/v4/prov/maas" // Registering builtin Tosca definition files _ "github.com/ystia/yorc/v4/tosca" // Registering builtin HashiCorp Vault Client Builder _ "github.com/ystia/yorc/v4/vault/hashivault" // Registering builtin activity hooks - _ "github.com/ystia/yorc/v4/prov/validation" -) - -import ( "context" "os" "path/filepath" "github.com/ystia/yorc/v4/deployments/store" + _ "github.com/ystia/yorc/v4/prov/validation" gplugin "github.com/hashicorp/go-plugin" "github.com/pkg/errors" - "github.com/ystia/yorc/v4/config" "github.com/ystia/yorc/v4/log" "github.com/ystia/yorc/v4/plugin" From 0200d9a9a8d6592e2f37d41da95bc824ada4130d Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 19 Apr 2021 11:23:54 +0200 Subject: [PATCH 02/23] Generating compute infra --- prov/maas/executor.go | 44 ++++++++++++++++++++++------ prov/maas/generator.go | 66 ++++++++++++++++++++++++++++++++++++++++++ prov/maas/structs.go | 8 +++++ 3 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 prov/maas/generator.go create mode 100644 prov/maas/structs.go diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 287880488..005f83962 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -16,12 +16,13 @@ package maas import ( "context" - "fmt" "strings" "github.com/pkg/errors" "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/deployments" "github.com/ystia/yorc/v4/locations" + "github.com/ystia/yorc/v4/tosca" ) const infrastructureType = "maas" @@ -30,7 +31,7 @@ type defaultExecutor struct { } func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configuration, taskID, deploymentID, nodeName, delegateOperation string) error { - + // Get locations props var locationProps config.DynamicMap locationMgr, err := locations.GetManager(cfg) if err == nil { @@ -40,13 +41,16 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura return err } - tmp := locationProps.GetString("api_token") - fmt.Println("HERE :: " + tmp) + // Get deployment instances names + instances, err := e.getAvailableInstances(ctx, deploymentID, nodeName) + if err != nil { + return err + } operation := strings.ToLower(delegateOperation) switch { case operation == "install": - err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation) + err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation, instances) // case operation == "uninstall": // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) default: @@ -55,11 +59,33 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura return err } +func (e *defaultExecutor) getAvailableInstances(ctx context.Context, deploymentID, nodeName string) ([]string, error) { + instances, err := deployments.GetNodeInstancesIds(ctx, deploymentID, nodeName) + if err != nil { + return nil, err + } + + availableIntances := []string{} + for _, instanceName := range instances { + instanceState, err := deployments.GetInstanceState(ctx, deploymentID, nodeName, instanceName) + if err != nil { + return nil, err + } + if instanceState == tosca.NodeStateDeleting || instanceState == tosca.NodeStateDeleted { + // Do not generate something for this node instance (will be deleted if exists) + continue + } + availableIntances = append(availableIntances, instanceName) + } + + return availableIntances, nil +} + func (e *defaultExecutor) installNode(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName string, operation string) error { - // infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation) - // if err != nil { - // return err - // } + infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation) + if err != nil { + return err + } // return e.createInfrastructure(ctx, cfg, locationProps, deploymentID, nodeName, infra) return nil diff --git a/prov/maas/generator.go b/prov/maas/generator.go new file mode 100644 index 000000000..ce71287ad --- /dev/null +++ b/prov/maas/generator.go @@ -0,0 +1,66 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "context" + + "github.com/pkg/errors" + "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/deployments" + "github.com/ystia/yorc/v4/log" + "github.com/ystia/yorc/v4/tosca" +) + +func generateInfrastructure(ctx context.Context, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances []string) (*infrastructure, error) { + log.Debugf("Generating infrastructure for deployment with id %s", deploymentID) + infra := &infrastructure{} + log.Debugf("inspecting node %s", nodeName) + nodeType, err := deployments.GetNodeType(ctx, deploymentID, nodeName) + if err != nil { + return nil, err + } + + switch nodeType { + case "yorc.nodes.maas.Compute": + var instances []string + instances, err = deployments.GetNodeInstancesIds(ctx, deploymentID, nodeName) + if err != nil { + return nil, err + } + + for _, instanceName := range instances { + var instanceState tosca.NodeState + instanceState, err = deployments.GetInstanceState(ctx, deploymentID, nodeName, instanceName) + if err != nil { + return nil, err + } + + if operation == "install" && instanceState != tosca.NodeStateCreating { + continue + } else if operation == "uninstall" && instanceState != tosca.NodeStateDeleting { + continue + } + + if err := generateNodeAllocation(ctx, locationProps, deploymentID, nodeName, instanceName, infra); err != nil { + return nil, err + } + } + default: + return nil, errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, nodeName, deploymentID) + } + + return infra, nil +} diff --git a/prov/maas/structs.go b/prov/maas/structs.go new file mode 100644 index 000000000..9152be2d5 --- /dev/null +++ b/prov/maas/structs.go @@ -0,0 +1,8 @@ +package maas + +type infrastructure struct { + nodes []*nodeAllocation +} + +type nodeAllocation struct { +} From 2761947d4728ed25daffc033f8d74d09415350ab Mon Sep 17 00:00:00 2001 From: hildericSB Date: Mon, 19 Apr 2021 16:24:56 +0200 Subject: [PATCH 03/23] generateNodeAllocation WIP --- prov/maas/executor.go | 63 +++++++++++++++++++++++++++--------------- prov/maas/generator.go | 16 ++++++++++- prov/maas/maas_node.go | 39 ++++++++++++++++++++++++++ prov/maas/structs.go | 15 ++++++++++ 4 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 prov/maas/maas_node.go diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 005f83962..604e802ac 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -16,13 +16,18 @@ package maas import ( "context" + "fmt" "strings" "github.com/pkg/errors" "github.com/ystia/yorc/v4/config" "github.com/ystia/yorc/v4/deployments" + "github.com/ystia/yorc/v4/events" "github.com/ystia/yorc/v4/locations" + "github.com/ystia/yorc/v4/log" + "github.com/ystia/yorc/v4/tasks" "github.com/ystia/yorc/v4/tosca" + "golang.org/x/sync/errgroup" ) const infrastructureType = "maas" @@ -41,8 +46,8 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura return err } - // Get deployment instances names - instances, err := e.getAvailableInstances(ctx, deploymentID, nodeName) + // Get instances names + instances, err := tasks.GetInstances(ctx, taskID, deploymentID, nodeName) if err != nil { return err } @@ -50,7 +55,7 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura operation := strings.ToLower(delegateOperation) switch { case operation == "install": - err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation, instances) + err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation, &instances) // case operation == "uninstall": // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) default: @@ -59,34 +64,46 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura return err } -func (e *defaultExecutor) getAvailableInstances(ctx context.Context, deploymentID, nodeName string) ([]string, error) { - instances, err := deployments.GetNodeInstancesIds(ctx, deploymentID, nodeName) - if err != nil { - return nil, err - } - - availableIntances := []string{} - for _, instanceName := range instances { - instanceState, err := deployments.GetInstanceState(ctx, deploymentID, nodeName, instanceName) +func (e *defaultExecutor) installNode(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances *[]string) error { + for _, instance := range *instances { + err := deployments.SetInstanceStateWithContextualLogs(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: instance}), deploymentID, nodeName, instance, tosca.NodeStateCreating) if err != nil { - return nil, err - } - if instanceState == tosca.NodeStateDeleting || instanceState == tosca.NodeStateDeleted { - // Do not generate something for this node instance (will be deleted if exists) - continue + return err } - availableIntances = append(availableIntances, instanceName) } - return availableIntances, nil + infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation, instances) + if err != nil { + return err + } + + return e.createInfrastructure(ctx, cfg, locationProps, deploymentID, nodeName, infra) } -func (e *defaultExecutor) installNode(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName string, operation string) error { - infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation) - if err != nil { +func (e *defaultExecutor) createInfrastructure(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName string, infra *infrastructure) error { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString("Creating the maas infrastructure") + var g errgroup.Group + for _, compute := range infra.nodes { + func(ctx context.Context, comp *nodeAllocation) { + g.Go(func() error { + return e.createNodeAllocation(ctx, cfg, locationProps, comp, deploymentID, nodeName) + }) + }(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: compute.instanceName}), compute) + } + + if err := g.Wait(); err != nil { + err = errors.Wrapf(err, "Failed to create maas infrastructure for deploymentID:%q, node name:%s", deploymentID, nodeName) + log.Debugf("%+v", err) + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) return err } - // return e.createInfrastructure(ctx, cfg, locationProps, deploymentID, nodeName, infra) + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString("Successfully creating the maas infrastructure") + return nil +} + +func (e *defaultExecutor) createNodeAllocation(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, nodeAlloc *nodeAllocation, deploymentID, nodeName string) error { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString(fmt.Sprintf("Creating node allocation for: deploymentID:%q, node name:%q", deploymentID, nodeName)) + return nil } diff --git a/prov/maas/generator.go b/prov/maas/generator.go index ce71287ad..538a420b5 100644 --- a/prov/maas/generator.go +++ b/prov/maas/generator.go @@ -24,7 +24,7 @@ import ( "github.com/ystia/yorc/v4/tosca" ) -func generateInfrastructure(ctx context.Context, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances []string) (*infrastructure, error) { +func generateInfrastructure(ctx context.Context, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances *[]string) (*infrastructure, error) { log.Debugf("Generating infrastructure for deployment with id %s", deploymentID) infra := &infrastructure{} log.Debugf("inspecting node %s", nodeName) @@ -33,6 +33,20 @@ func generateInfrastructure(ctx context.Context, locationProps config.DynamicMap return nil, err } + for _, instance := range *instances { + instanceState, err := deployments.GetInstanceState(ctx, deploymentID, nodeName, instance) + if err != nil { + return nil, err + } + + if operation == "install" && instanceState != tosca.NodeStateCreating { + continue + } else if operation == "uninstall" && instanceState != tosca.NodeStateDeleting { + continue + } + + } + switch nodeType { case "yorc.nodes.maas.Compute": var instances []string diff --git a/prov/maas/maas_node.go b/prov/maas/maas_node.go new file mode 100644 index 000000000..94f8477a3 --- /dev/null +++ b/prov/maas/maas_node.go @@ -0,0 +1,39 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "context" + + "github.com/pkg/errors" + + "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/deployments" +) + +func generateNodeAllocation(ctx context.Context, locationProps config.DynamicMap, deploymentID string, nodeName, instanceName string, infra *infrastructure) error { + nodeType, err := deployments.GetNodeType(ctx, deploymentID, nodeName) + if err != nil { + return err + } + if nodeType != "yorc.nodes.maas.Compute" { + return errors.Errorf("Unsupported node type for %q: %s", nodeName, nodeType) + } + + node := &nodeAllocation{instanceName: instanceName} + + infra.nodes = append(infra.nodes, node) + return nil +} diff --git a/prov/maas/structs.go b/prov/maas/structs.go index 9152be2d5..f7f800c91 100644 --- a/prov/maas/structs.go +++ b/prov/maas/structs.go @@ -1,3 +1,17 @@ +// Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package maas type infrastructure struct { @@ -5,4 +19,5 @@ type infrastructure struct { } type nodeAllocation struct { + instanceName string } From c12b4bbdd3552645d900fab9dea4ca4f8c1e23af Mon Sep 17 00:00:00 2001 From: Hilderic Date: Fri, 23 Apr 2021 14:59:51 +0200 Subject: [PATCH 04/23] Allocating a node WIP --- go.mod | 5 ++ go.sum | 22 ++++++ prov/maas/apiCall.go | 175 ++++++++++++++++++++++++++++++++++++++++++ prov/maas/executor.go | 24 ++++++ 4 files changed, 226 insertions(+) create mode 100644 prov/maas/apiCall.go diff --git a/go.mod b/go.mod index 9ed093ad2..cbe9494b0 100644 --- a/go.mod +++ b/go.mod @@ -56,6 +56,11 @@ require ( github.com/hashicorp/vault v0.9.0 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c github.com/jefferai/jsonx v1.0.1 // indirect + github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271 // indirect + github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect + github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767 // indirect + github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e // indirect + github.com/juju/schema v1.0.0 // indirect github.com/julienschmidt/httprouter v1.2.0 github.com/justinas/alice v0.0.0-20160512134231-052b8b6c18ed github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect diff --git a/go.sum b/go.sum index 2d73113d6..0592b272d 100644 --- a/go.sum +++ b/go.sum @@ -267,6 +267,23 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271 h1:4R626WTwa7pRYQFiIRLVPepMhm05eZMEx+wIurRnMLc= +github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271/go.mod h1:5XgO71dV1JClcOJE+4dzdn4HrI5LiyKd7PlVG6eZYhY= +github.com/juju/errors v0.0.0-20150916125642-1b5e39b83d18/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/errors v0.0.0-20200330140219-3fe23663418f h1:MCOvExGLpaSIzLYB4iQXEHP4jYVU6vmzLNQPdMVrxnM= +github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767 h1:b59sh8vHY7lke8eyoxKbGKmOM78DlyMtwQ7ryE3Tuuo= +github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767/go.mod h1:ppx9XlnQMX/+h/kH+cU9kfDUT6GimqGtNRWdobUZVRE= +github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e h1:FdDd7bdI6cjq5vaoYlK1mfQYfF9sF2VZw8VEZMsl5t8= +github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/retry v0.0.0-20151029024821-62c620325291/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= +github.com/juju/schema v1.0.0 h1:sZvJ7iQXHhMw/lJ4YfUmq+fe7R2ZSUzZzd/eSokaB3M= +github.com/juju/schema v1.0.0/go.mod h1:Y+ThzXpUJ0E7NYYocAbuvJ7vTivXfrof/IfRPq/0abI= +github.com/juju/testing v0.0.0-20180402130637-44801989f0f7/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/juju/utils v0.0.0-20180424094159-2000ea4ff043/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= +github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2 h1:loQDi5MyxxNm7Q42mBGuPD6X+F6zw8j5S9yexLgn/BE= +github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/justinas/alice v0.0.0-20160512134231-052b8b6c18ed h1:Ab4XhecWusSSeIfQ2eySh7kffQ1Wsv6fNSkwefr6AVQ= @@ -495,6 +512,7 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= @@ -511,6 +529,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -594,6 +613,7 @@ gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d h1:YjTGSRV59gG1DHCq68v2B771I9dGFxvMkugf7OKglpk= @@ -603,6 +623,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/ory-am/dockertest.v3 v3.3.5 h1:bJGdHNsq45hfEN5oNKBEYHeqnch6F7ZgPE8CHjLe8Ic= @@ -610,6 +631,7 @@ gopkg.in/ory-am/dockertest.v3 v3.3.5/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKek gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170712054546-1be3d31502d6/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go new file mode 100644 index 000000000..93735f93f --- /dev/null +++ b/prov/maas/apiCall.go @@ -0,0 +1,175 @@ +// Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "errors" + "fmt" + "log" + "net/url" + "strings" + "time" + + "github.com/juju/gomaasapi" + "github.com/ystia/yorc/v4/config" +) + +var apiVersion string = "2.0" + +func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, error) { + // Check manadatory maas configuration + if err := checkLocationConfig(locationProps); err != nil { + log.Printf("Unable to provide maas client due to:%+v", err) + return nil, err + } + + apiURL := locationProps.GetString("api_token") + apiKey := locationProps.GetString("api_url") + + authClient, err := gomaasapi.NewAuthenticatedClient(gomaasapi.AddAPIVersionToURL(apiURL, apiVersion), apiKey) + if err != nil { + return nil, err + } + + maas := gomaasapi.NewMAAS(*authClient) + + return maas, nil +} + +func checkLocationConfig(locationProps config.DynamicMap) error { + if strings.Trim(locationProps.GetString("api_url"), "") == "" { + return errors.New("maas location ulr is not set") + } + + if strings.Trim(locationProps.GetString("api_key"), "") == "" { + return errors.New("maas location api key is not set") + } + + // if strings.Trim(locationProps.GetString("user_token"), "") == "" { + // return errors.New("maas location user token is not set") + // } + return nil +} + +// func getMachines(maas *gomaasapi.MAASObject) []byte { +// machineListing := maas.GetSubObject("machines") +// machines, err := machineListing.CallGet("", url.Values{}) +// json, err := machines.MarshalJSON() +// return json +// } + +func allocateMachine(maas *gomaasapi.MAASObject) (string, error) { + machineListing := maas.GetSubObject("machines") + machineJsonObj, err := machineListing.CallPost("allocate", url.Values{}) + if err != nil { + return "", err + } + + machineMaasObj, err := machineJsonObj.GetMAASObject() + if err != nil { + return "", err + } + + system_id, err := machineMaasObj.GetField("system_id") + if err != nil { + return "", err + } + + return system_id, nil +} + +func deploy(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject, error) { + machineListing := maas.GetSubObject("machines/" + system_id) + machineJsonObj, err := machineListing.CallPost("deploy", url.Values{}) + + if err != nil { + return nil, err + } + + return &machineJsonObj, nil +} + +// func release(maas *gomaasapi.MAASObject, system_id string) []byte { +// machineListing := maas.GetSubObject("machines/" + system_id) +// machineJsonObj, err := machineListing.CallPost("release", url.Values{"quick_erase": {"true"}}) + +// json, err := machineJsonObj.MarshalJSON() + +// return json +// } + +func getMachineInfo(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject, error) { + machineListing := maas.GetSubObject("machines/" + system_id) + jsonObj, err := machineListing.CallGet("", url.Values{}) + if err != nil { + return nil, err + } + return &jsonObj, nil +} + +func allocateAndDeploy(maas *gomaasapi.MAASObject) (*gomaasapi.MAASObject, error) { + log.Println("Allocating machine") + system_id, err := allocateMachine(maas) + if err != nil { + return nil, fmt.Errorf("failed to allocate machine: %w", err) + } + + log.Println("Deploying machine with system_id : " + system_id) + json, err := deploy(maas, system_id) + if err != nil { + return nil, err + } + + log.Println("Allocating and deployement of " + system_id + " successfull") + + tmp, err := json.GetMAASObject() + if err != nil { + return nil, fmt.Errorf("error getting mass obj: %w", err) + + } + status, err := tmp.GetField("status_name") + if err != nil { + return nil, fmt.Errorf("error extracting status_name: %w", err) + + } + + var deployRes gomaasapi.MAASObject + for { + time.Sleep(20 * time.Second) + log.Println("Checking if " + system_id + " has finished deploying...") + + json, err = getMachineInfo(maas, system_id) + if err != nil { + return nil, err + } + deployRes, err = json.GetMAASObject() + if err != nil { + return nil, err + } + status, err = deployRes.GetField("status_name") + if err != nil { + return nil, err + } + if status != "Deploying" { + break + } + } + + // if status != "Deployed" { + // return nil, fmt.Errorf("machine still not deployed, status is :" + status) + // } + + return &deployRes, nil +} diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 604e802ac..8cfdd06f7 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -105,5 +105,29 @@ func (e *defaultExecutor) createInfrastructure(ctx context.Context, cfg config.C func (e *defaultExecutor) createNodeAllocation(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, nodeAlloc *nodeAllocation, deploymentID, nodeName string) error { events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString(fmt.Sprintf("Creating node allocation for: deploymentID:%q, node name:%q", deploymentID, nodeName)) + maasClient, err := getMaasClient(locationProps) + if err != nil { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) + return err + } + + deployRes, err := allocateAndDeploy(maasClient) + if err != nil { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) + return err + } + + deployRes = deployRes + + // err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "system_id", deployRes.system_id) + // if err != nil { + // return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, nodeAlloc.instanceName) + // } + + // err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "endpoint", "ip_address", deployRes.ip_address) + // if err != nil { + // return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, nodeAlloc.instanceName) + // } + return nil } From f80a9352f281f095bb8db1a76f5307e06adbc452 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 26 Apr 2021 10:18:16 +0200 Subject: [PATCH 05/23] Allocate and deploy WIP --- prov/maas/apiCall.go | 48 ++++++++++++++++++++++++------------------- prov/maas/executor.go | 18 ++++++++-------- prov/maas/structs.go | 5 +++++ 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index 93735f93f..d11b16d59 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -15,7 +15,6 @@ package maas import ( - "errors" "fmt" "log" "net/url" @@ -23,6 +22,7 @@ import ( "time" "github.com/juju/gomaasapi" + "github.com/pkg/errors" "github.com/ystia/yorc/v4/config" ) @@ -119,7 +119,7 @@ func getMachineInfo(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JS return &jsonObj, nil } -func allocateAndDeploy(maas *gomaasapi.MAASObject) (*gomaasapi.MAASObject, error) { +func allocateAndDeploy(maas *gomaasapi.MAASObject) (*deployResults, error) { log.Println("Allocating machine") system_id, err := allocateMachine(maas) if err != nil { @@ -127,30 +127,19 @@ func allocateAndDeploy(maas *gomaasapi.MAASObject) (*gomaasapi.MAASObject, error } log.Println("Deploying machine with system_id : " + system_id) - json, err := deploy(maas, system_id) + _, err = deploy(maas, system_id) if err != nil { return nil, err } log.Println("Allocating and deployement of " + system_id + " successfull") - - tmp, err := json.GetMAASObject() - if err != nil { - return nil, fmt.Errorf("error getting mass obj: %w", err) - - } - status, err := tmp.GetField("status_name") - if err != nil { - return nil, fmt.Errorf("error extracting status_name: %w", err) - - } - + // Wait for the node to finish deploying var deployRes gomaasapi.MAASObject for { time.Sleep(20 * time.Second) log.Println("Checking if " + system_id + " has finished deploying...") - json, err = getMachineInfo(maas, system_id) + json, err := getMachineInfo(maas, system_id) if err != nil { return nil, err } @@ -158,7 +147,7 @@ func allocateAndDeploy(maas *gomaasapi.MAASObject) (*gomaasapi.MAASObject, error if err != nil { return nil, err } - status, err = deployRes.GetField("status_name") + status, err := deployRes.GetField("status_name") if err != nil { return nil, err } @@ -167,9 +156,26 @@ func allocateAndDeploy(maas *gomaasapi.MAASObject) (*gomaasapi.MAASObject, error } } - // if status != "Deployed" { - // return nil, fmt.Errorf("machine still not deployed, status is :" + status) - // } + // Get machines ips + test := deployRes.GetMap() + ipaddrObj := test["ip_addresses"] + + ipsAddr, err := ipaddrObj.GetArray() + if err != nil { + return nil, err + } + + var ips []string + for _, ipObj := range ipsAddr { + ipString, err := ipObj.GetString() + if err != nil { + return nil, errors.Wrapf(err, "Failed getting ips from machines with system_id : %s", system_id) + } + ips = append(ips, ipString) + } - return &deployRes, nil + return &deployResults{ + ips: ips, + system_id: system_id, + }, nil } diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 8cfdd06f7..43b834e28 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -117,17 +117,15 @@ func (e *defaultExecutor) createNodeAllocation(ctx context.Context, cfg config.C return err } - deployRes = deployRes - - // err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "system_id", deployRes.system_id) - // if err != nil { - // return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, nodeAlloc.instanceName) - // } + err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "system_id", deployRes.system_id) + if err != nil { + return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, nodeAlloc.instanceName) + } - // err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "endpoint", "ip_address", deployRes.ip_address) - // if err != nil { - // return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, nodeAlloc.instanceName) - // } + err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "endpoint", "ip_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, nodeAlloc.instanceName) + } return nil } diff --git a/prov/maas/structs.go b/prov/maas/structs.go index f7f800c91..e7a722597 100644 --- a/prov/maas/structs.go +++ b/prov/maas/structs.go @@ -21,3 +21,8 @@ type infrastructure struct { type nodeAllocation struct { instanceName string } + +type deployResults struct { + ips []string + system_id string +} From 4e6832d07ac3a941b74370b4980cfabc87bdef6e Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 26 Apr 2021 14:39:03 +0200 Subject: [PATCH 06/23] Compute allocating fix --- prov/maas/apiCall.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index d11b16d59..e7e33d557 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -35,8 +35,8 @@ func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, erro return nil, err } - apiURL := locationProps.GetString("api_token") - apiKey := locationProps.GetString("api_url") + apiURL := locationProps.GetString("api_url") + apiKey := locationProps.GetString("api_key") authClient, err := gomaasapi.NewAuthenticatedClient(gomaasapi.AddAPIVersionToURL(apiURL, apiVersion), apiKey) if err != nil { @@ -120,24 +120,24 @@ func getMachineInfo(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JS } func allocateAndDeploy(maas *gomaasapi.MAASObject) (*deployResults, error) { - log.Println("Allocating machine") + // log.Println("Allocating machine") system_id, err := allocateMachine(maas) if err != nil { return nil, fmt.Errorf("failed to allocate machine: %w", err) } - log.Println("Deploying machine with system_id : " + system_id) + // log.Println("Deploying machine with system_id : " + system_id) _, err = deploy(maas, system_id) if err != nil { return nil, err } - log.Println("Allocating and deployement of " + system_id + " successfull") + // log.Println("Allocating and deployement of " + system_id + " successfull") // Wait for the node to finish deploying var deployRes gomaasapi.MAASObject for { time.Sleep(20 * time.Second) - log.Println("Checking if " + system_id + " has finished deploying...") + // log.Println("Checking if " + system_id + " has finished deploying...") json, err := getMachineInfo(maas, system_id) if err != nil { From d37b07810656c62c039c916c3085773bd7e6e69a Mon Sep 17 00:00:00 2001 From: Hilderic Date: Wed, 28 Apr 2021 17:31:04 +0200 Subject: [PATCH 07/23] Code simplification (no more generator) --- prov/maas/apiCall.go | 5 ++ prov/maas/executor.go | 102 +++++++++++++++++------------------ prov/maas/generator.go | 80 ---------------------------- prov/maas/maas_compute.go | 109 ++++++++++++++++++++++++++++++++++++++ prov/maas/maas_node.go | 39 -------------- prov/maas/structs.go | 28 ---------- 6 files changed, 165 insertions(+), 198 deletions(-) delete mode 100644 prov/maas/generator.go create mode 100644 prov/maas/maas_compute.go delete mode 100644 prov/maas/maas_node.go delete mode 100644 prov/maas/structs.go diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index e7e33d557..d3335826c 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -28,6 +28,11 @@ import ( var apiVersion string = "2.0" +type deployResults struct { + ips []string + system_id string +} + func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, error) { // Check manadatory maas configuration if err := checkLocationConfig(locationProps); err != nil { diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 43b834e28..1eeedf3b4 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -16,7 +16,6 @@ package maas import ( "context" - "fmt" "strings" "github.com/pkg/errors" @@ -35,6 +34,16 @@ const infrastructureType = "maas" type defaultExecutor struct { } +type operationParameters struct { + locationProps config.DynamicMap + taskID string + deploymentID string + nodeName string + delegateOperation string + instances []string +} + +// ExecDelegate : Get required operation params and call the operation func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configuration, taskID, deploymentID, nodeName, delegateOperation string) error { // Get locations props var locationProps config.DynamicMap @@ -52,80 +61,71 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura return err } + // Apply operation + operationParams := operationParameters{ + locationProps: locationProps, + taskID: taskID, + deploymentID: deploymentID, + nodeName: nodeName, + delegateOperation: delegateOperation, + instances: instances, + } + operation := strings.ToLower(delegateOperation) switch { case operation == "install": - err = e.installNode(ctx, cfg, locationProps, deploymentID, nodeName, operation, &instances) - // case operation == "uninstall": - // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) + err = e.installNode(ctx, &operationParams) + case operation == "uninstall": + // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) default: return errors.Errorf("Unsupported operation %q", delegateOperation) } return err } -func (e *defaultExecutor) installNode(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances *[]string) error { - for _, instance := range *instances { - err := deployments.SetInstanceStateWithContextualLogs(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: instance}), deploymentID, nodeName, instance, tosca.NodeStateCreating) - if err != nil { - return err - } - } +func (e *defaultExecutor) installNode(ctx context.Context, operationParams *operationParameters) error { + log.Debugf("Installing node %s for deployment %s", operationParams.nodeName, operationParams.deploymentID) - infra, err := generateInfrastructure(ctx, locationProps, deploymentID, nodeName, operation, instances) + // Verify node Type + nodeType, err := deployments.GetNodeType(ctx, operationParams.deploymentID, operationParams.nodeName) if err != nil { return err } + if nodeType != "yorc.nodes.maas.Compute" { + return errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, operationParams.nodeName, operationParams.deploymentID) + } - return e.createInfrastructure(ctx, cfg, locationProps, deploymentID, nodeName, infra) -} + compute, err := getMaasCompute(ctx, operationParams) + + if err != nil { + return errors.Wrapf(err, "Failed to get Compute properties for deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) + } -func (e *defaultExecutor) createInfrastructure(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, deploymentID, nodeName string, infra *infrastructure) error { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString("Creating the maas infrastructure") var g errgroup.Group - for _, compute := range infra.nodes { - func(ctx context.Context, comp *nodeAllocation) { + for _, instance := range operationParams.instances { + instanceState, err := deployments.GetInstanceState(ctx, operationParams.deploymentID, operationParams.nodeName, instance) + if err != nil { + return err + } + + // If instance creating or deleting, ignore it + if instanceState == tosca.NodeStateCreating || instanceState == tosca.NodeStateDeleting { + continue + } + + func(ctx context.Context, comp *maasCompute) { g.Go(func() error { - return e.createNodeAllocation(ctx, cfg, locationProps, comp, deploymentID, nodeName) + return compute.deployOnMaas(ctx, operationParams, instance) }) - }(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: compute.instanceName}), compute) + }(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: instance}), compute) } if err := g.Wait(); err != nil { - err = errors.Wrapf(err, "Failed to create maas infrastructure for deploymentID:%q, node name:%s", deploymentID, nodeName) + err = errors.Wrapf(err, "Failed install node deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) log.Debugf("%+v", err) - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, operationParams.deploymentID).RegisterAsString(err.Error()) return err } - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString("Successfully creating the maas infrastructure") - return nil -} - -func (e *defaultExecutor) createNodeAllocation(ctx context.Context, cfg config.Configuration, locationProps config.DynamicMap, nodeAlloc *nodeAllocation, deploymentID, nodeName string) error { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString(fmt.Sprintf("Creating node allocation for: deploymentID:%q, node name:%q", deploymentID, nodeName)) - - maasClient, err := getMaasClient(locationProps) - if err != nil { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) - return err - } - - deployRes, err := allocateAndDeploy(maasClient) - if err != nil { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) - return err - } - - err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "system_id", deployRes.system_id) - if err != nil { - return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, nodeAlloc.instanceName) - } - - err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, nodeAlloc.instanceName, "endpoint", "ip_address", deployRes.ips[0]) - if err != nil { - return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, nodeAlloc.instanceName) - } - return nil } diff --git a/prov/maas/generator.go b/prov/maas/generator.go deleted file mode 100644 index 538a420b5..000000000 --- a/prov/maas/generator.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package maas - -import ( - "context" - - "github.com/pkg/errors" - "github.com/ystia/yorc/v4/config" - "github.com/ystia/yorc/v4/deployments" - "github.com/ystia/yorc/v4/log" - "github.com/ystia/yorc/v4/tosca" -) - -func generateInfrastructure(ctx context.Context, locationProps config.DynamicMap, deploymentID, nodeName, operation string, instances *[]string) (*infrastructure, error) { - log.Debugf("Generating infrastructure for deployment with id %s", deploymentID) - infra := &infrastructure{} - log.Debugf("inspecting node %s", nodeName) - nodeType, err := deployments.GetNodeType(ctx, deploymentID, nodeName) - if err != nil { - return nil, err - } - - for _, instance := range *instances { - instanceState, err := deployments.GetInstanceState(ctx, deploymentID, nodeName, instance) - if err != nil { - return nil, err - } - - if operation == "install" && instanceState != tosca.NodeStateCreating { - continue - } else if operation == "uninstall" && instanceState != tosca.NodeStateDeleting { - continue - } - - } - - switch nodeType { - case "yorc.nodes.maas.Compute": - var instances []string - instances, err = deployments.GetNodeInstancesIds(ctx, deploymentID, nodeName) - if err != nil { - return nil, err - } - - for _, instanceName := range instances { - var instanceState tosca.NodeState - instanceState, err = deployments.GetInstanceState(ctx, deploymentID, nodeName, instanceName) - if err != nil { - return nil, err - } - - if operation == "install" && instanceState != tosca.NodeStateCreating { - continue - } else if operation == "uninstall" && instanceState != tosca.NodeStateDeleting { - continue - } - - if err := generateNodeAllocation(ctx, locationProps, deploymentID, nodeName, instanceName, infra); err != nil { - return nil, err - } - } - default: - return nil, errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, nodeName, deploymentID) - } - - return infra, nil -} diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go new file mode 100644 index 000000000..aabddb788 --- /dev/null +++ b/prov/maas/maas_compute.go @@ -0,0 +1,109 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "context" + "fmt" + + "github.com/pkg/errors" + "github.com/ystia/yorc/v4/deployments" + "github.com/ystia/yorc/v4/events" + "github.com/ystia/yorc/v4/tosca" +) + +type maasCompute struct { + hostCapabilities hostCapabilities +} + +type hostCapabilities struct { + num_cpus string + mem_size string + disk_size string +} + +func (*maasCompute) deployOnMaas(ctx context.Context, operationParams *operationParameters, instance string) error { + deploymentID := operationParams.deploymentID + nodeName := operationParams.nodeName + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreating) + + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelINFO, deploymentID).RegisterAsString(fmt.Sprintf("Creating node allocation for: deploymentID:%q, node name:%q", deploymentID, nodeName)) + + maasClient, err := getMaasClient(operationParams.locationProps) + if err != nil { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) + return err + } + + deployRes, err := allocateAndDeploy(maasClient) + if err != nil { + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) + return err + } + + err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, instance, "system_id", deployRes.system_id) + if err != nil { + return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, instance) + } + + err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, instance, "endpoint", "ip_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, instance) + } + + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreated) + return nil +} + +func getMaasCompute(ctx context.Context, operationParams *operationParameters) (*maasCompute, error) { + maasCompute := &maasCompute{} + + err := getPropertiesFromHostCapabilities(ctx, operationParams, &maasCompute.hostCapabilities) + if err != nil { + return nil, err + } + + return maasCompute, nil +} + +func getPropertiesFromHostCapabilities(ctx context.Context, operationParams *operationParameters, hostCapabilities *hostCapabilities) error { + deploymentID := operationParams.deploymentID + nodeName := operationParams.nodeName + + p, err := deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "host", "num_cpus") + if err != nil { + return err + } + if p != nil && p.RawString() != "" { + hostCapabilities.num_cpus = p.RawString() + } + + p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "host", "mem_size") + if err != nil { + return err + } + if p != nil && p.RawString() != "" { + hostCapabilities.mem_size = p.RawString() + } + + p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "host", "disk_size") + if err != nil { + return err + } + if p != nil && p.RawString() != "" { + hostCapabilities.disk_size = p.RawString() + } + return nil +} diff --git a/prov/maas/maas_node.go b/prov/maas/maas_node.go deleted file mode 100644 index 94f8477a3..000000000 --- a/prov/maas/maas_node.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package maas - -import ( - "context" - - "github.com/pkg/errors" - - "github.com/ystia/yorc/v4/config" - "github.com/ystia/yorc/v4/deployments" -) - -func generateNodeAllocation(ctx context.Context, locationProps config.DynamicMap, deploymentID string, nodeName, instanceName string, infra *infrastructure) error { - nodeType, err := deployments.GetNodeType(ctx, deploymentID, nodeName) - if err != nil { - return err - } - if nodeType != "yorc.nodes.maas.Compute" { - return errors.Errorf("Unsupported node type for %q: %s", nodeName, nodeType) - } - - node := &nodeAllocation{instanceName: instanceName} - - infra.nodes = append(infra.nodes, node) - return nil -} diff --git a/prov/maas/structs.go b/prov/maas/structs.go deleted file mode 100644 index e7a722597..000000000 --- a/prov/maas/structs.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package maas - -type infrastructure struct { - nodes []*nodeAllocation -} - -type nodeAllocation struct { - instanceName string -} - -type deployResults struct { - ips []string - system_id string -} From 46e500c23da0475fc18a4ec95832a1713ac5e7c3 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Thu, 29 Apr 2021 15:25:47 +0200 Subject: [PATCH 08/23] Undeploy compute --- prov/maas/apiCall.go | 15 ++++++------ prov/maas/executor.go | 50 +++++++++++++++++++++++++++++++++++++-- prov/maas/maas_compute.go | 26 +++++++++++++++++++- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index d3335826c..30a1c1d22 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -106,14 +106,15 @@ func deploy(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject return &machineJsonObj, nil } -// func release(maas *gomaasapi.MAASObject, system_id string) []byte { -// machineListing := maas.GetSubObject("machines/" + system_id) -// machineJsonObj, err := machineListing.CallPost("release", url.Values{"quick_erase": {"true"}}) - -// json, err := machineJsonObj.MarshalJSON() +func release(maas *gomaasapi.MAASObject, system_id string) error { + machineListing := maas.GetSubObject("machines/" + system_id) + _, err := machineListing.CallPost("release", url.Values{"quick_erase": {"true"}}) + if err != nil { + return err + } -// return json -// } + return nil +} func getMachineInfo(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject, error) { machineListing := maas.GetSubObject("machines/" + system_id) diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 1eeedf3b4..9e8a428bd 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -76,7 +76,7 @@ func (e *defaultExecutor) ExecDelegate(ctx context.Context, cfg config.Configura case operation == "install": err = e.installNode(ctx, &operationParams) case operation == "uninstall": - // err = e.uninstallNode(ctx, cfg, locationProps, deploymentID, nodeName, instances, operation) + err = e.uninstallNode(ctx, &operationParams) default: return errors.Errorf("Unsupported operation %q", delegateOperation) } @@ -115,7 +115,53 @@ func (e *defaultExecutor) installNode(ctx context.Context, operationParams *oper func(ctx context.Context, comp *maasCompute) { g.Go(func() error { - return compute.deployOnMaas(ctx, operationParams, instance) + return compute.deploy(ctx, operationParams, instance) + }) + }(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: instance}), compute) + } + + if err := g.Wait(); err != nil { + err = errors.Wrapf(err, "Failed install node deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) + log.Debugf("%+v", err) + events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, operationParams.deploymentID).RegisterAsString(err.Error()) + return err + } + + return nil +} + +func (e *defaultExecutor) uninstallNode(ctx context.Context, operationParams *operationParameters) error { + log.Debugf("Uninstalling node %s for deployment %s", operationParams.nodeName, operationParams.deploymentID) + + // Verify node Type + nodeType, err := deployments.GetNodeType(ctx, operationParams.deploymentID, operationParams.nodeName) + if err != nil { + return err + } + if nodeType != "yorc.nodes.maas.Compute" { + return errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, operationParams.nodeName, operationParams.deploymentID) + } + + compute, err := getMaasCompute(ctx, operationParams) + if err != nil { + return errors.Wrapf(err, "Failed to get Compute properties for deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) + } + + var g errgroup.Group + for _, instance := range operationParams.instances { + instanceState, err := deployments.GetInstanceState(ctx, operationParams.deploymentID, operationParams.nodeName, instance) + if err != nil { + return err + } + + // If instance creating or deleting, ignore it + if instanceState == tosca.NodeStateCreating || instanceState == tosca.NodeStateDeleting { + continue + } + + func(ctx context.Context, comp *maasCompute) { + g.Go(func() error { + return compute.undeploy(ctx, operationParams, instance) }) }(events.AddLogOptionalFields(ctx, events.LogOptionalFields{events.InstanceID: instance}), compute) } diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index aabddb788..4f4ae0ac7 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -34,7 +34,7 @@ type hostCapabilities struct { disk_size string } -func (*maasCompute) deployOnMaas(ctx context.Context, operationParams *operationParameters, instance string) error { +func (*maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreating) @@ -107,3 +107,27 @@ func getPropertiesFromHostCapabilities(ctx context.Context, operationParams *ope } return nil } + +func (*maasCompute) undeploy(ctx context.Context, operationParams *operationParameters, instance string) error { + deploymentID := operationParams.deploymentID + nodeName := operationParams.nodeName + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleting) + + maasClient, err := getMaasClient(operationParams.locationProps) + if err != nil { + return err + } + + system_id, err := deployments.GetInstanceAttributeValue(ctx, deploymentID, nodeName, instance, "system_id") + if err != nil { + return errors.Wrapf(err, "can't find instance attribute system id for nodename:%s deployementId: %s", nodeName, deploymentID) + } + + err = release(maasClient, system_id.RawString()) + if err != nil { + return errors.Wrapf(err, "Release API call error for nodename:%s deployementId: %s", nodeName, deploymentID) + } + + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleted) + return nil +} From cff2ed2e2a8b66be9dc87ad5f5aa59b06c85fa34 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Thu, 29 Apr 2021 15:28:26 +0200 Subject: [PATCH 09/23] Removing code smell --- prov/maas/apiCall.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index 30a1c1d22..ea318e403 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -106,8 +106,8 @@ func deploy(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject return &machineJsonObj, nil } -func release(maas *gomaasapi.MAASObject, system_id string) error { - machineListing := maas.GetSubObject("machines/" + system_id) +func release(maas *gomaasapi.MAASObject, systemId string) error { + machineListing := maas.GetSubObject("machines/" + systemId) _, err := machineListing.CallPost("release", url.Values{"quick_erase": {"true"}}) if err != nil { return err @@ -116,8 +116,8 @@ func release(maas *gomaasapi.MAASObject, system_id string) error { return nil } -func getMachineInfo(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject, error) { - machineListing := maas.GetSubObject("machines/" + system_id) +func getMachineInfo(maas *gomaasapi.MAASObject, systemId string) (*gomaasapi.JSONObject, error) { + machineListing := maas.GetSubObject("machines/" + systemId) jsonObj, err := machineListing.CallGet("", url.Values{}) if err != nil { return nil, err From 6afb3e68474089bb7cf91768b1a78a60092745fd Mon Sep 17 00:00:00 2001 From: Hilderic Date: Fri, 30 Apr 2021 08:46:01 +0200 Subject: [PATCH 10/23] MEM allocation support --- prov/maas/apiCall.go | 22 ++++++++++++++++++---- prov/maas/maas_compute.go | 6 ++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index ea318e403..db882daca 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -21,6 +21,7 @@ import ( "strings" "time" + "github.com/dustin/go-humanize" "github.com/juju/gomaasapi" "github.com/pkg/errors" "github.com/ystia/yorc/v4/config" @@ -75,9 +76,22 @@ func checkLocationConfig(locationProps config.DynamicMap) error { // return json // } -func allocateMachine(maas *gomaasapi.MAASObject) (string, error) { +func allocateMachine(maas *gomaasapi.MAASObject, compute *maasCompute) (string, error) { + host := compute.hostCapabilities + + // Convert mem into MB without text + mem, err := humanize.ParseBytes(host.mem_size) + if err != nil { + return "", err + } + mem = mem / 1000000 + fmt.Println("mem size : " + fmt.Sprint(mem)) + machineListing := maas.GetSubObject("machines") - machineJsonObj, err := machineListing.CallPost("allocate", url.Values{}) + machineJsonObj, err := machineListing.CallPost("allocate", url.Values{ + "cpu_count": {host.num_cpus}, + "mem": {fmt.Sprint(mem)}, + }) if err != nil { return "", err } @@ -125,9 +139,9 @@ func getMachineInfo(maas *gomaasapi.MAASObject, systemId string) (*gomaasapi.JSO return &jsonObj, nil } -func allocateAndDeploy(maas *gomaasapi.MAASObject) (*deployResults, error) { +func allocateAndDeploy(maas *gomaasapi.MAASObject, compute *maasCompute) (*deployResults, error) { // log.Println("Allocating machine") - system_id, err := allocateMachine(maas) + system_id, err := allocateMachine(maas, compute) if err != nil { return nil, fmt.Errorf("failed to allocate machine: %w", err) } diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 4f4ae0ac7..5641f1aa9 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -34,7 +34,7 @@ type hostCapabilities struct { disk_size string } -func (*maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { +func (compute *maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreating) @@ -43,13 +43,11 @@ func (*maasCompute) deploy(ctx context.Context, operationParams *operationParame maasClient, err := getMaasClient(operationParams.locationProps) if err != nil { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) return err } - deployRes, err := allocateAndDeploy(maasClient) + deployRes, err := allocateAndDeploy(maasClient, compute) if err != nil { - events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, deploymentID).RegisterAsString(err.Error()) return err } From 3569ca0bc851966e52305b37bd3a994758d829dd Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 3 May 2021 10:31:42 +0200 Subject: [PATCH 11/23] OS and MEM deploy support --- prov/maas/apiCall.go | 65 +++++++++++++------------ prov/maas/executor.go | 4 +- prov/maas/maas_compute.go | 99 ++++++++++++++++++++++++++++++++------- 3 files changed, 121 insertions(+), 47 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index db882daca..de6bf114a 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -21,7 +21,6 @@ import ( "strings" "time" - "github.com/dustin/go-humanize" "github.com/juju/gomaasapi" "github.com/pkg/errors" "github.com/ystia/yorc/v4/config" @@ -29,11 +28,38 @@ import ( var apiVersion string = "2.0" +type allocateParams struct { + values url.Values +} +type deployParams struct { + values url.Values + system_id string +} + type deployResults struct { ips []string system_id string } +func newAllocateParams(num_cpus, RAM string) *allocateParams { + values := url.Values{ + "cpu_count": {num_cpus}, + "mem": {RAM}, + } + return &allocateParams{ + values: values, + } +} + +func newDeployParams(distro_series string) *deployParams { + values := url.Values{ + "distro_series": {distro_series}, + } + return &deployParams{ + values: values, + } +} + func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, error) { // Check manadatory maas configuration if err := checkLocationConfig(locationProps); err != nil { @@ -62,10 +88,6 @@ func checkLocationConfig(locationProps config.DynamicMap) error { if strings.Trim(locationProps.GetString("api_key"), "") == "" { return errors.New("maas location api key is not set") } - - // if strings.Trim(locationProps.GetString("user_token"), "") == "" { - // return errors.New("maas location user token is not set") - // } return nil } @@ -76,22 +98,10 @@ func checkLocationConfig(locationProps config.DynamicMap) error { // return json // } -func allocateMachine(maas *gomaasapi.MAASObject, compute *maasCompute) (string, error) { - host := compute.hostCapabilities - - // Convert mem into MB without text - mem, err := humanize.ParseBytes(host.mem_size) - if err != nil { - return "", err - } - mem = mem / 1000000 - fmt.Println("mem size : " + fmt.Sprint(mem)) +func allocateMachine(maas *gomaasapi.MAASObject, allocateParams *allocateParams) (string, error) { machineListing := maas.GetSubObject("machines") - machineJsonObj, err := machineListing.CallPost("allocate", url.Values{ - "cpu_count": {host.num_cpus}, - "mem": {fmt.Sprint(mem)}, - }) + machineJsonObj, err := machineListing.CallPost("allocate", allocateParams.values) if err != nil { return "", err } @@ -109,9 +119,9 @@ func allocateMachine(maas *gomaasapi.MAASObject, compute *maasCompute) (string, return system_id, nil } -func deploy(maas *gomaasapi.MAASObject, system_id string) (*gomaasapi.JSONObject, error) { - machineListing := maas.GetSubObject("machines/" + system_id) - machineJsonObj, err := machineListing.CallPost("deploy", url.Values{}) +func deploy(maas *gomaasapi.MAASObject, deployParams *deployParams) (*gomaasapi.JSONObject, error) { + machineListing := maas.GetSubObject("machines/" + deployParams.system_id) + machineJsonObj, err := machineListing.CallPost("deploy", deployParams.values) if err != nil { return nil, err @@ -139,25 +149,22 @@ func getMachineInfo(maas *gomaasapi.MAASObject, systemId string) (*gomaasapi.JSO return &jsonObj, nil } -func allocateAndDeploy(maas *gomaasapi.MAASObject, compute *maasCompute) (*deployResults, error) { - // log.Println("Allocating machine") - system_id, err := allocateMachine(maas, compute) +func allocateAndDeploy(maas *gomaasapi.MAASObject, allocateParams *allocateParams, deployParams *deployParams) (*deployResults, error) { + system_id, err := allocateMachine(maas, allocateParams) if err != nil { return nil, fmt.Errorf("failed to allocate machine: %w", err) } + deployParams.system_id = system_id - // log.Println("Deploying machine with system_id : " + system_id) - _, err = deploy(maas, system_id) + _, err = deploy(maas, deployParams) if err != nil { return nil, err } - // log.Println("Allocating and deployement of " + system_id + " successfull") // Wait for the node to finish deploying var deployRes gomaasapi.MAASObject for { time.Sleep(20 * time.Second) - // log.Println("Checking if " + system_id + " has finished deploying...") json, err := getMachineInfo(maas, system_id) if err != nil { diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 9e8a428bd..4d5fc9c10 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -95,7 +95,7 @@ func (e *defaultExecutor) installNode(ctx context.Context, operationParams *oper return errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, operationParams.nodeName, operationParams.deploymentID) } - compute, err := getMaasCompute(ctx, operationParams) + compute, err := getComputeFromDeployment(ctx, operationParams) if err != nil { return errors.Wrapf(err, "Failed to get Compute properties for deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) @@ -142,7 +142,7 @@ func (e *defaultExecutor) uninstallNode(ctx context.Context, operationParams *op return errors.Errorf("Unsupported node type '%s' for node '%s' in deployment '%s'", nodeType, operationParams.nodeName, operationParams.deploymentID) } - compute, err := getMaasCompute(ctx, operationParams) + compute, err := getComputeFromDeployment(ctx, operationParams) if err != nil { return errors.Wrapf(err, "Failed to get Compute properties for deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) } diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 5641f1aa9..1d8777fe5 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -18,6 +18,7 @@ import ( "context" "fmt" + "github.com/dustin/go-humanize" "github.com/pkg/errors" "github.com/ystia/yorc/v4/deployments" "github.com/ystia/yorc/v4/events" @@ -25,7 +26,8 @@ import ( ) type maasCompute struct { - hostCapabilities hostCapabilities + host hostCapabilities + os osCapabilities } type hostCapabilities struct { @@ -34,7 +36,13 @@ type hostCapabilities struct { disk_size string } -func (compute *maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { +type osCapabilities struct { + architecture string + distribution string + version string +} + +func (c *maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreating) @@ -46,7 +54,12 @@ func (compute *maasCompute) deploy(ctx context.Context, operationParams *operati return err } - deployRes, err := allocateAndDeploy(maasClient, compute) + allocateParams, err := c.buildAllocateParams() + if err != nil { + return err + } + + deployRes, err := allocateAndDeploy(maasClient, allocateParams, newDeployParams(c.os.distribution)) if err != nil { return err } @@ -65,10 +78,15 @@ func (compute *maasCompute) deploy(ctx context.Context, operationParams *operati return nil } -func getMaasCompute(ctx context.Context, operationParams *operationParameters) (*maasCompute, error) { +func getComputeFromDeployment(ctx context.Context, operationParams *operationParameters) (*maasCompute, error) { maasCompute := &maasCompute{} - err := getPropertiesFromHostCapabilities(ctx, operationParams, &maasCompute.hostCapabilities) + err := maasCompute.getAndsetPropertiesFromHostCapabilities(ctx, operationParams) + if err != nil { + return nil, err + } + + err = maasCompute.getAndsetPropertiesFromOSCapabilities(ctx, operationParams) if err != nil { return nil, err } @@ -76,9 +94,35 @@ func getMaasCompute(ctx context.Context, operationParams *operationParameters) ( return maasCompute, nil } -func getPropertiesFromHostCapabilities(ctx context.Context, operationParams *operationParameters, hostCapabilities *hostCapabilities) error { +func (*maasCompute) undeploy(ctx context.Context, operationParams *operationParameters, instance string) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleting) + + maasClient, err := getMaasClient(operationParams.locationProps) + if err != nil { + return err + } + + system_id, err := deployments.GetInstanceAttributeValue(ctx, deploymentID, nodeName, instance, "system_id") + if err != nil || system_id == nil { + return errors.Wrapf(err, "can't find instance attribute system id for nodename:%s deployementId: %s \n Maybe last deployement was not successful", nodeName, deploymentID) + } + + err = release(maasClient, system_id.RawString()) + if err != nil { + return errors.Wrapf(err, "Release API call error for nodename:%s deployementId: %s", nodeName, deploymentID) + } + + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleted) + return nil +} + +// Set host capabilities using deployments values +func (c *maasCompute) getAndsetPropertiesFromHostCapabilities(ctx context.Context, operationParams *operationParameters) error { + deploymentID := operationParams.deploymentID + nodeName := operationParams.nodeName + hostCapabilities := &c.host p, err := deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "host", "num_cpus") if err != nil { @@ -106,26 +150,49 @@ func getPropertiesFromHostCapabilities(ctx context.Context, operationParams *ope return nil } -func (*maasCompute) undeploy(ctx context.Context, operationParams *operationParameters, instance string) error { +// Set os capabilities using deployments values +func (c *maasCompute) getAndsetPropertiesFromOSCapabilities(ctx context.Context, operationParams *operationParameters) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName - deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleting) + os := &c.os - maasClient, err := getMaasClient(operationParams.locationProps) + p, err := deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "architecture") if err != nil { return err } - - system_id, err := deployments.GetInstanceAttributeValue(ctx, deploymentID, nodeName, instance, "system_id") - if err != nil { - return errors.Wrapf(err, "can't find instance attribute system id for nodename:%s deployementId: %s", nodeName, deploymentID) + if p != nil && p.RawString() != "" { + os.architecture = p.RawString() } - err = release(maasClient, system_id.RawString()) + p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "distribution") if err != nil { - return errors.Wrapf(err, "Release API call error for nodename:%s deployementId: %s", nodeName, deploymentID) + return err + } + if p != nil && p.RawString() != "" { + os.distribution = p.RawString() } - deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleted) + // p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "version") + // if err != nil { + // return err + // } + // if p != nil && p.RawString() != "" { + // os.version = p.RawString() + // } return nil } + +func (c *maasCompute) buildAllocateParams() (*allocateParams, error) { + // Convert mem into MB without text + mem := "" + if c.host.mem_size != "" { + memInt, err := humanize.ParseBytes(c.host.mem_size) + if err != nil { + return nil, err + } + memInt = memInt / 1000000 + mem = fmt.Sprint(memInt) + } + + return newAllocateParams(c.host.num_cpus, mem), nil +} From cc8ee8fcfbc9b528692e9275173ff71446a9bfd3 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 3 May 2021 11:12:16 +0200 Subject: [PATCH 12/23] Adding arch support --- prov/maas/apiCall.go | 4 +++- prov/maas/maas_compute.go | 17 ++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index de6bf114a..e80bd65de 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -41,10 +41,12 @@ type deployResults struct { system_id string } -func newAllocateParams(num_cpus, RAM string) *allocateParams { +func newAllocateParams(num_cpus, RAM, arch, storage string) *allocateParams { values := url.Values{ "cpu_count": {num_cpus}, "mem": {RAM}, + "arch": {arch}, + "storage": {storage}, } return &allocateParams{ values: values, diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 1d8777fe5..22dcbfe48 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -39,7 +39,6 @@ type hostCapabilities struct { type osCapabilities struct { architecture string distribution string - version string } func (c *maasCompute) deploy(ctx context.Context, operationParams *operationParameters, instance string) error { @@ -172,13 +171,13 @@ func (c *maasCompute) getAndsetPropertiesFromOSCapabilities(ctx context.Context, os.distribution = p.RawString() } - // p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "version") - // if err != nil { - // return err - // } - // if p != nil && p.RawString() != "" { - // os.version = p.RawString() - // } + p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "architecture") + if err != nil { + return err + } + if p != nil && p.RawString() != "" { + os.architecture = p.RawString() + } return nil } @@ -194,5 +193,5 @@ func (c *maasCompute) buildAllocateParams() (*allocateParams, error) { mem = fmt.Sprint(memInt) } - return newAllocateParams(c.host.num_cpus, mem), nil + return newAllocateParams(c.host.num_cpus, mem, c.os.architecture, ""), nil } From 0ba4c805c254f43e27bc0390626a7a65bfe21b37 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Tue, 4 May 2021 12:25:26 +0200 Subject: [PATCH 13/23] delayBetweenStatusCheck as loc config --- prov/maas/apiCall.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index e80bd65de..29451983a 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -27,6 +27,7 @@ import ( ) var apiVersion string = "2.0" +var delayBetweenStatusCheck string = "20s" type allocateParams struct { values url.Values @@ -63,7 +64,7 @@ func newDeployParams(distro_series string) *deployParams { } func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, error) { - // Check manadatory maas configuration + // Check mandatory maas configuration if err := checkLocationConfig(locationProps); err != nil { log.Printf("Unable to provide maas client due to:%+v", err) return nil, err @@ -72,6 +73,11 @@ func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, erro apiURL := locationProps.GetString("api_url") apiKey := locationProps.GetString("api_key") + stringDelay := locationProps.GetString("delayBetweenStatusCheck") + if stringDelay != "" { + delayBetweenStatusCheck = stringDelay + } + authClient, err := gomaasapi.NewAuthenticatedClient(gomaasapi.AddAPIVersionToURL(apiURL, apiVersion), apiKey) if err != nil { return nil, err @@ -164,9 +170,13 @@ func allocateAndDeploy(maas *gomaasapi.MAASObject, allocateParams *allocateParam } // Wait for the node to finish deploying + duration, err := time.ParseDuration(delayBetweenStatusCheck) + if err != nil { + return nil, err + } var deployRes gomaasapi.MAASObject for { - time.Sleep(20 * time.Second) + time.Sleep(duration) json, err := getMachineInfo(maas, system_id) if err != nil { From 12452235e032473ace1f75eddc9dce6a70e2ad2f Mon Sep 17 00:00:00 2001 From: Hilderic Date: Fri, 7 May 2021 10:13:06 +0200 Subject: [PATCH 14/23] Supporting more compute properties --- data/tosca/yorc-maas-types.yml | 26 ++++++- prov/maas/apiCall.go | 25 +++++-- prov/maas/maas_compute.go | 120 +++++++++++++++++++++++++++------ 3 files changed, 145 insertions(+), 26 deletions(-) diff --git a/data/tosca/yorc-maas-types.yml b/data/tosca/yorc-maas-types.yml index 0cf8db7d3..add91db62 100644 --- a/data/tosca/yorc-maas-types.yml +++ b/data/tosca/yorc-maas-types.yml @@ -12,6 +12,30 @@ node_types: yorc.nodes.maas.Compute: derived_from: yorc.nodes.Compute properties: + distro_series: + type: string + required: false + description: If present, this parameter specifies the OS the machine will use. Else the MASS default OS will be use. + arch : + type: string + required: false + description: Architecture of the returned machine (e.g. 'i386/generic', 'amd64', 'armhf/highbank', etc.). + erase: + type: string + required: false + description: Erase the disk when undeploying. if neither secure_erase nor quick_erase are specified, MAAS will overwrite the whole disk with null bytes. This can be very slow. + secure_erase: + type: string + required: false + description: Use the drive's secure erase feature if available. In some cases, this can be much faster than overwriting the drive. Some drives implement secure erasure by overwriting themselves so this could still be slow. + quick_erase: + type: string + required: false + description: Wipe 2MiB at the start and at the end of the drive to make data recovery inconvenient and unlikely to happen by accident. This is not secure. + tags: + type: string + required: false + description: Comma seperated list of tags that the machine must match in order to be acquired. If multiple tag names are specified, the machine must be tagged with all of them. capabilities: host: - type: tosca.capabilities.Container + type: tosca.capabilities.Container \ No newline at end of file diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index 29451983a..4d82cfb38 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -37,17 +37,23 @@ type deployParams struct { system_id string } +type releaseParams struct { + values url.Values + system_id string +} + type deployResults struct { ips []string system_id string } -func newAllocateParams(num_cpus, RAM, arch, storage string) *allocateParams { +func newAllocateParams(num_cpus, RAM, arch, storage, tags string) *allocateParams { values := url.Values{ "cpu_count": {num_cpus}, "mem": {RAM}, "arch": {arch}, "storage": {storage}, + "tags": {tags}, } return &allocateParams{ values: values, @@ -63,6 +69,17 @@ func newDeployParams(distro_series string) *deployParams { } } +func newReleaseParams(erase, secure_erase, quick_erase string) *releaseParams { + values := url.Values{ + "erase": {erase}, + "secure_erase": {secure_erase}, + "quick_erase": {quick_erase}, + } + return &releaseParams{ + values: values, + } +} + func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, error) { // Check mandatory maas configuration if err := checkLocationConfig(locationProps); err != nil { @@ -138,9 +155,9 @@ func deploy(maas *gomaasapi.MAASObject, deployParams *deployParams) (*gomaasapi. return &machineJsonObj, nil } -func release(maas *gomaasapi.MAASObject, systemId string) error { - machineListing := maas.GetSubObject("machines/" + systemId) - _, err := machineListing.CallPost("release", url.Values{"quick_erase": {"true"}}) +func release(maas *gomaasapi.MAASObject, releaseParams *releaseParams) error { + machineListing := maas.GetSubObject("machines/" + releaseParams.system_id) + _, err := machineListing.CallPost("release", releaseParams.values) if err != nil { return err } diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 22dcbfe48..12da478c3 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -26,8 +26,14 @@ import ( ) type maasCompute struct { - host hostCapabilities - os osCapabilities + distro_series string + arch string + erase string + secure_erase string + quick_erase string + tags string + host hostCapabilities + os osCapabilities } type hostCapabilities struct { @@ -58,7 +64,7 @@ func (c *maasCompute) deploy(ctx context.Context, operationParams *operationPara return err } - deployRes, err := allocateAndDeploy(maasClient, allocateParams, newDeployParams(c.os.distribution)) + deployRes, err := allocateAndDeploy(maasClient, allocateParams, newDeployParams(c.distro_series)) if err != nil { return err } @@ -80,7 +86,12 @@ func (c *maasCompute) deploy(ctx context.Context, operationParams *operationPara func getComputeFromDeployment(ctx context.Context, operationParams *operationParameters) (*maasCompute, error) { maasCompute := &maasCompute{} - err := maasCompute.getAndsetPropertiesFromHostCapabilities(ctx, operationParams) + err := maasCompute.getAndsetProperties(ctx, operationParams) + if err != nil { + return nil, err + } + + err = maasCompute.getAndsetPropertiesFromHostCapabilities(ctx, operationParams) if err != nil { return nil, err } @@ -93,7 +104,7 @@ func getComputeFromDeployment(ctx context.Context, operationParams *operationPar return maasCompute, nil } -func (*maasCompute) undeploy(ctx context.Context, operationParams *operationParameters, instance string) error { +func (c *maasCompute) undeploy(ctx context.Context, operationParams *operationParameters, instance string) error { deploymentID := operationParams.deploymentID nodeName := operationParams.nodeName deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateDeleting) @@ -108,7 +119,10 @@ func (*maasCompute) undeploy(ctx context.Context, operationParams *operationPara return errors.Wrapf(err, "can't find instance attribute system id for nodename:%s deployementId: %s \n Maybe last deployement was not successful", nodeName, deploymentID) } - err = release(maasClient, system_id.RawString()) + releaseParams := newReleaseParams(c.erase, c.secure_erase, c.quick_erase) + releaseParams.system_id = system_id.RawString() + + err = release(maasClient, releaseParams) if err != nil { return errors.Wrapf(err, "Release API call error for nodename:%s deployementId: %s", nodeName, deploymentID) } @@ -117,6 +131,85 @@ func (*maasCompute) undeploy(ctx context.Context, operationParams *operationPara return nil } +func (c *maasCompute) buildAllocateParams() (*allocateParams, error) { + // Convert mem into MB without text + mem := "" + if c.host.mem_size != "" { + memInt, err := humanize.ParseBytes(c.host.mem_size) + if err != nil { + return nil, err + } + memInt = memInt / 1000000 + mem = fmt.Sprint(memInt) + } + + storage := "" + if c.host.disk_size != "" { + storageInt, err := humanize.ParseBytes(c.host.disk_size) + if err != nil { + return nil, err + } + storageInt = storageInt / 1000000000 + storage = "label:" + fmt.Sprint(storageInt) + } + return newAllocateParams(c.host.num_cpus, mem, c.arch, storage, c.tags), nil +} + +// Set host capabilities using deployments values +func (c *maasCompute) getAndsetProperties(ctx context.Context, operationParams *operationParameters) error { + deploymentID := operationParams.deploymentID + nodeName := operationParams.nodeName + + p, err := deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "distro_series", false) + if err != nil { + return err + } + if p != "" { + c.distro_series = p + } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "arch", false) + if err != nil { + return err + } + if p != "" { + c.arch = p + } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "erase", false) + if err != nil { + return err + } + if p != "" { + c.erase = p + } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "secure_erase", false) + if err != nil { + return err + } + if p != "" { + c.secure_erase = p + } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "quick_erase", false) + if err != nil { + return err + } + if p != "" { + c.quick_erase = p + } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "tags", false) + if err != nil { + return err + } + if p != "" { + c.tags = p + } + return nil +} + // Set host capabilities using deployments values func (c *maasCompute) getAndsetPropertiesFromHostCapabilities(ctx context.Context, operationParams *operationParameters) error { deploymentID := operationParams.deploymentID @@ -180,18 +273,3 @@ func (c *maasCompute) getAndsetPropertiesFromOSCapabilities(ctx context.Context, } return nil } - -func (c *maasCompute) buildAllocateParams() (*allocateParams, error) { - // Convert mem into MB without text - mem := "" - if c.host.mem_size != "" { - memInt, err := humanize.ParseBytes(c.host.mem_size) - if err != nil { - return nil, err - } - memInt = memInt / 1000000 - mem = fmt.Sprint(memInt) - } - - return newAllocateParams(c.host.num_cpus, mem, c.os.architecture, ""), nil -} From 838e2d7d705624c1dad16380bc2f7b565e4ce20e Mon Sep 17 00:00:00 2001 From: Hilderic Date: Wed, 12 May 2021 11:25:48 +0200 Subject: [PATCH 15/23] Some properties fixes --- data/tosca/yorc-maas-types.yml | 8 ++++---- prov/maas/executor.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/tosca/yorc-maas-types.yml b/data/tosca/yorc-maas-types.yml index add91db62..68a85f683 100644 --- a/data/tosca/yorc-maas-types.yml +++ b/data/tosca/yorc-maas-types.yml @@ -21,21 +21,21 @@ node_types: required: false description: Architecture of the returned machine (e.g. 'i386/generic', 'amd64', 'armhf/highbank', etc.). erase: - type: string + type: boolean required: false description: Erase the disk when undeploying. if neither secure_erase nor quick_erase are specified, MAAS will overwrite the whole disk with null bytes. This can be very slow. secure_erase: - type: string + type: boolean required: false description: Use the drive's secure erase feature if available. In some cases, this can be much faster than overwriting the drive. Some drives implement secure erasure by overwriting themselves so this could still be slow. quick_erase: - type: string + type: boolean required: false description: Wipe 2MiB at the start and at the end of the drive to make data recovery inconvenient and unlikely to happen by accident. This is not secure. tags: type: string required: false - description: Comma seperated list of tags that the machine must match in order to be acquired. If multiple tag names are specified, the machine must be tagged with all of them. + description: Comma separated list of tags that the machine must match in order to be acquired. If multiple tag names are specified, the machine must be tagged with all of them. capabilities: host: type: tosca.capabilities.Container \ No newline at end of file diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 4d5fc9c10..87d75c0c4 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -154,8 +154,8 @@ func (e *defaultExecutor) uninstallNode(ctx context.Context, operationParams *op return err } - // If instance creating or deleting, ignore it - if instanceState == tosca.NodeStateCreating || instanceState == tosca.NodeStateDeleting { + // If instance deleting, ignore it + if instanceState == tosca.NodeStateDeleting { continue } From 3e268164e7c454b64d480a404a7b07544db61213 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Wed, 12 May 2021 16:26:20 +0200 Subject: [PATCH 16/23] not tags + private_address --- data/tosca/yorc-maas-types.yml | 4 ++++ prov/maas/apiCall.go | 3 ++- prov/maas/maas_compute.go | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/data/tosca/yorc-maas-types.yml b/data/tosca/yorc-maas-types.yml index 68a85f683..8f95efd03 100644 --- a/data/tosca/yorc-maas-types.yml +++ b/data/tosca/yorc-maas-types.yml @@ -36,6 +36,10 @@ node_types: type: string required: false description: Comma separated list of tags that the machine must match in order to be acquired. If multiple tag names are specified, the machine must be tagged with all of them. + not_tags: + type: string + required: false + description: Comma separated list of tags that the machine must NOT match. If multiple tag names are specified, the machine must NOT be tagged with ANY of them. capabilities: host: type: tosca.capabilities.Container \ No newline at end of file diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index 4d82cfb38..89d58f2e0 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -47,13 +47,14 @@ type deployResults struct { system_id string } -func newAllocateParams(num_cpus, RAM, arch, storage, tags string) *allocateParams { +func newAllocateParams(num_cpus, RAM, arch, storage, tags, not_tags string) *allocateParams { values := url.Values{ "cpu_count": {num_cpus}, "mem": {RAM}, "arch": {arch}, "storage": {storage}, "tags": {tags}, + "not_tags": {not_tags}, } return &allocateParams{ values: values, diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 12da478c3..a6b9fd8e1 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -32,6 +32,7 @@ type maasCompute struct { secure_erase string quick_erase string tags string + not_tags string host hostCapabilities os osCapabilities } @@ -79,6 +80,11 @@ func (c *maasCompute) deploy(ctx context.Context, operationParams *operationPara return errors.Wrapf(err, "Failed to set capability attribute (ip_address) for node name:%s, instance name:%q", nodeName, instance) } + err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, instance, "endpoint", "private_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set capability attribute (private_address) for node name:%s, instance name:%q", nodeName, instance) + } + deployments.SetInstanceStateWithContextualLogs(ctx, deploymentID, nodeName, instance, tosca.NodeStateCreated) return nil } @@ -152,7 +158,7 @@ func (c *maasCompute) buildAllocateParams() (*allocateParams, error) { storageInt = storageInt / 1000000000 storage = "label:" + fmt.Sprint(storageInt) } - return newAllocateParams(c.host.num_cpus, mem, c.arch, storage, c.tags), nil + return newAllocateParams(c.host.num_cpus, mem, c.arch, storage, c.tags, c.not_tags), nil } // Set host capabilities using deployments values @@ -207,6 +213,15 @@ func (c *maasCompute) getAndsetProperties(ctx context.Context, operationParams * if p != "" { c.tags = p } + + p, err = deployments.GetStringNodeProperty(ctx, deploymentID, nodeName, "not_tags", false) + if err != nil { + return err + } + if p != "" { + c.not_tags = p + } + return nil } From ebfd6711bb9820dd1e29838a6c639310f1545f89 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Mon, 17 May 2021 13:52:14 +0200 Subject: [PATCH 17/23] compute test --- prov/maas/consul_test.go | 63 ++++++++++++++++ prov/maas/maas_compute_test.go | 63 ++++++++++++++++ prov/maas/testdata/testSimpleMaasCompute.yaml | 74 +++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 prov/maas/consul_test.go create mode 100644 prov/maas/maas_compute_test.go create mode 100644 prov/maas/testdata/testSimpleMaasCompute.yaml diff --git a/prov/maas/consul_test.go b/prov/maas/consul_test.go new file mode 100644 index 000000000..21071fb67 --- /dev/null +++ b/prov/maas/consul_test.go @@ -0,0 +1,63 @@ +// Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/locations" + "github.com/ystia/yorc/v4/testutil" +) + +var MAAS_LOCATION_PROPS config.DynamicMap + +// The aim of this function is to run all package tests with consul server dependency with only one consul server start +func TestRunConsulMaasPackageTests(t *testing.T) { + cfg := testutil.SetupTestConfig(t) + srv, _ := testutil.NewTestConsulInstance(t, &cfg) + defer func() { + srv.Stop() + os.RemoveAll(cfg.WorkingDirectory) + }() + + // Create a maas location + locationMgr, err := locations.GetManager(cfg) + require.NoError(t, err, "Error initializing locations") + + MAAS_LOCATION_PROPS = config.DynamicMap{ + "api_url": "10.0.0.0", + "api_key": "jGhsLn7JdVHNn6JhpT:SFtuTJSs2DpFbNGvQd:PJfNarCdtXUAQ8694f529a8fLZPaDBHE", + } + err = locationMgr.CreateLocation( + locations.LocationConfiguration{ + Name: "testMaasLocation", + Type: infrastructureType, + Properties: MAAS_LOCATION_PROPS, + }) + require.NoError(t, err, "Failed to create a location") + defer func() { + locationMgr.RemoveLocation(t.Name()) + }() + + t.Run("groupMaas", func(t *testing.T) { + t.Run("testSimpleMaasCompute", func(t *testing.T) { + testSimpleMaasCompute(t, cfg) + }) + }) +} diff --git a/prov/maas/maas_compute_test.go b/prov/maas/maas_compute_test.go new file mode 100644 index 000000000..c2906d52b --- /dev/null +++ b/prov/maas/maas_compute_test.go @@ -0,0 +1,63 @@ +// Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +import ( + "context" + "path" + "testing" + + "github.com/stretchr/testify/require" + "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/deployments" +) + +func loadTestYaml(t *testing.T) string { + deploymentID := path.Base(t.Name()) + yamlName := "testdata/" + deploymentID + ".yaml" + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, yamlName) + require.Nil(t, err, "Failed to parse "+yamlName+" definition") + return deploymentID +} + +func testSimpleMaasCompute(t *testing.T, cfg config.Configuration) { + t.Parallel() + deploymentID := loadTestYaml(t) + + operationParams := operationParameters{ + locationProps: MAAS_LOCATION_PROPS, + taskID: "0", + deploymentID: deploymentID, + nodeName: "Compute", + delegateOperation: "install", + instances: []string{"instance0"}, + } + + compute, err := getComputeFromDeployment(context.Background(), &operationParams) + require.Nil(t, err) + require.NotNil(t, compute) + + require.Equal(t, "bionic", compute.distro_series) + require.Equal(t, "amd64", compute.arch) + require.Equal(t, "true", compute.erase) + require.Equal(t, "true", compute.quick_erase) + require.Equal(t, "true", compute.secure_erase) + require.Equal(t, "tagTest", compute.tags) + require.Equal(t, "notTagTest", compute.not_tags) + + require.Equal(t, "3", compute.host.num_cpus) + require.Equal(t, "10 GB", compute.host.mem_size) + require.Equal(t, "200 GB", compute.host.disk_size) +} diff --git a/prov/maas/testdata/testSimpleMaasCompute.yaml b/prov/maas/testdata/testSimpleMaasCompute.yaml new file mode 100644 index 000000000..768a2f532 --- /dev/null +++ b/prov/maas/testdata/testSimpleMaasCompute.yaml @@ -0,0 +1,74 @@ +tosca_definitions_version: alien_dsl_3_0_0 + +metadata: + template_name: 1Compute + template_version: 0.1.0-SNAPSHOT + template_author: ${template_author} + +description: "" + +imports: + - + - + - + +topology_template: + node_templates: + Compute: + type: yorc.nodes.maas.Compute + properties: + distro_series: bionic + arch: amd64 + erase: true + quick_erase: true + secure_erase: true + tags: tagTest + not_tags: notTagTest + capabilities: + host: + properties: + num_cpus: 3 + mem_size: "10 GB" + disk_size: "200 GB" + + endpoint: + properties: + credentials: + user: ubuntu + token_type: null + secure: true + protocol: tcp + network_name: PRIVATE + initiator: source + scalable: + properties: + min_instances: 1 + max_instances: 1 + default_instances: 1 + workflows: + install: + steps: + Compute_install: + target: Compute + activities: + - delegate: install + uninstall: + steps: + Compute_uninstall: + target: Compute + activities: + - delegate: uninstall + start: + steps: + Compute_start: + target: Compute + activities: + - delegate: start + stop: + steps: + Compute_stop: + target: Compute + activities: + - delegate: stop + run: + cancel: From b77af0a7306d67aeec8478d1b1dad79481df7e6f Mon Sep 17 00:00:00 2001 From: Hilderic Date: Wed, 2 Jun 2021 10:18:57 +0200 Subject: [PATCH 18/23] Better test for compute --- go.mod | 3 +- go.sum | 35 +- prov/maas/{consul_test.go => all_test.go} | 42 +- prov/maas/all_test_data.go | 1583 +++++++++++++++++++++ prov/maas/maas_compute_test.go | 14 +- 5 files changed, 1632 insertions(+), 45 deletions(-) rename prov/maas/{consul_test.go => all_test.go} (56%) create mode 100644 prov/maas/all_test_data.go diff --git a/go.mod b/go.mod index cbe9494b0..292ab5183 100644 --- a/go.mod +++ b/go.mod @@ -55,10 +55,11 @@ require ( github.com/hashicorp/serf v0.8.3 // indirect github.com/hashicorp/vault v0.9.0 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c + github.com/jarcoal/httpmock v1.0.8 github.com/jefferai/jsonx v1.0.1 // indirect github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271 // indirect github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect - github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767 // indirect + github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767 github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e // indirect github.com/juju/schema v1.0.0 // indirect github.com/julienschmidt/httprouter v1.2.0 diff --git a/go.sum b/go.sum index 0592b272d..97e9fce7d 100644 --- a/go.sum +++ b/go.sum @@ -147,7 +147,6 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb h1:H3tisfjQwq9FTyWqlKsZpgoYrsvn2pmTWvAiDHa5pho= github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= -github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -164,13 +163,11 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/addlicense v0.0.0-20190107131845-2e5cf00261bf h1:sY3YFbxQBI/WqUznt+mPxct/yY7FI4NZzQj10oJwYq0= github.com/google/addlicense v0.0.0-20190107131845-2e5cf00261bf/go.mod h1:QtPG26W17m+OIQgE6gQ24gC1M6pUaMBAbFrTIDtwG/E= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -219,7 +216,6 @@ github.com/hashicorp/go-memdb v1.1.0 h1:ClvpUXpBA6UDs5+vc1h3wqe4UJU+rwum7CU219Se github.com/hashicorp/go-memdb v1.1.0/go.mod h1:LWQ8R70vPrS4OEY9k28D2z8/Zzyu34NVzeRibGAzHO0= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= @@ -231,7 +227,6 @@ github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -260,6 +255,8 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k= +github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jefferai/jsonx v1.0.1 h1:GvWkLWihoLqDG0BSP45TUQJH9qsINX50PVrFULgpc/I= github.com/jefferai/jsonx v1.0.1/go.mod h1:yFo3l2fcm7cZVHGq3HKLXE+Pd4RWuRjNBDHksM7XekQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -277,10 +274,13 @@ github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767/go.mod h1:ppx9XlnQM github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e h1:FdDd7bdI6cjq5vaoYlK1mfQYfF9sF2VZw8VEZMsl5t8= github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/retry v0.0.0-20151029024821-62c620325291 h1:Rp0pLxDOsLDDwh2S73oHLI2KTFFyrF6oM/DgP0FhhBk= github.com/juju/retry v0.0.0-20151029024821-62c620325291/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= github.com/juju/schema v1.0.0 h1:sZvJ7iQXHhMw/lJ4YfUmq+fe7R2ZSUzZzd/eSokaB3M= github.com/juju/schema v1.0.0/go.mod h1:Y+ThzXpUJ0E7NYYocAbuvJ7vTivXfrof/IfRPq/0abI= +github.com/juju/testing v0.0.0-20180402130637-44801989f0f7 h1:IOzyKRl+7X8/fDIqNUDQH73yo8bqDrMEh90y9Il158A= github.com/juju/testing v0.0.0-20180402130637-44801989f0f7/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/juju/utils v0.0.0-20180424094159-2000ea4ff043 h1:kjdsJcIYzmK2k4X2yVCi5Nip6sGoAuc7CLbp+qQnQUM= github.com/juju/utils v0.0.0-20180424094159-2000ea4ff043/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2 h1:loQDi5MyxxNm7Q42mBGuPD6X+F6zw8j5S9yexLgn/BE= github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= @@ -303,7 +303,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= @@ -313,7 +312,6 @@ github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0 github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -321,14 +319,12 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215 h1:hDa3vAq/Zo5gjfJ46XMsGFbH+hTizpR4fUzQCk2nxgk= github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215/go.mod h1:LH+NgPY9AJpDfqAFtzyer01N9MYNsAKUf3DC9DV1xIY= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -347,7 +343,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -377,12 +372,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= 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 v0.0.0-20170829012221-11459a886d9c h1:Hww8mOyEKTeON4bZn7FrlLismspbPc1teNRUVH7wLQ8= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c h1:eSfnfIuwhxZyULg1NNuZycJcYkjYVGYe7FczwQReM6U= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -399,7 +392,6 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= @@ -407,7 +399,6 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -435,7 +426,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -465,7 +455,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -474,13 +463,11 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -492,7 +479,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -515,11 +501,8 @@ golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -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-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= @@ -542,9 +525,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -575,7 +556,6 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -589,7 +569,6 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4 h1:1mMox4TgefDwqluYCv677yNXwlfTkija4owZve/jr78= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117170720-ade7f2547e48/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -602,7 +581,6 @@ google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO50 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo= 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.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= @@ -611,7 +589,6 @@ gopkg.in/AlecAivazis/survey.v1 v1.6.3 h1:5ULq/dOAZJZxz8kPV3sI8HHjluXi3k62fUtkTbB gopkg.in/AlecAivazis/survey.v1 v1.6.3/go.mod h1:2Ehl7OqkBl3Xb8VmC4oFW2bItAhnUfzIjrOzwRxCrOU= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -634,9 +611,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.0.0-20170712054546-1be3d31502d6/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/prov/maas/consul_test.go b/prov/maas/all_test.go similarity index 56% rename from prov/maas/consul_test.go rename to prov/maas/all_test.go index 21071fb67..6d3bddc31 100644 --- a/prov/maas/consul_test.go +++ b/prov/maas/all_test.go @@ -15,12 +15,16 @@ package maas import ( + "context" "os" + "path" "testing" "github.com/stretchr/testify/require" + "github.com/jarcoal/httpmock" "github.com/ystia/yorc/v4/config" + "github.com/ystia/yorc/v4/deployments" "github.com/ystia/yorc/v4/locations" "github.com/ystia/yorc/v4/testutil" ) @@ -28,7 +32,8 @@ import ( var MAAS_LOCATION_PROPS config.DynamicMap // The aim of this function is to run all package tests with consul server dependency with only one consul server start -func TestRunConsulMaasPackageTests(t *testing.T) { +func TestMainMaas(t *testing.T) { + // Create consul instance cfg := testutil.SetupTestConfig(t) srv, _ := testutil.NewTestConsulInstance(t, &cfg) defer func() { @@ -41,8 +46,9 @@ func TestRunConsulMaasPackageTests(t *testing.T) { require.NoError(t, err, "Error initializing locations") MAAS_LOCATION_PROPS = config.DynamicMap{ - "api_url": "10.0.0.0", - "api_key": "jGhsLn7JdVHNn6JhpT:SFtuTJSs2DpFbNGvQd:PJfNarCdtXUAQ8694f529a8fLZPaDBHE", + "api_url": "10.0.0.0", + "api_key": "jGhsLn7JdVHNn6JhpT:SFtuTJSs2DpFbNGvQd:PJfNarCdtXUAQ8694f529a8fLZPaDBHE", + "delayBetweenStatusCheck": "1ms", } err = locationMgr.CreateLocation( locations.LocationConfiguration{ @@ -57,7 +63,35 @@ func TestRunConsulMaasPackageTests(t *testing.T) { t.Run("groupMaas", func(t *testing.T) { t.Run("testSimpleMaasCompute", func(t *testing.T) { - testSimpleMaasCompute(t, cfg) + testInstallCompute(t, cfg) }) + t.Run("testSimpleMaasCompute", func(t *testing.T) { + testGetComputeFromDeployment(t, cfg) + }) + }) } + +func testInstallCompute(t *testing.T, cfg config.Configuration) { + executor := &defaultExecutor{} + ctx := context.Background() + + deploymentID := path.Base(t.Name()) + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") + require.Nil(t, err, "Failed to parse testInstallCompute definition") + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/?op=allocate", + httpmock.NewStringResponder(200, allocateResponse)) + + httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/tdgqkw/?op=deploy", + httpmock.NewStringResponder(200, deployResponse)) + + httpmock.RegisterResponder("GET", "/10.0.0.0/api/2.0/machines/tdgqkw/", + httpmock.NewStringResponder(200, machineDeployed)) + + err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "install") + require.Nil(t, err) +} diff --git a/prov/maas/all_test_data.go b/prov/maas/all_test_data.go new file mode 100644 index 000000000..352649936 --- /dev/null +++ b/prov/maas/all_test_data.go @@ -0,0 +1,1583 @@ +// Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package maas + +var allocateResponse = ` +{ + "hostname": "alert-buck", + "distro_series": "", + "address_ttl": null, + "network_test_status": -1, + "ip_addresses": [], + "other_test_status_name": "Unknown", + "memory_test_status_name": "Unknown", + "cpu_count": 8, + "hwe_kernel": null, + "storage_test_status": 2, + "node_type_name": "Machine", + "commissioning_status": 2, + "virtualmachine_id": null, + "status_action": "", + "bios_boot_method": "pxe", + "netboot": true, + "interface_set": [ + { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 16, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "product": "82576 Gigabit Network Connection", + "discovered": [], + "links": [ + { + "id": 31, + "mode": "auto", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "space": "undefined", + "id": 2, + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f0", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 100, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 18, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": null, + "product": "82576 Gigabit Network Connection", + "discovered": null, + "links": [], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f1", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 0, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/18/" + } + ], + "network_test_status_name": "Unknown", + "pod": null, + "disable_ipv4": false, + "blockdevice_set": [ + { + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "available_size": 0, + "name": "sda", + "uuid": null, + "serial": "Z1W1QQ4T", + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "storage_pool": null, + "id": 12, + "system_id": "tdgqkw", + "used_for": "Unused", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "available_size": 1000204886016, + "name": "sdb", + "uuid": null, + "serial": "Z1W1QJMW", + "partitions": [], + "path": "/dev/disk/by-dname/sdb", + "used_size": 0, + "partition_table_type": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "node_type": 0, + "commissioning_status_name": "Passed", + "interface_test_status": -1, + "storage": 2000409.7720320001, + "owner_data": {}, + "owner": "jim", + "system_id": "tdgqkw", + "raids": [], + "min_hwe_kernel": "", + "cpu_speed": 2930, + "locked": false, + "osystem": "", + "physicalblockdevice_set": [ + { + "firmware_version": "SN03", + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 0, + "size": 1000204886016, + "name": "sda", + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "uuid": null, + "serial": "Z1W1QQ4T", + "block_size": 512, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "firmware_version": "SN03", + "storage_pool": null, + "id": 12, + "system_id": "tdgqkw", + "used_for": "Unused", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 1000204886016, + "size": 1000204886016, + "name": "sdb", + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "uuid": null, + "serial": "Z1W1QJMW", + "block_size": 512, + "partitions": [], + "path": "/dev/disk/by-dname/sdb", + "used_size": 0, + "partition_table_type": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "interface_test_status_name": "Unknown", + "boot_interface": { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 16, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "product": "82576 Gigabit Network Connection", + "discovered": [], + "links": [ + { + "id": 31, + "mode": "auto", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "space": "undefined", + "id": 2, + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f0", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 100, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + "volume_groups": [], + "storage_test_status_name": "Passed", + "tag_names": [ + "yorc" + ], + "status_message": "Released", + "hardware_info": { + "system_vendor": "Bull SAS", + "system_product": "bullx", + "system_family": "Server", + "system_version": "R422-E2", + "system_sku": "R4222X80", + "system_serial": "1234567890", + "cpu_model": "Intel(R) Xeon(R) CPU X5570 ", + "mainboard_vendor": "Supermicro", + "mainboard_product": "X8DTT", + "mainboard_serial": "1234567890", + "mainboard_version": "1.00", + "mainboard_firmware_vendor": "American Megatrends Inc.", + "mainboard_firmware_date": "05/20/2010", + "mainboard_firmware_version": "R4222X80", + "chassis_vendor": "Supermicro", + "chassis_type": "Main Server Chassis", + "chassis_serial": "1234567890.", + "chassis_version": "1234567890" + }, + "special_filesystems": [], + "cpu_test_status_name": "Unknown", + "current_commissioning_result_id": 6, + "constraints_by_type": { + "storage": { + "label": [ + 11 + ] + } + }, + "memory": 12288, + "status": 10, + "virtualblockdevice_set": [], + "hardware_uuid": "1d030221-ce00-d553-d522-003048c6f252", + "pool": { + "name": "default", + "description": "Default pool", + "id": 0, + "resource_uri": "/MAAS/api/2.0/resourcepool/0/" + }, + "architecture": "amd64/generic", + "iscsiblockdevice_set": [], + "current_testing_result_id": 22, + "memory_test_status": -1, + "power_state": "off", + "bcaches": [], + "numanode_set": [ + { + "index": 0, + "memory": 7963, + "cores": [ + 0, + 1, + 2, + 3 + ], + "hugepages_set": [] + }, + { + "index": 1, + "memory": 4028, + "cores": [ + 4, + 5, + 6, + 7 + ], + "hugepages_set": [] + } + ], + "power_type": "ipmi", + "fqdn": "alert-buck.maas", + "cache_sets": [], + "testing_status": 2, + "current_installation_result_id": null, + "default_gateways": { + "ipv4": { + "gateway_ip": "172.20.0.1", + "link_id": null + }, + "ipv6": { + "gateway_ip": null, + "link_id": null + } + }, + "zone": { + "name": "default", + "description": "", + "id": 1, + "resource_uri": "/MAAS/api/2.0/zones/default/" + }, + "boot_disk": { + "firmware_version": "SN03", + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 0, + "size": 1000204886016, + "name": "sda", + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "uuid": null, + "serial": "Z1W1QQ4T", + "block_size": 512, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + "status_name": "Allocated", + "domain": { + "authoritative": true, + "ttl": null, + "is_default": true, + "resource_record_count": 3, + "name": "maas", + "id": 0, + "resource_uri": "/MAAS/api/2.0/domains/0/" + }, + "description": "", + "swap_size": null, + "other_test_status": -1, + "testing_status_name": "Passed", + "cpu_test_status": -1, + "resource_uri": "/MAAS/api/2.0/machines/tdgqkw/" +} +` + +var deployResponse = ` +{ + "physicalblockdevice_set": [ + { + "firmware_version": "SN03", + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "path": "/dev/disk/by-dname/sda", + "available_size": 0, + "type": "physical", + "tags": [ + "ssd" + ], + "partition_table_type": "GPT", + "model": "ST1000NM0033-9ZM", + "name": "sda", + "filesystem": null, + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "used_size": 1000200994816, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "system_id": "tdgqkw", + "type": "partition", + "id": 7, + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "serial": "Z1W1QQ4T", + "block_size": 512, + "uuid": null, + "size": 1000204886016, + "id": 11, + "numa_node": 0, + "storage_pool": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "firmware_version": "SN03", + "system_id": "tdgqkw", + "used_for": "Unused", + "path": "/dev/disk/by-dname/sdb", + "available_size": 1000204886016, + "type": "physical", + "tags": [ + "ssd" + ], + "partition_table_type": null, + "model": "ST1000NM0033-9ZM", + "name": "sdb", + "filesystem": null, + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "used_size": 0, + "partitions": [], + "serial": "Z1W1QJMW", + "block_size": 512, + "uuid": null, + "size": 1000204886016, + "id": 12, + "numa_node": 0, + "storage_pool": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "system_id": "tdgqkw", + "other_test_status": -1, + "power_type": "ipmi", + "network_test_status_name": "Unknown", + "memory_test_status_name": "Unknown", + "network_test_status": -1, + "boot_interface": { + "link_connected": true, + "system_id": "tdgqkw", + "params": "", + "links": [ + { + "id": 31, + "mode": "auto", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "primary_rack": "67mdw3", + "fabric": "fabric-1", + "id": 5002, + "space": "undefined", + "name": "untagged", + "fabric_id": 1, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "id": 2, + "space": "undefined", + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "type": "physical", + "mac_address": "cb:d5:c9:f7:78:04", + "sriov_max_vf": 7, + "tags": [ + "sriov" + ], + "children": [], + "firmware_version": "1.2.3", + "name": "enp1s0f0", + "effective_mtu": 1500, + "enabled": true, + "link_speed": 100, + "discovered": [], + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "primary_rack": "67mdw3", + "fabric": "fabric-1", + "id": 5002, + "space": "undefined", + "name": "untagged", + "fabric_id": 1, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "vendor": "Intel Corporation", + "interface_speed": 1000, + "id": 16, + "parents": [], + "numa_node": 0, + "product": "82576 Gigabit Network Connection", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + "address_ttl": null, + "tag_names": [ + "yorc" + ], + "locked": false, + "memory": 12288, + "current_installation_result_id": 143, + "domain": { + "authoritative": true, + "ttl": null, + "is_default": true, + "id": 0, + "resource_record_count": 3, + "name": "maas", + "resource_uri": "/MAAS/api/2.0/domains/0/" + }, + "virtualmachine_id": null, + "description": "", + "current_testing_result_id": 22, + "storage_test_status_name": "Passed", + "min_hwe_kernel": "", + "bcaches": [], + "memory_test_status": -1, + "architecture": "amd64/generic", + "status": 9, + "pool": { + "name": "default", + "description": "Default pool", + "id": 0, + "resource_uri": "/MAAS/api/2.0/resourcepool/0/" + }, + "iscsiblockdevice_set": [], + "raids": [], + "status_message": "Deploying", + "swap_size": null, + "testing_status": 2, + "storage": 2000409.7720320001, + "osystem": "ubuntu", + "boot_disk": { + "firmware_version": "SN03", + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "path": "/dev/disk/by-dname/sda", + "available_size": 0, + "type": "physical", + "tags": [ + "ssd" + ], + "partition_table_type": "GPT", + "model": "ST1000NM0033-9ZM", + "name": "sda", + "filesystem": null, + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "used_size": 1000200994816, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "system_id": "tdgqkw", + "type": "partition", + "id": 7, + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "serial": "Z1W1QQ4T", + "block_size": 512, + "uuid": null, + "size": 1000204886016, + "id": 11, + "numa_node": 0, + "storage_pool": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + "power_state": "off", + "special_filesystems": [], + "volume_groups": [], + "commissioning_status_name": "Passed", + "hwe_kernel": "ga-20.04", + "netboot": true, + "blockdevice_set": [ + { + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "path": "/dev/disk/by-dname/sda", + "available_size": 0, + "type": "physical", + "partition_table_type": "GPT", + "model": "ST1000NM0033-9ZM", + "name": "sda", + "filesystem": null, + "used_size": 1000200994816, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "system_id": "tdgqkw", + "type": "partition", + "id": 7, + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "serial": "Z1W1QQ4T", + "uuid": null, + "id": 11, + "numa_node": 0, + "storage_pool": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "system_id": "tdgqkw", + "used_for": "Unused", + "path": "/dev/disk/by-dname/sdb", + "available_size": 1000204886016, + "type": "physical", + "partition_table_type": null, + "model": "ST1000NM0033-9ZM", + "name": "sdb", + "filesystem": null, + "used_size": 0, + "partitions": [], + "serial": "Z1W1QJMW", + "uuid": null, + "id": 12, + "numa_node": 0, + "storage_pool": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "cpu_count": 8, + "pod": null, + "ip_addresses": [], + "node_type": 0, + "distro_series": "focal", + "current_commissioning_result_id": 6, + "fqdn": "alert-buck.maas", + "owner_data": {}, + "virtualblockdevice_set": [], + "default_gateways": { + "ipv4": { + "gateway_ip": "172.20.0.1", + "link_id": null + }, + "ipv6": { + "gateway_ip": null, + "link_id": null + } + }, + "cpu_test_status_name": "Unknown", + "hostname": "alert-buck", + "interface_test_status": -1, + "cpu_speed": 2930, + "status_action": "", + "hardware_info": { + "system_vendor": "Bull SAS", + "system_product": "bullx", + "system_family": "Server", + "system_version": "R422-E2", + "system_sku": "R4222X80", + "system_serial": "1234567890", + "cpu_model": "Intel(R) Xeon(R) CPU X5570 ", + "mainboard_vendor": "Supermicro", + "mainboard_product": "X8DTT", + "mainboard_serial": "1234567890", + "mainboard_version": "1.00", + "mainboard_firmware_vendor": "American Megatrends Inc.", + "mainboard_firmware_date": "05/20/2010", + "mainboard_firmware_version": "R4222X80", + "chassis_vendor": "Supermicro", + "chassis_type": "Main Server Chassis", + "chassis_serial": "1234567890.", + "chassis_version": "1234567890" + }, + "owner": "jim", + "interface_set": [ + { + "link_connected": true, + "system_id": "tdgqkw", + "params": "", + "links": [ + { + "id": 31, + "mode": "auto", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "primary_rack": "67mdw3", + "fabric": "fabric-1", + "id": 5002, + "space": "undefined", + "name": "untagged", + "fabric_id": 1, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "id": 2, + "space": "undefined", + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "type": "physical", + "mac_address": "cb:d5:c9:f7:78:04", + "sriov_max_vf": 7, + "tags": [ + "sriov" + ], + "children": [], + "firmware_version": "1.2.3", + "name": "enp1s0f0", + "effective_mtu": 1500, + "enabled": true, + "link_speed": 100, + "discovered": [], + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "primary_rack": "67mdw3", + "fabric": "fabric-1", + "id": 5002, + "space": "undefined", + "name": "untagged", + "fabric_id": 1, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "vendor": "Intel Corporation", + "interface_speed": 1000, + "id": 16, + "parents": [], + "numa_node": 0, + "product": "82576 Gigabit Network Connection", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + { + "link_connected": true, + "system_id": "tdgqkw", + "params": "", + "links": [], + "type": "physical", + "mac_address": "cb:d5:c9:f7:78:04", + "sriov_max_vf": 7, + "tags": [ + "sriov" + ], + "children": [], + "firmware_version": "1.2.3", + "name": "enp1s0f1", + "effective_mtu": 1500, + "enabled": true, + "link_speed": 0, + "discovered": null, + "vlan": null, + "vendor": "Intel Corporation", + "interface_speed": 1000, + "id": 18, + "parents": [], + "numa_node": 0, + "product": "82576 Gigabit Network Connection", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/18/" + } + ], + "commissioning_status": 2, + "zone": { + "name": "default", + "description": "", + "id": 1, + "resource_uri": "/MAAS/api/2.0/zones/default/" + }, + "node_type_name": "Machine", + "interface_test_status_name": "Unknown", + "bios_boot_method": "pxe", + "status_name": "Deploying", + "cache_sets": [], + "disable_ipv4": false, + "storage_test_status": 2, + "hardware_uuid": "1d030221-ce00-d553-d522-003048c6f252", + "testing_status_name": "Passed", + "cpu_test_status": -1, + "numanode_set": [ + { + "index": 0, + "memory": 7963, + "cores": [ + 0, + 1, + 2, + 3 + ], + "hugepages_set": [] + }, + { + "index": 1, + "memory": 4028, + "cores": [ + 4, + 5, + 6, + 7 + ], + "hugepages_set": [] + } + ], + "other_test_status_name": "Unknown", + "resource_uri": "/MAAS/api/2.0/machines/tdgqkw/" +} +` + +var machineDeployed = ` +{ + "hostname": "alert-buck", + "distro_series": "focal", + "address_ttl": null, + "network_test_status": -1, + "ip_addresses": [ + "172.20.0.114" + ], + "other_test_status_name": "Unknown", + "memory_test_status_name": "Unknown", + "cpu_count": 8, + "hwe_kernel": "ga-20.04", + "storage_test_status": 2, + "node_type_name": "Machine", + "commissioning_status": 2, + "virtualmachine_id": null, + "status_action": "", + "bios_boot_method": "pxe", + "netboot": false, + "interface_set": [ + { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 16, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "product": "82576 Gigabit Network Connection", + "discovered": [], + "links": [ + { + "id": 31, + "mode": "auto", + "ip_address": "172.20.0.114", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "space": "undefined", + "id": 2, + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f0", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 100, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 18, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": null, + "product": "82576 Gigabit Network Connection", + "discovered": null, + "links": [], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f1", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 0, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/18/" + } + ], + "network_test_status_name": "Unknown", + "pod": null, + "disable_ipv4": false, + "blockdevice_set": [ + { + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "available_size": 0, + "name": "sda", + "uuid": null, + "serial": "Z1W1QQ4T", + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "size": 1000204886016, + "block_size": 512, + "tags": [ + "ssd" + ], + "storage_pool": null, + "id": 12, + "system_id": "tdgqkw", + "used_for": "Unused", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "available_size": 1000204886016, + "name": "sdb", + "uuid": null, + "serial": "Z1W1QJMW", + "partitions": [], + "path": "/dev/disk/by-dname/sdb", + "used_size": 0, + "partition_table_type": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "node_type": 0, + "commissioning_status_name": "Passed", + "interface_test_status": -1, + "storage": 2000409.7720320001, + "owner_data": {}, + "owner": "jim", + "system_id": "tdgqkw", + "raids": [], + "min_hwe_kernel": "", + "cpu_speed": 2930, + "locked": false, + "osystem": "ubuntu", + "physicalblockdevice_set": [ + { + "firmware_version": "SN03", + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 0, + "size": 1000204886016, + "name": "sda", + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "uuid": null, + "serial": "Z1W1QQ4T", + "block_size": 512, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + { + "firmware_version": "SN03", + "storage_pool": null, + "id": 12, + "system_id": "tdgqkw", + "used_for": "Unused", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 1000204886016, + "size": 1000204886016, + "name": "sdb", + "id_path": "/dev/disk/by-id/wwn-0x5000c5006689ae3f", + "uuid": null, + "serial": "Z1W1QJMW", + "block_size": 512, + "partitions": [], + "path": "/dev/disk/by-dname/sdb", + "used_size": 0, + "partition_table_type": null, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/12/" + } + ], + "interface_test_status_name": "Unknown", + "boot_interface": { + "params": "", + "interface_speed": 1000, + "vendor": "Intel Corporation", + "enabled": true, + "id": 16, + "sriov_max_vf": 7, + "effective_mtu": 1500, + "system_id": "tdgqkw", + "type": "physical", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "product": "82576 Gigabit Network Connection", + "discovered": [], + "links": [ + { + "id": 31, + "mode": "auto", + "ip_address": "172.20.0.114", + "subnet": { + "name": "172.20.0.0/24", + "description": "", + "vlan": { + "vid": 0, + "mtu": 1500, + "dhcp_on": true, + "external_dhcp": null, + "relay_vlan": null, + "secondary_rack": null, + "fabric": "fabric-1", + "fabric_id": 1, + "primary_rack": "67mdw3", + "name": "untagged", + "space": "undefined", + "id": 5002, + "resource_uri": "/MAAS/api/2.0/vlans/5002/" + }, + "cidr": "172.20.0.0/24", + "rdns_mode": 2, + "gateway_ip": "172.20.0.1", + "dns_servers": [], + "allow_dns": true, + "allow_proxy": true, + "active_discovery": false, + "managed": true, + "space": "undefined", + "id": 2, + "resource_uri": "/MAAS/api/2.0/subnets/2/" + } + } + ], + "numa_node": 0, + "tags": [ + "sriov" + ], + "name": "enp1s0f0", + "mac_address": "cb:d5:c9:f7:78:04", + "firmware_version": "1.2.3", + "parents": [], + "children": [], + "link_connected": true, + "link_speed": 100, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/interfaces/16/" + }, + "volume_groups": [], + "storage_test_status_name": "Passed", + "tag_names": [ + "yorc" + ], + "status_message": "Deployed", + "hardware_info": { + "system_vendor": "Bull SAS", + "system_product": "bullx", + "system_family": "Server", + "system_version": "R422-E2", + "system_sku": "R4222X80", + "system_serial": "1234567890", + "cpu_model": "Intel(R) Xeon(R) CPU X5570 ", + "mainboard_vendor": "Supermicro", + "mainboard_product": "X8DTT", + "mainboard_serial": "1234567890", + "mainboard_version": "1.00", + "mainboard_firmware_vendor": "American Megatrends Inc.", + "mainboard_firmware_date": "05/20/2010", + "mainboard_firmware_version": "R4222X80", + "chassis_vendor": "Supermicro", + "chassis_type": "Main Server Chassis", + "chassis_serial": "1234567890.", + "chassis_version": "1234567890" + }, + "special_filesystems": [], + "cpu_test_status_name": "Unknown", + "current_commissioning_result_id": 6, + "memory": 12288, + "status": 6, + "virtualblockdevice_set": [], + "hardware_uuid": "1d030221-ce00-d553-d522-003048c6f252", + "pool": { + "name": "default", + "description": "Default pool", + "id": 0, + "resource_uri": "/MAAS/api/2.0/resourcepool/0/" + }, + "architecture": "amd64/generic", + "iscsiblockdevice_set": [], + "current_testing_result_id": 22, + "memory_test_status": -1, + "power_state": "on", + "bcaches": [], + "numanode_set": [ + { + "index": 0, + "memory": 7963, + "cores": [ + 0, + 1, + 2, + 3 + ], + "hugepages_set": [] + }, + { + "index": 1, + "memory": 4028, + "cores": [ + 4, + 5, + 6, + 7 + ], + "hugepages_set": [] + } + ], + "power_type": "ipmi", + "fqdn": "alert-buck.maas", + "cache_sets": [], + "testing_status": 2, + "current_installation_result_id": 143, + "default_gateways": { + "ipv4": { + "gateway_ip": "172.20.0.1", + "link_id": null + }, + "ipv6": { + "gateway_ip": null, + "link_id": null + } + }, + "zone": { + "name": "default", + "description": "", + "id": 1, + "resource_uri": "/MAAS/api/2.0/zones/default/" + }, + "boot_disk": { + "firmware_version": "SN03", + "storage_pool": null, + "id": 11, + "system_id": "tdgqkw", + "used_for": "GPT partitioned with 1 partition", + "model": "ST1000NM0033-9ZM", + "type": "physical", + "filesystem": null, + "numa_node": 0, + "tags": [ + "ssd" + ], + "available_size": 0, + "size": 1000204886016, + "name": "sda", + "id_path": "/dev/disk/by-id/wwn-0x5000c50066898892", + "uuid": null, + "serial": "Z1W1QQ4T", + "block_size": 512, + "partitions": [ + { + "uuid": "32fc769e-2f84-4db6-8d06-3c0b6ef4282a", + "size": 1000194703360, + "bootable": false, + "tags": [], + "system_id": "tdgqkw", + "device_id": 11, + "used_for": "ext4 formatted filesystem mounted at /", + "type": "partition", + "path": "/dev/disk/by-dname/sda-part2", + "filesystem": { + "fstype": "ext4", + "label": "root", + "uuid": "bc9577af-b6a9-4eb7-95bf-887300365bc9", + "mount_point": "/", + "mount_options": null + }, + "id": 7, + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/partition/7" + } + ], + "path": "/dev/disk/by-dname/sda", + "used_size": 1000200994816, + "partition_table_type": "GPT", + "resource_uri": "/MAAS/api/2.0/nodes/tdgqkw/blockdevices/11/" + }, + "status_name": "Deployed", + "domain": { + "authoritative": true, + "ttl": null, + "is_default": true, + "resource_record_count": 3, + "name": "maas", + "id": 0, + "resource_uri": "/MAAS/api/2.0/domains/0/" + }, + "description": "", + "swap_size": null, + "other_test_status": -1, + "testing_status_name": "Passed", + "cpu_test_status": -1, + "resource_uri": "/MAAS/api/2.0/machines/tdgqkw/" +} +` diff --git a/prov/maas/maas_compute_test.go b/prov/maas/maas_compute_test.go index c2906d52b..484961ed8 100644 --- a/prov/maas/maas_compute_test.go +++ b/prov/maas/maas_compute_test.go @@ -24,17 +24,11 @@ import ( "github.com/ystia/yorc/v4/deployments" ) -func loadTestYaml(t *testing.T) string { - deploymentID := path.Base(t.Name()) - yamlName := "testdata/" + deploymentID + ".yaml" - err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, yamlName) - require.Nil(t, err, "Failed to parse "+yamlName+" definition") - return deploymentID -} - -func testSimpleMaasCompute(t *testing.T, cfg config.Configuration) { +func testGetComputeFromDeployment(t *testing.T, cfg config.Configuration) { t.Parallel() - deploymentID := loadTestYaml(t) + deploymentID := path.Base(t.Name()) + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") + require.Nil(t, err, "Failed to parse testInstallCompute definition") operationParams := operationParameters{ locationProps: MAAS_LOCATION_PROPS, From 6414a8bff7b3196541b05f5cd235910fa28f0e51 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Wed, 2 Jun 2021 14:28:48 +0200 Subject: [PATCH 19/23] Adding uninstall test --- prov/maas/all_test.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/prov/maas/all_test.go b/prov/maas/all_test.go index 6d3bddc31..754faa6da 100644 --- a/prov/maas/all_test.go +++ b/prov/maas/all_test.go @@ -62,9 +62,12 @@ func TestMainMaas(t *testing.T) { }() t.Run("groupMaas", func(t *testing.T) { - t.Run("testSimpleMaasCompute", func(t *testing.T) { + t.Run("testInstallCompute", func(t *testing.T) { testInstallCompute(t, cfg) }) + t.Run("testUninstallCompute", func(t *testing.T) { + testUninstallCompute(t, cfg) + }) t.Run("testSimpleMaasCompute", func(t *testing.T) { testGetComputeFromDeployment(t, cfg) }) @@ -95,3 +98,21 @@ func testInstallCompute(t *testing.T, cfg config.Configuration) { err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "install") require.Nil(t, err) } + +func testUninstallCompute(t *testing.T, cfg config.Configuration) { + executor := &defaultExecutor{} + ctx := context.Background() + + deploymentID := path.Base(t.Name()) + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") + require.Nil(t, err, "Failed to parse testUninstallCompute definition") + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/tdgqkw/?op=release", + httpmock.NewStringResponder(200, deployResponse)) + + err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "uninstall") + require.Nil(t, err) +} From 33ac34efc1a266010ffd85b8babaef1c30b117a3 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Tue, 8 Jun 2021 14:53:27 +0200 Subject: [PATCH 20/23] undeploy error fix --- prov/maas/all_test.go | 25 +++++++++++++++++++++++++ prov/maas/maas_compute.go | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/prov/maas/all_test.go b/prov/maas/all_test.go index 754faa6da..5b9b3e534 100644 --- a/prov/maas/all_test.go +++ b/prov/maas/all_test.go @@ -68,6 +68,9 @@ func TestMainMaas(t *testing.T) { t.Run("testUninstallCompute", func(t *testing.T) { testUninstallCompute(t, cfg) }) + t.Run("testUninstallNoSystemIdErrorCompute", func(t *testing.T) { + testUninstallNoSystemIdErrorCompute(t, cfg) + }) t.Run("testSimpleMaasCompute", func(t *testing.T) { testGetComputeFromDeployment(t, cfg) }) @@ -113,6 +116,28 @@ func testUninstallCompute(t *testing.T, cfg config.Configuration) { httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/tdgqkw/?op=release", httpmock.NewStringResponder(200, deployResponse)) + err = deployments.SetInstanceAttribute(ctx, deploymentID, "Compute", "0", "system_id", "tdgqkw") + require.Nil(t, err) + err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "uninstall") require.Nil(t, err) } + +func testUninstallNoSystemIdErrorCompute(t *testing.T, cfg config.Configuration) { + executor := &defaultExecutor{} + ctx := context.Background() + + deploymentID := path.Base(t.Name()) + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") + require.Nil(t, err, "Failed to parse testUninstallCompute definition") + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/tdgqkw/?op=release", + httpmock.NewStringResponder(200, deployResponse)) + + err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "uninstall") + + require.Contains(t, err.Error(), "can't find instance attribute system id") +} diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index a6b9fd8e1..e9d4164e0 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -122,7 +122,7 @@ func (c *maasCompute) undeploy(ctx context.Context, operationParams *operationPa system_id, err := deployments.GetInstanceAttributeValue(ctx, deploymentID, nodeName, instance, "system_id") if err != nil || system_id == nil { - return errors.Wrapf(err, "can't find instance attribute system id for nodename:%s deployementId: %s \n Maybe last deployement was not successful", nodeName, deploymentID) + return errors.Errorf("can't find instance attribute system id for nodename:%s deployementId: %s \n Maybe last deployement was not successful", nodeName, deploymentID) } releaseParams := newReleaseParams(c.erase, c.secure_erase, c.quick_erase) From 28f1b9daff4c21428216e57775cee250dde51600 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Tue, 8 Jun 2021 15:19:46 +0200 Subject: [PATCH 21/23] Clean up + more test --- prov/maas/all_test.go | 23 ++++++++++++++++------- prov/maas/maas_compute.go | 18 +----------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/prov/maas/all_test.go b/prov/maas/all_test.go index 5b9b3e534..ab10935aa 100644 --- a/prov/maas/all_test.go +++ b/prov/maas/all_test.go @@ -65,6 +65,9 @@ func TestMainMaas(t *testing.T) { t.Run("testInstallCompute", func(t *testing.T) { testInstallCompute(t, cfg) }) + t.Run("testInstallCompute", func(t *testing.T) { + testInstallComputeNoApiResponse(t, cfg) + }) t.Run("testUninstallCompute", func(t *testing.T) { testUninstallCompute(t, cfg) }) @@ -102,6 +105,18 @@ func testInstallCompute(t *testing.T, cfg config.Configuration) { require.Nil(t, err) } +func testInstallComputeNoApiResponse(t *testing.T, cfg config.Configuration) { + executor := &defaultExecutor{} + ctx := context.Background() + + deploymentID := path.Base(t.Name()) + err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") + require.Nil(t, err, "Failed to parse testInstallComputeNoApiResponse definition") + + err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "install") + require.NotNil(t, err) +} + func testUninstallCompute(t *testing.T, cfg config.Configuration) { executor := &defaultExecutor{} ctx := context.Background() @@ -129,13 +144,7 @@ func testUninstallNoSystemIdErrorCompute(t *testing.T, cfg config.Configuration) deploymentID := path.Base(t.Name()) err := deployments.StoreDeploymentDefinition(context.Background(), deploymentID, "testdata/testSimpleMaasCompute.yaml") - require.Nil(t, err, "Failed to parse testUninstallCompute definition") - - httpmock.Activate() - defer httpmock.DeactivateAndReset() - - httpmock.RegisterResponder("POST", "/10.0.0.0/api/2.0/machines/tdgqkw/?op=release", - httpmock.NewStringResponder(200, deployResponse)) + require.Nil(t, err, "Failed to parse testUninstallNoSystemIdErrorCompute definition") err = executor.ExecDelegate(ctx, cfg, "taskID", deploymentID, "Compute", "uninstall") diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index e9d4164e0..0cbcec838 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -263,28 +263,12 @@ func (c *maasCompute) getAndsetPropertiesFromOSCapabilities(ctx context.Context, nodeName := operationParams.nodeName os := &c.os - p, err := deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "architecture") - if err != nil { - return err - } - if p != nil && p.RawString() != "" { - os.architecture = p.RawString() - } - - p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "distribution") + p, err := deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "distribution") if err != nil { return err } if p != nil && p.RawString() != "" { os.distribution = p.RawString() } - - p, err = deployments.GetCapabilityPropertyValue(ctx, deploymentID, nodeName, "os", "architecture") - if err != nil { - return err - } - if p != nil && p.RawString() != "" { - os.architecture = p.RawString() - } return nil } From 2406c0a31a2dbec46d6d8c8f9322452ed946f0c1 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Tue, 13 Jul 2021 16:26:10 +0200 Subject: [PATCH 22/23] fix ips mass compute --- prov/maas/maas_compute.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/prov/maas/maas_compute.go b/prov/maas/maas_compute.go index 0cbcec838..a97712b2c 100644 --- a/prov/maas/maas_compute.go +++ b/prov/maas/maas_compute.go @@ -72,7 +72,27 @@ func (c *maasCompute) deploy(ctx context.Context, operationParams *operationPara err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, instance, "system_id", deployRes.system_id) if err != nil { - return errors.Wrapf(err, "Failed to set attribute (system_id) for node name:%q, instance name:%q", nodeName, instance) + return errors.Wrapf(err, "Failed to set instance attribute (system_id) for node name:%q, instance name:%q", nodeName, instance) + } + + err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, instance, "ip_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set instance attribute (ip_address) for node name:%q, instance name:%q", deployRes.ips[0], instance) + } + + err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, instance, "private_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set attribute instance attribute (private_address) for node name:%q, instance name:%q", deployRes.ips[0], instance) + } + + err = deployments.SetInstanceAttribute(ctx, deploymentID, nodeName, instance, "public_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set attribute instance attribute (public_address) for node name:%q, instance name:%q", deployRes.ips[0], instance) + } + + err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, instance, "endpoint", "private_address", deployRes.ips[0]) + if err != nil { + return errors.Wrapf(err, "Failed to set instance attribute (private_address) for node name:%s, instance name:%q", nodeName, instance) } err = deployments.SetInstanceCapabilityAttribute(ctx, deploymentID, nodeName, instance, "endpoint", "ip_address", deployRes.ips[0]) From 624bc7a125a91173001fbbc13e24814c8bbad4c7 Mon Sep 17 00:00:00 2001 From: Hilderic Date: Tue, 13 Jul 2021 17:03:06 +0200 Subject: [PATCH 23/23] Bootstrap MAAS (WIP) --- commands/bootstrap/inputs.go | 12 ++++++++--- .../topology/ondemand_resources_maas.tmpl | 6 ++++++ .../topology/topology_compute_maas.tmpl | 20 ++++++++++++++++++ .../topology_infrastructure_maas.tmpl | 18 ++++++++++++++++ .../resources/topology/tosca_types.zip | Bin 1079814 -> 1081429 bytes prov/maas/apiCall.go | 4 ++-- prov/maas/executor.go | 2 +- 7 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 commands/bootstrap/resources/topology/ondemand_resources_maas.tmpl create mode 100644 commands/bootstrap/resources/topology/topology_compute_maas.tmpl create mode 100644 commands/bootstrap/resources/topology/topology_infrastructure_maas.tmpl diff --git a/commands/bootstrap/inputs.go b/commands/bootstrap/inputs.go index afb51238b..27638b57e 100644 --- a/commands/bootstrap/inputs.go +++ b/commands/bootstrap/inputs.go @@ -403,6 +403,8 @@ func initializeInputs(inputFilePath, resourcesPath string, configuration config. infrastructureType = "aws" case "HostsPool": infrastructureType = "hostspool" + case "MAAS": + infrastructureType = "maas" default: infrastructureType = "" } @@ -428,7 +430,7 @@ func initializeInputs(inputFilePath, resourcesPath string, configuration config. fmt.Println("") prompt := &survey.Select{ Message: "Select an infrastructure type:", - Options: []string{"Google", "AWS", "OpenStack", "HostsPool"}, + Options: []string{"Google", "AWS", "OpenStack", "HostsPool", "MAAS"}, } survey.AskOne(prompt, &infraSelected, nil) infrastructureType = strings.ToLower(infraSelected) @@ -477,8 +479,10 @@ func initializeInputs(inputFilePath, resourcesPath string, configuration config. case "hostspool": // No infrastructure defined in case of hosts pool // Hosts Pool don't have network-reletad on-demand resources + case "maas": + infraNodeType = "org.ystia.yorc.pub.location.MAASConfig" default: - return fmt.Errorf("Infrastruture type %s is not supported by bootstrap", + return fmt.Errorf("infrastruture type %s is not supported by bootstrap", infrastructureType) } @@ -491,7 +495,7 @@ func initializeInputs(inputFilePath, resourcesPath string, configuration config. return err } if len(matchingPath) == 0 { - return fmt.Errorf("Found no node types definition file matching pattern %s", nodeTypesFilePathPattern) + return fmt.Errorf("found no node types definition file matching pattern %s", nodeTypesFilePathPattern) } data, err := ioutil.ReadFile(matchingPath[0]) @@ -768,6 +772,8 @@ func initializeInputs(inputFilePath, resourcesPath string, configuration config. inputValues.Location.Type = "AWS" case "hostspool": inputValues.Location.Type = "HostsPool" + case "maas": + inputValues.Location.Type = "maas" default: return fmt.Errorf("Bootstrapping on %s not supported yet", infrastructureType) } diff --git a/commands/bootstrap/resources/topology/ondemand_resources_maas.tmpl b/commands/bootstrap/resources/topology/ondemand_resources_maas.tmpl new file mode 100644 index 000000000..8c353b06a --- /dev/null +++ b/commands/bootstrap/resources/topology/ondemand_resources_maas.tmpl @@ -0,0 +1,6 @@ +resources: + - resourceType: "yorc.nodes.maas.Compute" + resourceName: "Compute" + archiveName: yorc-maas-types + id: "yorc.bootstrap.maas.Compute" + properties: {{formatAsYAML .Compute 8}} diff --git a/commands/bootstrap/resources/topology/topology_compute_maas.tmpl b/commands/bootstrap/resources/topology/topology_compute_maas.tmpl new file mode 100644 index 000000000..ddaaaf14f --- /dev/null +++ b/commands/bootstrap/resources/topology/topology_compute_maas.tmpl @@ -0,0 +1,20 @@ +{{ define "Compute" }} + type: yorc.nodes.maas.Compute + properties: {{formatAsYAML .Compute 8}} + capabilities: + endpoint: + properties: + credentials: {{formatAsYAML .Credentials 14}} + secure: true + protocol: tcp + network_name: PRIVATE + initiator: source + os: + properties: + type: linux + scalable: + properties: + min_instances: 1 + max_instances: 1 + default_instances: 1 +{{ end }} diff --git a/commands/bootstrap/resources/topology/topology_infrastructure_maas.tmpl b/commands/bootstrap/resources/topology/topology_infrastructure_maas.tmpl new file mode 100644 index 000000000..739f76a04 --- /dev/null +++ b/commands/bootstrap/resources/topology/topology_infrastructure_maas.tmpl @@ -0,0 +1,18 @@ +{{ define "Infrastructure" }} + type: org.ystia.yorc.location.MAASConfig + properties: {{formatAsYAML .Location.Properties 8}} + location_name: "{{.Location.Name}}" + requirements: + - infraHostedOnYorcServer: + type_requirement: yorc + node: YorcServer + capability: org.ystia.yorc.pub.capabilities.YorcConfigContainer + relationship: org.ystia.yorc.linux.ansible.relationships.YorcConfigMAASHostedOnYorc + {{if not .Insecure}} + - infraSecretsHostedOnVault: + type_requirement: host + node: VaultServer + capability: org.alien4cloud.vault.pub.capabilities.VaultServer + relationship: org.ystia.yorc.linux.ansible.relationships.HostsPoolSecretsOnVault + {{end}} +{{ end }} diff --git a/commands/bootstrap/resources/topology/tosca_types.zip b/commands/bootstrap/resources/topology/tosca_types.zip index 71620a04c170a8b59e02193f2a40ef6c3f78a6a3..a59eeaa030d4afdc71bd76afcae36aece3c5ece0 100644 GIT binary patch delta 21531 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 Tn%rP&FxBK7g>vOA2B!QUxFL|i diff --git a/prov/maas/apiCall.go b/prov/maas/apiCall.go index 89d58f2e0..381af20e7 100644 --- a/prov/maas/apiCall.go +++ b/prov/maas/apiCall.go @@ -108,11 +108,11 @@ func getMaasClient(locationProps config.DynamicMap) (*gomaasapi.MAASObject, erro func checkLocationConfig(locationProps config.DynamicMap) error { if strings.Trim(locationProps.GetString("api_url"), "") == "" { - return errors.New("maas location ulr is not set") + return errors.New("maas api_url is not set") } if strings.Trim(locationProps.GetString("api_key"), "") == "" { - return errors.New("maas location api key is not set") + return errors.New("maas api key is not set") } return nil } diff --git a/prov/maas/executor.go b/prov/maas/executor.go index 87d75c0c4..7e74c9107 100644 --- a/prov/maas/executor.go +++ b/prov/maas/executor.go @@ -167,7 +167,7 @@ func (e *defaultExecutor) uninstallNode(ctx context.Context, operationParams *op } if err := g.Wait(); err != nil { - err = errors.Wrapf(err, "Failed install node deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) + err = errors.Wrapf(err, "Failed uninstall node deploymentID:%q, node name:%s", operationParams.deploymentID, operationParams.nodeName) log.Debugf("%+v", err) events.WithContextOptionalFields(ctx).NewLogEntry(events.LogLevelERROR, operationParams.deploymentID).RegisterAsString(err.Error()) return err