Skip to content

Commit 4a0b946

Browse files
committed
vcsim: add query and metadata support for CNS Volume API
vcsim: add disk backing for cns volumes govc: add volume.create command govc: add volume.ls query filter flags Signed-off-by: Doug MacEachern <[email protected]>
1 parent 7396b62 commit 4a0b946

File tree

8 files changed

+653
-253
lines changed

8 files changed

+653
-253
lines changed

cli/volume/create.go

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package volume
6+
7+
import (
8+
"context"
9+
"flag"
10+
"fmt"
11+
12+
"github.com/vmware/govmomi/cli"
13+
"github.com/vmware/govmomi/cli/flags"
14+
"github.com/vmware/govmomi/cns"
15+
"github.com/vmware/govmomi/cns/types"
16+
"github.com/vmware/govmomi/session"
17+
"github.com/vmware/govmomi/units"
18+
vim "github.com/vmware/govmomi/vim25/types"
19+
)
20+
21+
type disk struct {
22+
*flags.DatastoreFlag
23+
*flags.StorageProfileFlag
24+
25+
size units.ByteSize
26+
27+
spec types.CnsVolumeCreateSpec
28+
29+
meta types.CnsKubernetesEntityMetadata
30+
31+
disk string
32+
}
33+
34+
func init() {
35+
cli.Register("volume.create", &disk{}, true)
36+
}
37+
38+
func (cmd *disk) Register(ctx context.Context, f *flag.FlagSet) {
39+
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
40+
cmd.DatastoreFlag.Register(ctx, f)
41+
42+
cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
43+
cmd.StorageProfileFlag.Register(ctx, f)
44+
45+
_ = cmd.size.Set("10G")
46+
f.Var(&cmd.size, "size", "Size of new volume")
47+
48+
f.StringVar(&cmd.spec.VolumeType, "type", string(types.CnsVolumeTypeBlock), "Volume type")
49+
50+
f.StringVar(&cmd.spec.Metadata.ContainerCluster.ClusterType, "cluster-type", string(types.CnsClusterTypeKubernetes), "Cluster type")
51+
f.StringVar(&cmd.spec.Metadata.ContainerCluster.ClusterFlavor, "cluster-flavor", string(types.CnsClusterFlavorVanilla), "Cluster flavor")
52+
f.StringVar(&cmd.spec.Metadata.ContainerCluster.ClusterDistribution, "cluster-distro", "KUBERNETES", "Cluster distribution")
53+
f.StringVar(&cmd.spec.Metadata.ContainerCluster.ClusterId, "cluster-id", "", "Cluster ID")
54+
f.StringVar(&cmd.spec.Metadata.ContainerCluster.VSphereUser, "vsphere-user", "", "vSphere user")
55+
56+
f.StringVar(&cmd.meta.EntityName, "entity-name", "", "Entity name")
57+
f.StringVar(&cmd.meta.Namespace, "entity-namespace", "default", "Entity namespace")
58+
f.StringVar(&cmd.meta.EntityType, "entity-type", string(types.CnsKubernetesEntityTypePVC), "Entity type")
59+
f.Var((*keyValue)(&cmd.meta.Labels), "label", "Label")
60+
61+
f.StringVar(&cmd.disk, "disk-id", "", "Backing disk id")
62+
}
63+
64+
func (cmd *disk) Process(ctx context.Context) error {
65+
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
66+
return err
67+
}
68+
if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
69+
return err
70+
}
71+
return nil
72+
}
73+
74+
func (cmd *disk) Usage() string {
75+
return "NAME"
76+
}
77+
78+
func (cmd *disk) Description() string {
79+
return `Create volume NAME on DS.
80+
81+
Examples:
82+
govc volume.create -size 10G my-volume`
83+
}
84+
85+
func (cmd *disk) Run(ctx context.Context, f *flag.FlagSet) error {
86+
cmd.spec.Name = f.Arg(0)
87+
if cmd.spec.Name == "" {
88+
return flag.ErrHelp
89+
}
90+
91+
vc, err := cmd.Client()
92+
if err != nil {
93+
return err
94+
}
95+
96+
c, err := cmd.CnsClient()
97+
if err != nil {
98+
return err
99+
}
100+
101+
ds, err := cmd.DatastoreIfSpecified()
102+
if err != nil {
103+
return err
104+
}
105+
106+
if ds != nil {
107+
cmd.spec.Datastores = []vim.ManagedObjectReference{ds.Reference()}
108+
}
109+
110+
profiles, err := cmd.StorageProfileList(ctx)
111+
if err != nil {
112+
return err
113+
}
114+
115+
for _, id := range profiles {
116+
cmd.spec.Profile = append(cmd.spec.Profile, &vim.VirtualMachineDefinedProfileSpec{ProfileId: id})
117+
}
118+
119+
cmd.spec.BackingObjectDetails = &types.CnsBlockBackingDetails{
120+
BackingDiskId: cmd.disk,
121+
CnsBackingObjectDetails: types.CnsBackingObjectDetails{
122+
CapacityInMb: int64(cmd.size) / units.MB,
123+
},
124+
}
125+
126+
if cmd.meta.EntityName == "" {
127+
cmd.meta.EntityName = cmd.spec.Name
128+
}
129+
cmd.spec.Metadata.EntityMetadata = append(cmd.spec.Metadata.EntityMetadata, &cmd.meta)
130+
131+
if cmd.spec.Metadata.ContainerCluster.VSphereUser == "" {
132+
s, err := session.NewManager(vc).UserSession(ctx)
133+
if err != nil {
134+
return err
135+
}
136+
cmd.spec.Metadata.ContainerCluster.VSphereUser = s.UserName
137+
}
138+
139+
task, err := c.CreateVolume(ctx, []types.CnsVolumeCreateSpec{cmd.spec})
140+
if err != nil {
141+
return err
142+
}
143+
144+
info, err := cns.GetTaskInfo(ctx, task)
145+
if err != nil {
146+
return err
147+
}
148+
149+
res, err := cns.GetTaskResult(ctx, info)
150+
if err != nil {
151+
return err
152+
}
153+
154+
fmt.Println(res.GetCnsVolumeOperationResult().VolumeId.Id)
155+
156+
return nil
157+
}

cli/volume/ls.go

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2020-2023 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package volume
186

@@ -35,6 +23,7 @@ import (
3523
type ls struct {
3624
*flags.ClientFlag
3725
*flags.DatastoreFlag
26+
*flags.StorageProfileFlag
3827
*flags.OutputFlag
3928

4029
types.CnsQueryFilter
@@ -45,6 +34,21 @@ type ls struct {
4534
back bool
4635
}
4736

37+
type keyValue []vim.KeyValue
38+
39+
func (e *keyValue) String() string {
40+
return fmt.Sprintf("%v", *e)
41+
}
42+
43+
func (e *keyValue) Set(v string) error {
44+
r := strings.SplitN(v, "=", 2)
45+
if len(r) < 2 {
46+
return fmt.Errorf("failed to parse: %s", v)
47+
}
48+
*e = append(*e, vim.KeyValue{Key: r[0], Value: r[1]})
49+
return nil
50+
}
51+
4852
func init() {
4953
cli.Register("volume.ls", &ls{})
5054
}
@@ -56,13 +60,21 @@ func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
5660
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
5761
cmd.DatastoreFlag.Register(ctx, f)
5862

63+
cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
64+
cmd.StorageProfileFlag.Register(ctx, f)
65+
5966
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
6067
cmd.OutputFlag.Register(ctx, f)
6168

6269
f.BoolVar(&cmd.long, "l", false, "Long listing format")
6370
f.BoolVar(&cmd.id, "i", false, "List volume ID only")
6471
f.BoolVar(&cmd.disk, "L", false, "List volume disk or file backing ID only")
6572
f.BoolVar(&cmd.back, "b", false, "List file backing path")
73+
74+
f.Var((*flags.StringList)(&cmd.Names), "n", "List volumes with names")
75+
f.Var((*keyValue)(&cmd.Labels), "label", "List volumes with labels")
76+
f.StringVar(&cmd.HealthStatus, "H", "", "List volumes with health status")
77+
f.Var((*flags.StringList)(&cmd.ContainerClusterIds), "c", "List volumes in clusters")
6678
}
6779

6880
func (cmd *ls) Process(ctx context.Context) error {
@@ -72,6 +84,9 @@ func (cmd *ls) Process(ctx context.Context) error {
7284
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
7385
return err
7486
}
87+
if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
88+
return err
89+
}
7590
return cmd.OutputFlag.Process(ctx)
7691
}
7792

@@ -123,6 +138,8 @@ func (r *lsWriter) Write(w io.Writer) error {
123138
id = backing.BackingFileId
124139
case *types.CnsVsanFileShareBackingDetails:
125140
id = backing.Name
141+
case *types.CnsBackingObjectDetails:
142+
id = volume.VolumeId.Id
126143
default:
127144
log.Printf("%s unknown backing type: %T", volume.VolumeId.Id, backing)
128145
}
@@ -135,16 +152,16 @@ func (r *lsWriter) Write(w io.Writer) error {
135152
tw := tabwriter.NewWriter(r.cmd.Out, 2, 0, 2, ' ', 0)
136153

137154
for _, volume := range r.Volume {
138-
fmt.Printf("%s\t%s", volume.VolumeId.Id, volume.Name)
155+
fmt.Fprintf(tw, "%s\t%s", volume.VolumeId.Id, volume.Name)
139156
if r.cmd.back {
140-
fmt.Printf("\t%s", r.backing(volume.VolumeId))
157+
fmt.Fprintf(tw, "\t%s", r.backing(volume.VolumeId))
141158
}
142159
if r.cmd.long {
143160
capacity := volume.BackingObjectDetails.GetCnsBackingObjectDetails().CapacityInMb
144161
c := volume.Metadata.ContainerCluster
145-
fmt.Printf("\t%s\t%s\t%s", units.ByteSize(capacity*1024*1024), c.ClusterType, c.ClusterId)
162+
fmt.Fprintf(tw, "\t%s\t%s\t%s", units.ByteSize(capacity*1024*1024), c.ClusterType, c.ClusterId)
146163
}
147-
fmt.Println()
164+
fmt.Fprintln(tw)
148165
}
149166

150167
return tw.Flush()
@@ -188,6 +205,11 @@ func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
188205
cmd.Datastores = []vim.ManagedObjectReference{ds.Reference()}
189206
}
190207

208+
cmd.StoragePolicyId, err = cmd.StorageProfile(ctx)
209+
if err != nil {
210+
return err
211+
}
212+
191213
c, err := cmd.CnsClient()
192214
if err != nil {
193215
return err

cli/volume/rm.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2020 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package volume
186

@@ -55,6 +43,11 @@ Examples:
5543
}
5644

5745
func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error {
46+
// Despite the method signature, CnsDeleteVolume can only delete 1 at a time.
47+
if f.NArg() != 1 {
48+
return flag.ErrHelp
49+
}
50+
5851
c, err := cmd.CnsClient()
5952
if err != nil {
6053
return err

0 commit comments

Comments
 (0)