github.com/vmware/govmomi@v0.43.0/simulator/customization_spec_manager.go (about)

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