1// Copyright 2018 VMware, Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package management
16
17import (
18	"context"
19
20	"github.com/vmware/govmomi/vim25/types"
21
22	"github.com/vmware/vic/lib/config"
23	"github.com/vmware/vic/lib/install/validate"
24	"github.com/vmware/vic/pkg/trace"
25	"github.com/vmware/vic/pkg/vsphere/tasks"
26)
27
28func (d *Dispatcher) createVMGroup(conf *config.VirtualContainerHostConfigSpec) error {
29	defer trace.End(trace.Begin("", d.op))
30
31	if !conf.UseVMGroup {
32		return nil
33	}
34
35	d.op.Debugf("Creating DRS VM Group %q on %q", conf.VMGroupName, d.appliance.Cluster)
36
37	_, err := tasks.WaitForResultAndRetryIf(d.op, func(op context.Context) (tasks.Task, error) {
38		containers, err := d.containerRefs(d.vchPool)
39		if err != nil {
40			return nil, err
41		}
42
43		vms := append(containers, d.appliance.Reference())
44
45		d.op.Debugf("Populating DRS VM Group %q with %q", conf.VMGroupName, vms)
46
47		spec := &types.ClusterConfigSpecEx{
48			GroupSpec: []types.ClusterGroupSpec{
49				{
50					ArrayUpdateSpec: types.ArrayUpdateSpec{
51						Operation: types.ArrayUpdateOperationAdd,
52					},
53					Info: &types.ClusterVmGroup{
54						ClusterGroupInfo: types.ClusterGroupInfo{
55							Name: conf.VMGroupName,
56						},
57						Vm: vms,
58					},
59				},
60			},
61		}
62
63		return d.appliance.Cluster.Reconfigure(op, spec, true)
64	}, tasks.IsTransientError)
65
66	return err
67}
68
69func (d *Dispatcher) deleteVMGroupIfUsed(conf *config.VirtualContainerHostConfigSpec) error {
70	defer trace.End(trace.Begin("", d.op))
71
72	if !conf.UseVMGroup {
73		return nil
74	}
75
76	return d.deleteVMGroupIfExists(conf)
77}
78
79func (d *Dispatcher) deleteVMGroupIfExists(conf *config.VirtualContainerHostConfigSpec) error {
80	defer trace.End(trace.Begin("", d.op))
81
82	exists, err := validate.VMGroupExists(d.op, d.session.Cluster, conf.VMGroupName)
83	if err != nil {
84		d.op.Warn(err)
85		return nil
86	}
87	if !exists {
88		d.op.Debugf("Expected VM Group cannot be found; skipping removal.")
89		return nil
90	}
91
92	d.op.Infof("Removing VM Group %q", conf.VMGroupName)
93
94	spec := &types.ClusterConfigSpecEx{
95		GroupSpec: []types.ClusterGroupSpec{
96			{
97				ArrayUpdateSpec: types.ArrayUpdateSpec{
98					Operation: types.ArrayUpdateOperationRemove,
99					RemoveKey: conf.VMGroupName,
100				},
101			},
102		},
103	}
104
105	_, err = tasks.WaitForResultAndRetryIf(d.op, func(op context.Context) (tasks.Task, error) {
106		return d.appliance.Cluster.Reconfigure(op, spec, true)
107	}, tasks.IsTransientError)
108
109	return err
110}
111