github.com/vmware/govmomi@v0.37.1/govc/importx/spec.go (about) 1 /* 2 Copyright (c) 2015-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 */ 16 17 package importx 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "io" 24 "path" 25 "strings" 26 27 "github.com/vmware/govmomi/govc/cli" 28 "github.com/vmware/govmomi/govc/flags" 29 "github.com/vmware/govmomi/ovf" 30 "github.com/vmware/govmomi/vim25/types" 31 ) 32 33 var ( 34 allDiskProvisioningOptions = []string{ 35 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeFlat), 36 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeMonolithicSparse), 37 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeMonolithicFlat), 38 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeTwoGbMaxExtentSparse), 39 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeTwoGbMaxExtentFlat), 40 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeThin), 41 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeThick), 42 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeSeSparse), 43 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeEagerZeroedThick), 44 string(types.OvfCreateImportSpecParamsDiskProvisioningTypeSparse), 45 } 46 allIPAllocationPolicyOptions = []string{ 47 string(types.VAppIPAssignmentInfoIpAllocationPolicyDhcpPolicy), 48 string(types.VAppIPAssignmentInfoIpAllocationPolicyTransientPolicy), 49 string(types.VAppIPAssignmentInfoIpAllocationPolicyFixedPolicy), 50 string(types.VAppIPAssignmentInfoIpAllocationPolicyFixedAllocatedPolicy), 51 } 52 allIPProtocolOptions = []string{ 53 string(types.VAppIPAssignmentInfoProtocolsIPv4), 54 string(types.VAppIPAssignmentInfoProtocolsIPv6), 55 } 56 ) 57 58 type spec struct { 59 *ArchiveFlag 60 *flags.ClientFlag 61 *flags.OutputFlag 62 63 hidden bool 64 } 65 66 func init() { 67 cli.Register("import.spec", &spec{}) 68 } 69 70 func (cmd *spec) Register(ctx context.Context, f *flag.FlagSet) { 71 cmd.ArchiveFlag, ctx = newArchiveFlag(ctx) 72 cmd.ArchiveFlag.Register(ctx, f) 73 cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) 74 cmd.ClientFlag.Register(ctx, f) 75 76 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 77 cmd.OutputFlag.Register(ctx, f) 78 79 f.BoolVar(&cmd.hidden, "hidden", false, "Enable hidden properties") 80 } 81 82 func (cmd *spec) Process(ctx context.Context) error { 83 if err := cmd.ArchiveFlag.Process(ctx); err != nil { 84 return err 85 } 86 if err := cmd.ClientFlag.Process(ctx); err != nil { 87 return err 88 } 89 return cmd.OutputFlag.Process(ctx) 90 } 91 92 func (cmd *spec) Usage() string { 93 return "PATH_TO_OVF_OR_OVA" 94 } 95 96 func (cmd *spec) Run(ctx context.Context, f *flag.FlagSet) error { 97 fpath := "" 98 args := f.Args() 99 if len(args) == 1 { 100 fpath = f.Arg(0) 101 } 102 103 if len(fpath) > 0 { 104 switch path.Ext(fpath) { 105 case ".ovf": 106 cmd.Archive = &FileArchive{Path: fpath} 107 case "", ".ova": 108 cmd.Archive = &TapeArchive{Path: fpath} 109 fpath = "*.ovf" 110 default: 111 return fmt.Errorf("invalid file extension %s", path.Ext(fpath)) 112 } 113 114 if isRemotePath(f.Arg(0)) { 115 client, err := cmd.Client() 116 if err != nil { 117 return err 118 } 119 switch archive := cmd.Archive.(type) { 120 case *FileArchive: 121 archive.Client = client 122 case *TapeArchive: 123 archive.Client = client 124 } 125 } 126 } 127 128 env, err := cmd.Spec(fpath) 129 if err != nil { 130 return err 131 } 132 133 if !cmd.All() { 134 cmd.JSON = true 135 } 136 return cmd.WriteResult(&specResult{env}) 137 } 138 139 type specResult struct { 140 *Options 141 } 142 143 func (*specResult) Write(w io.Writer) error { 144 return nil 145 } 146 147 func (cmd *spec) Map(e *ovf.Envelope) (res []Property) { 148 if e == nil || e.VirtualSystem == nil { 149 return nil 150 } 151 152 for _, p := range e.VirtualSystem.Product { 153 for i, v := range p.Property { 154 if v.UserConfigurable == nil { 155 continue 156 } 157 if !*v.UserConfigurable && !cmd.hidden { 158 continue 159 } 160 161 d := "" 162 if v.Default != nil { 163 d = *v.Default 164 } 165 166 // vSphere only accept True/False as boolean values for some reason 167 if v.Type == "boolean" { 168 d = strings.Title(d) 169 } 170 171 np := Property{KeyValue: KeyValue{Key: p.Key(v), Value: d}} 172 173 if cmd.Verbose() { 174 np.Spec = &p.Property[i] 175 } 176 177 res = append(res, np) 178 } 179 } 180 181 return 182 } 183 184 func (cmd *spec) Spec(fpath string) (*Options, error) { 185 e := &ovf.Envelope{} 186 if fpath != "" { 187 d, err := cmd.ReadOvf(fpath) 188 if err != nil { 189 return nil, err 190 } 191 192 if e, err = cmd.ReadEnvelope(d); err != nil { 193 return nil, err 194 } 195 } 196 197 var deploymentOptions []string 198 if e.DeploymentOption != nil && e.DeploymentOption.Configuration != nil { 199 // add default first 200 for _, c := range e.DeploymentOption.Configuration { 201 if c.Default != nil && *c.Default { 202 deploymentOptions = append(deploymentOptions, c.ID) 203 } 204 } 205 206 for _, c := range e.DeploymentOption.Configuration { 207 if c.Default == nil || !*c.Default { 208 deploymentOptions = append(deploymentOptions, c.ID) 209 } 210 } 211 } 212 213 o := Options{ 214 DiskProvisioning: allDiskProvisioningOptions[0], 215 IPAllocationPolicy: allIPAllocationPolicyOptions[0], 216 IPProtocol: allIPProtocolOptions[0], 217 MarkAsTemplate: false, 218 PowerOn: false, 219 WaitForIP: false, 220 InjectOvfEnv: false, 221 PropertyMapping: cmd.Map(e), 222 } 223 224 if deploymentOptions != nil { 225 o.Deployment = deploymentOptions[0] 226 } 227 228 if e.VirtualSystem != nil && e.VirtualSystem.Annotation != nil { 229 for _, a := range e.VirtualSystem.Annotation { 230 o.Annotation += a.Annotation 231 } 232 } 233 234 if e.Network != nil { 235 for _, net := range e.Network.Networks { 236 o.NetworkMapping = append(o.NetworkMapping, Network{net.Name, ""}) 237 } 238 } 239 240 if cmd.Verbose() { 241 if deploymentOptions != nil { 242 o.AllDeploymentOptions = deploymentOptions 243 } 244 o.AllDiskProvisioningOptions = allDiskProvisioningOptions 245 o.AllIPAllocationPolicyOptions = allIPAllocationPolicyOptions 246 o.AllIPProtocolOptions = allIPProtocolOptions 247 } 248 249 return &o, nil 250 }