github.com/vmware/govmomi@v0.51.0/simulator/customization_spec_manager.go (about) 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 simulator 6 7 import ( 8 "encoding/pem" 9 "fmt" 10 "sync/atomic" 11 "time" 12 13 "github.com/vmware/govmomi/simulator/internal" 14 "github.com/vmware/govmomi/vim25/methods" 15 "github.com/vmware/govmomi/vim25/mo" 16 "github.com/vmware/govmomi/vim25/soap" 17 "github.com/vmware/govmomi/vim25/types" 18 ) 19 20 var DefaultCustomizationSpec = []types.CustomizationSpecItem{ 21 { 22 Info: types.CustomizationSpecInfo{ 23 Name: "vcsim-linux", 24 Description: "", 25 Type: "Linux", 26 ChangeVersion: "1569965707", 27 LastUpdateTime: types.NewTime(time.Now()), 28 }, 29 Spec: types.CustomizationSpec{ 30 Options: &types.CustomizationLinuxOptions{}, 31 Identity: &types.CustomizationLinuxPrep{ 32 CustomizationIdentitySettings: types.CustomizationIdentitySettings{}, 33 HostName: &types.CustomizationVirtualMachineName{}, 34 Domain: "eng.vmware.com", 35 TimeZone: "Pacific/Apia", 36 HwClockUTC: types.NewBool(true), 37 }, 38 GlobalIPSettings: types.CustomizationGlobalIPSettings{ 39 DnsSuffixList: nil, 40 DnsServerList: []string{"127.0.1.1"}, 41 }, 42 NicSettingMap: []types.CustomizationAdapterMapping{ 43 { 44 MacAddress: "", 45 Adapter: types.CustomizationIPSettings{ 46 Ip: &types.CustomizationDhcpIpGenerator{}, 47 SubnetMask: "", 48 Gateway: nil, 49 IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil), 50 DnsServerList: nil, 51 DnsDomain: "", 52 PrimaryWINS: "", 53 SecondaryWINS: "", 54 NetBIOS: "", 55 }, 56 }, 57 }, 58 EncryptionKey: nil, 59 }, 60 }, 61 { 62 Info: types.CustomizationSpecInfo{ 63 Name: "vcsim-linux-static", 64 Description: "", 65 Type: "Linux", 66 ChangeVersion: "1569969598", 67 LastUpdateTime: types.NewTime(time.Now()), 68 }, 69 Spec: types.CustomizationSpec{ 70 Options: &types.CustomizationLinuxOptions{}, 71 Identity: &types.CustomizationLinuxPrep{ 72 CustomizationIdentitySettings: types.CustomizationIdentitySettings{}, 73 HostName: &types.CustomizationPrefixName{ 74 CustomizationName: types.CustomizationName{}, 75 Base: "vcsim", 76 }, 77 Domain: "eng.vmware.com", 78 TimeZone: "Africa/Cairo", 79 HwClockUTC: types.NewBool(true), 80 }, 81 GlobalIPSettings: types.CustomizationGlobalIPSettings{ 82 DnsSuffixList: nil, 83 DnsServerList: []string{"127.0.1.1"}, 84 }, 85 NicSettingMap: []types.CustomizationAdapterMapping{ 86 { 87 MacAddress: "", 88 Adapter: types.CustomizationIPSettings{ 89 Ip: &types.CustomizationUnknownIpGenerator{}, 90 SubnetMask: "255.255.255.0", 91 Gateway: []string{"10.0.0.1"}, 92 IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil), 93 DnsServerList: nil, 94 DnsDomain: "", 95 PrimaryWINS: "", 96 SecondaryWINS: "", 97 NetBIOS: "", 98 }, 99 }, 100 }, 101 EncryptionKey: nil, 102 }, 103 }, 104 { 105 Info: types.CustomizationSpecInfo{ 106 Name: "vcsim-windows-static", 107 Description: "", 108 Type: "Windows", 109 ChangeVersion: "1569978029", 110 LastUpdateTime: types.NewTime(time.Now()), 111 }, 112 Spec: types.CustomizationSpec{ 113 Options: &types.CustomizationWinOptions{ 114 CustomizationOptions: types.CustomizationOptions{}, 115 ChangeSID: true, 116 DeleteAccounts: false, 117 Reboot: "", 118 }, 119 Identity: &types.CustomizationSysprep{ 120 CustomizationIdentitySettings: types.CustomizationIdentitySettings{}, 121 GuiUnattended: types.CustomizationGuiUnattended{ 122 Password: (*types.CustomizationPassword)(nil), 123 TimeZone: 2, 124 AutoLogon: false, 125 AutoLogonCount: 1, 126 }, 127 UserData: types.CustomizationUserData{ 128 FullName: "vcsim", 129 OrgName: "VMware", 130 ComputerName: &types.CustomizationVirtualMachineName{}, 131 ProductId: "", 132 }, 133 GuiRunOnce: (*types.CustomizationGuiRunOnce)(nil), 134 Identification: types.CustomizationIdentification{ 135 JoinWorkgroup: "WORKGROUP", 136 JoinDomain: "", 137 DomainAdmin: "", 138 DomainAdminPassword: (*types.CustomizationPassword)(nil), 139 }, 140 LicenseFilePrintData: &types.CustomizationLicenseFilePrintData{ 141 AutoMode: "perServer", 142 AutoUsers: 5, 143 }, 144 }, 145 GlobalIPSettings: types.CustomizationGlobalIPSettings{}, 146 NicSettingMap: []types.CustomizationAdapterMapping{ 147 { 148 MacAddress: "", 149 Adapter: types.CustomizationIPSettings{ 150 Ip: &types.CustomizationUnknownIpGenerator{}, 151 SubnetMask: "255.255.255.0", 152 Gateway: []string{"10.0.0.1"}, 153 IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil), 154 DnsServerList: nil, 155 DnsDomain: "", 156 PrimaryWINS: "", 157 SecondaryWINS: "", 158 NetBIOS: "", 159 }, 160 }, 161 }, 162 EncryptionKey: nil, 163 }, 164 }, 165 { 166 Info: types.CustomizationSpecInfo{ 167 Name: "vcsim-windows-domain", 168 Description: "", 169 Type: "Windows", 170 ChangeVersion: "1569970234", 171 LastUpdateTime: types.NewTime(time.Now()), 172 }, 173 Spec: types.CustomizationSpec{ 174 Options: &types.CustomizationWinOptions{ 175 CustomizationOptions: types.CustomizationOptions{}, 176 ChangeSID: true, 177 DeleteAccounts: false, 178 Reboot: "", 179 }, 180 Identity: &types.CustomizationSysprep{ 181 CustomizationIdentitySettings: types.CustomizationIdentitySettings{}, 182 GuiUnattended: types.CustomizationGuiUnattended{ 183 Password: &types.CustomizationPassword{ 184 Value: "3Gs...==", 185 PlainText: false, 186 }, 187 TimeZone: 15, 188 AutoLogon: false, 189 AutoLogonCount: 1, 190 }, 191 UserData: types.CustomizationUserData{ 192 FullName: "dougm", 193 OrgName: "VMware", 194 ComputerName: &types.CustomizationVirtualMachineName{}, 195 ProductId: "", 196 }, 197 GuiRunOnce: (*types.CustomizationGuiRunOnce)(nil), 198 Identification: types.CustomizationIdentification{ 199 JoinWorkgroup: "", 200 JoinDomain: "DOMAIN", 201 DomainAdmin: "vcsim", 202 DomainAdminPassword: &types.CustomizationPassword{ 203 Value: "H3g...==", 204 PlainText: false, 205 }, 206 }, 207 LicenseFilePrintData: &types.CustomizationLicenseFilePrintData{ 208 AutoMode: "perServer", 209 AutoUsers: 5, 210 }, 211 }, 212 GlobalIPSettings: types.CustomizationGlobalIPSettings{}, 213 NicSettingMap: []types.CustomizationAdapterMapping{ 214 { 215 MacAddress: "", 216 Adapter: types.CustomizationIPSettings{ 217 Ip: &types.CustomizationUnknownIpGenerator{}, 218 SubnetMask: "255.255.255.0", 219 Gateway: []string{"10.0.0.1"}, 220 IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil), 221 DnsServerList: nil, 222 DnsDomain: "", 223 PrimaryWINS: "", 224 SecondaryWINS: "", 225 NetBIOS: "", 226 }, 227 }, 228 }, 229 EncryptionKey: nil, 230 }, 231 }, 232 } 233 234 type CustomizationSpecManager struct { 235 mo.CustomizationSpecManager 236 237 items []types.CustomizationSpecItem 238 } 239 240 func (m *CustomizationSpecManager) init(r *Registry) { 241 m.items = DefaultCustomizationSpec 242 243 // Real VC is different DN, X509v3 extensions, etc. 244 // This is still useful for testing []byte of DER encoded cert over SOAP 245 if len(m.EncryptionKey) == 0 { 246 block, _ := pem.Decode(internal.LocalhostCert) 247 m.EncryptionKey = block.Bytes 248 } 249 } 250 251 var customizeNameCounter uint64 252 253 func customizeName(vm *VirtualMachine, base types.BaseCustomizationName) string { 254 n := atomic.AddUint64(&customizeNameCounter, 1) 255 256 switch name := base.(type) { 257 case *types.CustomizationPrefixName: 258 return fmt.Sprintf("%s-%d", name.Base, n) 259 case *types.CustomizationCustomName: 260 return fmt.Sprintf("%s-%d", name.Argument, n) 261 case *types.CustomizationFixedName: 262 return name.Name 263 case *types.CustomizationUnknownName: 264 return "" 265 case *types.CustomizationVirtualMachineName: 266 return fmt.Sprintf("%s-%d", vm.Name, n) 267 default: 268 return "" 269 } 270 } 271 272 func (m *CustomizationSpecManager) DoesCustomizationSpecExist(ctx *Context, req *types.DoesCustomizationSpecExist) soap.HasFault { 273 exists := false 274 275 for _, item := range m.items { 276 if item.Info.Name == req.Name { 277 exists = true 278 break 279 } 280 } 281 282 return &methods.DoesCustomizationSpecExistBody{ 283 Res: &types.DoesCustomizationSpecExistResponse{ 284 Returnval: exists, 285 }, 286 } 287 } 288 289 func (m *CustomizationSpecManager) GetCustomizationSpec(ctx *Context, req *types.GetCustomizationSpec) soap.HasFault { 290 body := new(methods.GetCustomizationSpecBody) 291 292 for _, item := range m.items { 293 if item.Info.Name == req.Name { 294 body.Res = &types.GetCustomizationSpecResponse{ 295 Returnval: item, 296 } 297 return body 298 } 299 } 300 301 body.Fault_ = Fault("", new(types.NotFound)) 302 303 return body 304 } 305 306 func (m *CustomizationSpecManager) CreateCustomizationSpec(ctx *Context, req *types.CreateCustomizationSpec) soap.HasFault { 307 body := new(methods.CreateCustomizationSpecBody) 308 309 for _, item := range m.items { 310 if item.Info.Name == req.Item.Info.Name { 311 body.Fault_ = Fault("", &types.AlreadyExists{Name: req.Item.Info.Name}) 312 return body 313 } 314 } 315 316 m.items = append(m.items, req.Item) 317 body.Res = new(types.CreateCustomizationSpecResponse) 318 319 return body 320 } 321 322 func (m *CustomizationSpecManager) OverwriteCustomizationSpec(ctx *Context, req *types.OverwriteCustomizationSpec) soap.HasFault { 323 body := new(methods.OverwriteCustomizationSpecBody) 324 325 for i, item := range m.items { 326 if item.Info.Name == req.Item.Info.Name { 327 m.items[i] = req.Item 328 body.Res = new(types.OverwriteCustomizationSpecResponse) 329 return body 330 } 331 } 332 333 body.Fault_ = Fault("", new(types.NotFound)) 334 335 return body 336 } 337 338 func (m *CustomizationSpecManager) Get() mo.Reference { 339 clone := *m 340 341 for i := range clone.items { 342 clone.Info = append(clone.Info, clone.items[i].Info) 343 } 344 345 return &clone 346 }