diff --git a/govc/kms/key/create.go b/govc/kms/key/create.go new file mode 100644 index 000000000..bbcc731d8 --- /dev/null +++ b/govc/kms/key/create.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved. + +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 key + +import ( + "context" + "flag" + "fmt" + + "github.com/vmware/govmomi/crypto" + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" +) + +type create struct { + *flags.ClientFlag +} + +func init() { + cli.Register("kms.key.create", &create{}, true) +} + +func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) +} + +func (cmd *create) Usage() string { + return "ID" +} + +func (cmd *create) Description() string { + return `Generate crypto key. + +Examples: + govc kms.key.create my-kp` +} + +func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { + id := f.Arg(0) + if id == "" { + return flag.ErrHelp + } + + c, err := cmd.Client() + if err != nil { + return err + } + + m, err := crypto.GetManagerKmip(c) + if err != nil { + return err + } + + key, err := m.GenerateKey(ctx, id) + if err != nil { + return err + } + + fmt.Println(key) + + return nil +} diff --git a/govc/kms/key/info.go b/govc/kms/key/info.go new file mode 100644 index 000000000..9200f46af --- /dev/null +++ b/govc/kms/key/info.go @@ -0,0 +1,182 @@ +/* +Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved. + +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 key + +import ( + "context" + "flag" + "fmt" + "io" + "strconv" + "text/tabwriter" + + "github.com/vmware/govmomi/crypto" + "github.com/vmware/govmomi/find" + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/types" +) + +type info struct { + *flags.ClientFlag + *flags.OutputFlag + + provider string + + avail, vms, hosts, other bool +} + +func init() { + cli.Register("kms.key.info", &info{}, true) +} + +func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) + + f.StringVar(&cmd.provider, "p", "", "Provider ID") + f.BoolVar(&cmd.avail, "a", true, "Show key availability") + f.BoolVar(&cmd.vms, "vms", false, "Show VMs using keys") + f.BoolVar(&cmd.hosts, "hosts", false, "Show hosts using keys") + f.BoolVar(&cmd.other, "other", false, "Show 3rd party using keys") +} + +func (cmd *info) Process(ctx context.Context) error { + if err := cmd.ClientFlag.Process(ctx); err != nil { + return err + } + return cmd.OutputFlag.Process(ctx) +} + +func (cmd *info) Usage() string { + return "ID..." +} + +func (cmd *info) Description() string { + return `Crypto key info. + +Examples: + govc kms.key.info -p my-kp ID + govc kms.key.info -p my-kp -vms ID` +} + +type infoResult struct { + Status []types.CryptoManagerKmipCryptoKeyStatus `json:"status"` + ctx context.Context + c *vim25.Client +} + +func (r *infoResult) writeObj(w io.Writer, refs []types.ManagedObjectReference) { + for _, ref := range refs { + p, err := find.InventoryPath(r.ctx, r.c, ref) + if err != nil { + p = ref.String() + } + fmt.Fprintf(w, " %s\t%s\n", ref.Value, p) + } +} + +func (r *infoResult) Write(w io.Writer) error { + tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) + + for _, s := range r.Status { + avail := "-" + reason := s.Reason + if s.KeyAvailable != nil { + avail = strconv.FormatBool(*s.KeyAvailable) + if *s.KeyAvailable && reason == "" { + reason = "KeyStateAvailable" + } + } + pid := "" + if p := s.KeyId.ProviderId; p != nil { + pid = p.Id + } + fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", + pid, s.KeyId.KeyId, avail, reason) + r.writeObj(tw, s.EncryptedVMs) + r.writeObj(tw, s.AffectedHosts) + } + + return tw.Flush() +} + +func argsToKeys(p string, args []string) []types.CryptoKeyId { + ids := make([]types.CryptoKeyId, len(args)) + + var provider *types.KeyProviderId + + if p != "" { + provider = &types.KeyProviderId{Id: p} + } + + for i, id := range args { + ids[i] = types.CryptoKeyId{ + KeyId: id, + ProviderId: provider, + } + } + + return ids +} + +func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { + n := f.NArg() + if n == 0 { + return flag.ErrHelp + } + + ids := argsToKeys(cmd.provider, f.Args()) + + c, err := cmd.Client() + if err != nil { + return err + } + + m, err := crypto.GetManagerKmip(c) + if err != nil { + return err + } + + check := int32(0) + + opts := []struct { + enabled bool + val int32 + }{ + {cmd.avail, crypto.CheckKeyAvailable}, + {cmd.vms, crypto.CheckKeyUsedByVms}, + {cmd.hosts, crypto.CheckKeyUsedByHosts}, + {cmd.other, crypto.CheckKeyUsedByOther}, + } + + for _, opt := range opts { + if opt.enabled { + check = check | opt.val + } + } + + res, err := m.QueryCryptoKeyStatus(ctx, ids, check) + if err != nil { + return err + } + + return cmd.WriteResult(&infoResult{res, ctx, c}) +} diff --git a/govc/kms/key/rm.go b/govc/kms/key/rm.go new file mode 100644 index 000000000..1bebcc2f0 --- /dev/null +++ b/govc/kms/key/rm.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved. + +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 key + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/crypto" + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" +) + +type rm struct { + *flags.ClientFlag + + provider string + force bool +} + +func init() { + cli.Register("kms.key.rm", &rm{}, true) +} + +func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + + f.StringVar(&cmd.provider, "p", "", "Provider ID") + f.BoolVar(&cmd.force, "f", false, "Force") +} + +func (cmd *rm) Usage() string { + return "ID..." +} + +func (cmd *rm) Description() string { + return `Remove crypto keys. + +Examples: + govc kms.key.rm -p my-kp ID` +} + +func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error { + n := f.NArg() + if n == 0 { + return flag.ErrHelp + } + + c, err := cmd.Client() + if err != nil { + return err + } + + m, err := crypto.GetManagerKmip(c) + if err != nil { + return err + } + + ids := argsToKeys(cmd.provider, f.Args()) + + return m.RemoveKeys(ctx, ids, cmd.force) +} diff --git a/govc/main.go b/govc/main.go index e3c4f923f..f61c4fb95 100644 --- a/govc/main.go +++ b/govc/main.go @@ -73,6 +73,7 @@ import ( _ "github.com/vmware/govmomi/govc/host/vswitch" _ "github.com/vmware/govmomi/govc/importx" _ "github.com/vmware/govmomi/govc/kms" + _ "github.com/vmware/govmomi/govc/kms/key" _ "github.com/vmware/govmomi/govc/library" _ "github.com/vmware/govmomi/govc/library/policy" _ "github.com/vmware/govmomi/govc/library/session"