diff --git a/pkg/executables/config/deploy-opts.json b/pkg/executables/config/deploy-opts.json deleted file mode 100644 index 287606fee979..000000000000 --- a/pkg/executables/config/deploy-opts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "DiskProvisioning": "thin" -} diff --git a/pkg/executables/govc.go b/pkg/executables/govc.go index a03cc89a839f..cd4de990cdf1 100644 --- a/pkg/executables/govc.go +++ b/pkg/executables/govc.go @@ -36,13 +36,20 @@ const ( vSpherePasswordKey = "EKSA_VSPHERE_PASSWORD" vSphereServerKey = "VSPHERE_SERVER" byteToGiB = 1073741824.0 - deployOptsFile = "deploy-opts.json" + DeployOptsFile = "deploy-opts.json" ) var requiredEnvs = []string{govcUsernameKey, govcPasswordKey, govcURLKey, govcInsecure} -//go:embed config/deploy-opts.json -var deployOpts []byte +type networkMapping struct { + Name string `json:"Name,omitempty"` + Network string `json:"Network,omitempty"` +} + +type deployOption struct { + DiskProvisioning string `json:"DiskProvisioning,omitempty"` + NetworkMapping []networkMapping `json:"NetworkMapping,omitempty"` +} type FolderType string @@ -269,9 +276,9 @@ func (g *Govc) CreateLibrary(ctx context.Context, datastore, library string) err return nil } -func (g *Govc) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, resourcePool string, resizeBRDisk bool) error { +func (g *Govc) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, network, resourcePool string, resizeBRDisk bool) error { logger.V(4).Info("Deploying template", "dir", templateDir, "templateName", templateName) - if err := g.deployTemplate(ctx, library, templateName, templateDir, datacenter, datastore, resourcePool); err != nil { + if err := g.deployTemplate(ctx, library, templateName, templateDir, datacenter, datastore, network, resourcePool); err != nil { return err } @@ -343,7 +350,7 @@ func (g *Govc) ImportTemplate(ctx context.Context, library, ovaURL, name string) return nil } -func (g *Govc) deployTemplate(ctx context.Context, library, templateName, deployFolder, datacenter, datastore, resourcePool string) error { +func (g *Govc) deployTemplate(ctx context.Context, library, templateName, deployFolder, datacenter, datastore, network, resourcePool string) error { envMap, err := g.validateAndSetupCreds() if err != nil { return fmt.Errorf("failed govc validations: %v", err) @@ -354,7 +361,12 @@ func (g *Govc) deployTemplate(ctx context.Context, library, templateName, deploy templateInLibraryPath = fmt.Sprintf("/%s", templateInLibraryPath) } - deployOptsPath, err := g.writer.Write(deployOptsFile, deployOpts, filewriter.PersistentFile) + deployOpts, err := getDeployOptions(network) + if err != nil { + return err + } + + deployOptsPath, err := g.writer.Write(DeployOptsFile, deployOpts, filewriter.PersistentFile) if err != nil { return fmt.Errorf("failed writing deploy options file to disk: %v", err) } @@ -897,3 +909,26 @@ func (g *Govc) createCategory(ctx context.Context, name string, objectTypes []ob } return nil } + +func getDeployOptions(network string) ([]byte, error) { + deployOptsStruct := deployOption{ + DiskProvisioning: "thin", + NetworkMapping: []networkMapping{ + { + Name: "nic0", // needed for Ubuntu + Network: network, + }, + { + Name: "VM Network", // needed for Bottlerocket + Network: network, + }, + }, + } + + deployOpts, err := json.Marshal(deployOptsStruct) + if err != nil { + return nil, fmt.Errorf("marshalling template deployment options: %v", err) + } + + return deployOpts, err +} diff --git a/pkg/executables/govc_test.go b/pkg/executables/govc_test.go index 990a53c18938..28a5982a8926 100644 --- a/pkg/executables/govc_test.go +++ b/pkg/executables/govc_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "errors" + "io/ioutil" "net/http" "net/http/httptest" "os" @@ -13,6 +14,7 @@ import ( "testing" "github.com/golang/mock/gomock" + "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/aws/eks-anywhere/internal/test" @@ -23,14 +25,15 @@ import ( ) const ( - govcUsername = "GOVC_USERNAME" - govcPassword = "GOVC_PASSWORD" - govcURL = "GOVC_URL" - govcInsecure = "GOVC_INSECURE" - vSphereUsername = "EKSA_VSPHERE_USERNAME" - vSpherePassword = "EKSA_VSPHERE_PASSWORD" - vSphereServer = "VSPHERE_SERVER" - templateLibrary = "eks-a-templates" + govcUsername = "GOVC_USERNAME" + govcPassword = "GOVC_PASSWORD" + govcURL = "GOVC_URL" + govcInsecure = "GOVC_INSECURE" + vSphereUsername = "EKSA_VSPHERE_USERNAME" + vSpherePassword = "EKSA_VSPHERE_PASSWORD" + vSphereServer = "VSPHERE_SERVER" + templateLibrary = "eks-a-templates" + expectedDeployOpts = `{"DiskProvisioning":"thin","NetworkMapping":[{"Name":"nic0","Network":"/SDDC-Datacenter/network/sddc-cgw-network-1"},{"Name":"VM Network","Network":"/SDDC-Datacenter/network/sddc-cgw-network-1"}]}` ) var govcEnvironment = map[string]string{ @@ -88,14 +91,14 @@ func setupContext(t *testing.T) { }) } -func setup(t *testing.T) (govc *executables.Govc, mockExecutable *mockexecutables.MockExecutable, env map[string]string) { +func setup(t *testing.T) (dir string, govc *executables.Govc, mockExecutable *mockexecutables.MockExecutable, env map[string]string) { setupContext(t) - _, writer := test.NewWriter(t) + dir, writer := test.NewWriter(t) mockCtrl := gomock.NewController(t) executable := mockexecutables.NewMockExecutable(mockCtrl) g := executables.NewGovc(executable, writer) - return g, executable, govcEnvironment + return dir, g, executable, govcEnvironment } type deployTemplateTest struct { @@ -104,6 +107,8 @@ type deployTemplateTest struct { env map[string]string datacenter string datastore string + dir string + network string resourcePool string templatePath string ovaURL string @@ -117,13 +122,15 @@ type deployTemplateTest struct { } func newDeployTemplateTest(t *testing.T) *deployTemplateTest { - g, exec, env := setup(t) + dir, g, exec, env := setup(t) return &deployTemplateTest{ govc: g, mockExecutable: exec, env: env, datacenter: "SDDC-Datacenter", datastore: "/SDDC-Datacenter/datastore/WorkloadDatastore", + dir: dir, + network: "/SDDC-Datacenter/network/sddc-cgw-network-1", resourcePool: "*/Resources/Compute-ResourcePool", templatePath: "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6", ovaURL: "https://aws.com/ova", @@ -181,7 +188,7 @@ func (dt *deployTemplateTest) expectMarkAsTemplateToReturn(err error) { func (dt *deployTemplateTest) DeployTemplateFromLibrary() error { gomock.InOrder(dt.expectations...) - return dt.govc.DeployTemplateFromLibrary(dt.ctx, dt.deployFolder, dt.templateName, templateLibrary, dt.datacenter, dt.datastore, dt.resourcePool, dt.resizeDisk2) + return dt.govc.DeployTemplateFromLibrary(dt.ctx, dt.deployFolder, dt.templateName, templateLibrary, dt.datacenter, dt.datastore, dt.network, dt.resourcePool, dt.resizeDisk2) } func (dt *deployTemplateTest) assertDeployTemplateSuccess(t *testing.T) { @@ -196,11 +203,22 @@ func (dt *deployTemplateTest) assertDeployTemplateError(t *testing.T) { } } +func (dt *deployTemplateTest) assertDeployOptsMatches(t *testing.T) { + g := gomega.NewWithT(t) + + actual, err := ioutil.ReadFile(filepath.Join(dt.dir, executables.DeployOptsFile)) + if err != nil { + t.Fatalf("failed to read deploy options file: %v", err) + } + + g.Expect(string(actual)).To(gomega.Equal(expectedDeployOpts)) +} + func TestSearchTemplateItExists(t *testing.T) { ctx := context.Background() datacenter := "SDDC-Datacenter" - g, executable, env := setup(t) + _, g, executable, env := setup(t) machineConfig := newMachineConfig(t) machineConfig.Spec.Template = "/SDDC Datacenter/vm/Templates/ubuntu 2004-kube-v1.19.6" executable.EXPECT().ExecuteWithEnv(ctx, env, "find", "-json", "/"+datacenter, "-type", "VirtualMachine", "-name", filepath.Base(machineConfig.Spec.Template)).Return(*bytes.NewBufferString("[\"/SDDC Datacenter/vm/Templates/ubuntu 2004-kube-v1.19.6\"]"), nil) @@ -216,7 +234,7 @@ func TestSearchTemplateItDoesNotExists(t *testing.T) { ctx := context.Background() datacenter := "SDDC-Datacenter" - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "find", "-json", "/"+datacenter, "-type", "VirtualMachine", "-name", filepath.Base(machineConfig.Spec.Template)).Return(*bytes.NewBufferString(""), nil) templateFullPath, err := g.SearchTemplate(ctx, datacenter, machineConfig) @@ -230,7 +248,7 @@ func TestSearchTemplateError(t *testing.T) { ctx := context.Background() datacenter := "SDDC-Datacenter" - g, executable, env := setup(t) + _, g, executable, env := setup(t) g.Retrier = retrier.NewWithMaxRetries(5, 0) executable.EXPECT().ExecuteWithEnv(ctx, env, gomock.Any()).Return(bytes.Buffer{}, errors.New("error from execute with env")).Times(5) @@ -243,7 +261,7 @@ func TestSearchTemplateError(t *testing.T) { func TestLibraryElementExistsItExists(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.ls", templateLibrary).Return(*bytes.NewBufferString("testing"), nil) exists, err := g.LibraryElementExists(ctx, templateLibrary) @@ -258,7 +276,7 @@ func TestLibraryElementExistsItExists(t *testing.T) { func TestLibraryElementExistsItDoesNotExists(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.ls", templateLibrary).Return(*bytes.NewBufferString(""), nil) exists, err := g.LibraryElementExists(ctx, templateLibrary) @@ -273,7 +291,7 @@ func TestLibraryElementExistsItDoesNotExists(t *testing.T) { func TestLibraryElementExistsError(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.ls", templateLibrary).Return(bytes.Buffer{}, errors.New("error from execute with env")) _, err := g.LibraryElementExists(ctx, templateLibrary) @@ -291,7 +309,7 @@ func TestGetLibraryElementContentVersionSuccess(t *testing.T) { ]` libraryElement := "/eks-a-templates/ubuntu-2004-kube-v1.19.6" - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.info", "-json", libraryElement).Return(*bytes.NewBufferString(response), nil) _, err := g.GetLibraryElementContentVersion(ctx, libraryElement) @@ -304,7 +322,7 @@ func TestGetLibraryElementContentVersionError(t *testing.T) { ctx := context.Background() libraryElement := "/eks-a-templates/ubuntu-2004-kube-v1.19.6" - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.info", "-json", libraryElement).Return(bytes.Buffer{}, errors.New("error from execute with env")) _, err := g.GetLibraryElementContentVersion(ctx, libraryElement) @@ -317,7 +335,7 @@ func TestDeleteLibraryElementSuccess(t *testing.T) { ctx := context.Background() libraryElement := "/eks-a-templates/ubuntu-2004-kube-v1.19.6" - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.rm", libraryElement).Return(*bytes.NewBufferString(""), nil) err := g.DeleteLibraryElement(ctx, libraryElement) @@ -330,7 +348,7 @@ func TestDeleteLibraryElementError(t *testing.T) { ctx := context.Background() libraryElement := "/eks-a-templates/ubuntu-2004-kube-v1.19.6" - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.rm", libraryElement).Return(bytes.Buffer{}, errors.New("error from execute with env")) err := g.DeleteLibraryElement(ctx, libraryElement) @@ -416,6 +434,7 @@ func TestDeployTemplateFromLibrarySuccess(t *testing.T) { tt.expectMarkAsTemplateToReturn(nil) tt.assertDeployTemplateSuccess(t) + tt.assertDeployOptsMatches(t) } func TestDeployTemplateFromLibraryErrorDeploy(t *testing.T) { @@ -542,7 +561,7 @@ func TestCreateLibrarySuccess(t *testing.T) { datastore := "/SDDC-Datacenter/datastore/WorkloadDatastore" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.create", "-ds", datastore, templateLibrary).Return(*bytes.NewBufferString("testing"), nil) err := g.CreateLibrary(ctx, datastore, templateLibrary) @@ -555,7 +574,7 @@ func TestCreateLibraryError(t *testing.T) { datastore := "/SDDC-Datacenter/datastore/WorkloadDatastore" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.create", "-ds", datastore, templateLibrary).Return(bytes.Buffer{}, errors.New("error from execute with env")) err := g.CreateLibrary(ctx, datastore, templateLibrary) @@ -568,7 +587,7 @@ func TestGetTagsSuccessNoTags(t *testing.T) { path := "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attached.ls", "-json", "-r", path).Return(*bytes.NewBufferString("null"), nil) tags, err := g.GetTags(ctx, path) @@ -591,7 +610,7 @@ func TestGetTagsSuccessHasTags(t *testing.T) { ]` wantTags := []string{"kubernetesChannel:1.19", "eksd:1.19-4"} - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attached.ls", "-json", "-r", path).Return(*bytes.NewBufferString(tagsReponse), nil) gotTags, err := g.GetTags(ctx, path) @@ -608,7 +627,7 @@ func TestGetTagsErrorGovc(t *testing.T) { path := "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) g.Retrier = retrier.NewWithMaxRetries(5, 0) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attached.ls", "-json", "-r", path).Return(bytes.Buffer{}, errors.New("error from exec")).Times(5) @@ -622,7 +641,7 @@ func TestGetTagsErrorUnmarshalling(t *testing.T) { path := "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attached.ls", "-json", "-r", path).Return(*bytes.NewBufferString("invalid"), nil) _, err := g.GetTags(ctx, path) @@ -634,7 +653,7 @@ func TestGetTagsErrorUnmarshalling(t *testing.T) { func TestListTagsSuccessNoTags(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.ls", "-json").Return(*bytes.NewBufferString("null"), nil) tags, err := g.ListTags(ctx) @@ -664,7 +683,7 @@ func TestListTagsSuccessHasTags(t *testing.T) { ]` wantTags := []string{"eksd:1.19-4", "kubernetesChannel:1.19"} - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.ls", "-json").Return(*bytes.NewBufferString(tagsReponse), nil) gotTags, err := g.ListTags(ctx) @@ -680,7 +699,7 @@ func TestListTagsSuccessHasTags(t *testing.T) { func TestListTagsErrorGovc(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.ls", "-json").Return(bytes.Buffer{}, errors.New("error from exec")) _, err := g.ListTags(ctx) @@ -692,7 +711,7 @@ func TestListTagsErrorGovc(t *testing.T) { func TestListTagsErrorUnmarshalling(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.ls", "-json").Return(*bytes.NewBufferString("invalid"), nil) _, err := g.ListTags(ctx) @@ -706,7 +725,7 @@ func TestAddTagSuccess(t *testing.T) { path := "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attach", tag, path).Return(*bytes.NewBufferString(""), nil) err := g.AddTag(ctx, path, tag) @@ -720,7 +739,7 @@ func TestAddTagError(t *testing.T) { path := "/SDDC-Datacenter/vm/Templates/ubuntu-2004-kube-v1.19.6" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.attach", tag, path).Return(bytes.Buffer{}, errors.New("error from execute with env")) err := g.AddTag(ctx, path, tag) @@ -734,7 +753,7 @@ func TestCreateTagSuccess(t *testing.T) { tag := "tag" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.create", "-c", category, tag).Return(*bytes.NewBufferString(""), nil) err := g.CreateTag(ctx, tag, category) @@ -748,7 +767,7 @@ func TestCreateTagError(t *testing.T) { tag := "tag" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.create", "-c", category, tag).Return(bytes.Buffer{}, errors.New("error from execute with env")) err := g.CreateTag(ctx, tag, category) @@ -760,7 +779,7 @@ func TestCreateTagError(t *testing.T) { func TestListCategoriesSuccessNoCategories(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.ls", "-json").Return(*bytes.NewBufferString("null"), nil) gotCategories, err := g.ListCategories(ctx) @@ -797,7 +816,7 @@ func TestListCategoriesSuccessHasCategories(t *testing.T) { ]` wantCats := []string{"eksd", "kubernetesChannel"} - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.ls", "-json").Return(*bytes.NewBufferString(catsResponse), nil) gotCats, err := g.ListCategories(ctx) @@ -813,7 +832,7 @@ func TestListCategoriesSuccessHasCategories(t *testing.T) { func TestListCategoriesErrorGovc(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.ls", "-json").Return(bytes.Buffer{}, errors.New("error from exec")) _, err := g.ListCategories(ctx) @@ -825,7 +844,7 @@ func TestListCategoriesErrorGovc(t *testing.T) { func TestListCategoriesErrorUnmarshalling(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.ls", "-json").Return(*bytes.NewBufferString("invalid"), nil) _, err := g.ListCategories(ctx) @@ -838,7 +857,7 @@ func TestCreateCategoryForVMSuccess(t *testing.T) { category := "category" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.create", "-t", "VirtualMachine", category).Return(*bytes.NewBufferString(""), nil) err := g.CreateCategoryForVM(ctx, category) @@ -851,7 +870,7 @@ func TestCreateCategoryForVMError(t *testing.T) { category := "category" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "tags.category.create", "-t", "VirtualMachine", category).Return(bytes.Buffer{}, errors.New("error from execute with env")) err := g.CreateCategoryForVM(ctx, category) @@ -865,7 +884,7 @@ func TestImportTemplateSuccess(t *testing.T) { name := "name" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.import", "-k", "-pull", "-n", name, templateLibrary, ovaURL).Return(*bytes.NewBufferString(""), nil) if err := g.ImportTemplate(ctx, templateLibrary, ovaURL, name); err != nil { @@ -878,7 +897,7 @@ func TestImportTemplateError(t *testing.T) { name := "name" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "library.import", "-k", "-pull", "-n", name, templateLibrary, ovaURL).Return(bytes.Buffer{}, errors.New("error from execute with env")) if err := g.ImportTemplate(ctx, templateLibrary, ovaURL, name); err == nil { @@ -891,7 +910,7 @@ func TestDeleteTemplateSuccess(t *testing.T) { resourcePool := "resourcePool" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.markasvm", "-pool", resourcePool, template).Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "snapshot.remove", "-vm", template, "*").Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.destroy", template).Return(*bytes.NewBufferString(""), nil) @@ -906,7 +925,7 @@ func TestDeleteTemplateMarkAsVMError(t *testing.T) { resourcePool := "resourcePool" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.markasvm", "-pool", resourcePool, template).Return(bytes.Buffer{}, errors.New("error from execute with env")) if err := g.DeleteTemplate(ctx, resourcePool, template); err == nil { @@ -919,7 +938,7 @@ func TestDeleteTemplateRemoveSnapshotError(t *testing.T) { resourcePool := "resourcePool" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.markasvm", "-pool", resourcePool, template).Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "snapshot.remove", "-vm", template, "*").Return(bytes.Buffer{}, errors.New("error from execute with env")) @@ -933,7 +952,7 @@ func TestDeleteTemplateDeleteVMError(t *testing.T) { resourcePool := "resourcePool" ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.markasvm", "-pool", resourcePool, template).Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "snapshot.remove", "-vm", template, "*").Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "vm.destroy", template).Return(bytes.Buffer{}, errors.New("error from execute with env")) @@ -945,7 +964,7 @@ func TestDeleteTemplateDeleteVMError(t *testing.T) { func TestGovcLogoutSuccess(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "session.logout").Return(*bytes.NewBufferString(""), nil) executable.EXPECT().ExecuteWithEnv(ctx, env, "session.logout", "-k").Return(*bytes.NewBufferString(""), nil) @@ -958,7 +977,7 @@ func TestGovcLogoutSuccess(t *testing.T) { func TestGovcValidateVCenterConnectionSuccess(t *testing.T) { ctx := context.Background() ts := newHTTPSServer(t) - g, _, _ := setup(t) + _, g, _, _ := setup(t) if err := g.ValidateVCenterConnection(ctx, strings.TrimPrefix(ts.URL, "https://")); err != nil { t.Fatalf("Govc.ValidateVCenterConnection() err = %v, want err nil", err) @@ -967,7 +986,7 @@ func TestGovcValidateVCenterConnectionSuccess(t *testing.T) { func TestGovcValidateVCenterAuthenticationSuccess(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "about", "-k").Return(*bytes.NewBufferString(""), nil) @@ -978,7 +997,7 @@ func TestGovcValidateVCenterAuthenticationSuccess(t *testing.T) { func TestGovcIsCertSelfSignedTrue(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "about").Return(*bytes.NewBufferString(""), errors.New("")) @@ -989,7 +1008,7 @@ func TestGovcIsCertSelfSignedTrue(t *testing.T) { func TestGovcIsCertSelfSignedFalse(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) executable.EXPECT().ExecuteWithEnv(ctx, env, "about").Return(*bytes.NewBufferString(""), nil) @@ -1000,7 +1019,7 @@ func TestGovcIsCertSelfSignedFalse(t *testing.T) { func TestGovcGetCertThumbprintSuccess(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) wantThumbprint := "AB:AB:AB" executable.EXPECT().ExecuteWithEnv(ctx, env, "about.cert", "-thumbprint", "-k").Return(*bytes.NewBufferString("server.com AB:AB:AB"), nil) @@ -1017,7 +1036,7 @@ func TestGovcGetCertThumbprintSuccess(t *testing.T) { func TestGovcGetCertThumbprintBadOutput(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) wantErr := "invalid thumbprint format" executable.EXPECT().ExecuteWithEnv(ctx, env, "about.cert", "-thumbprint", "-k").Return(*bytes.NewBufferString("server.comAB:AB:AB"), nil) @@ -1029,7 +1048,7 @@ func TestGovcGetCertThumbprintBadOutput(t *testing.T) { func TestGovcConfigureCertThumbprint(t *testing.T) { ctx := context.Background() - g, _, _ := setup(t) + _, g, _, _ := setup(t) server := "server.com" thumbprint := "AB:AB:AB" wantKnownHostsContent := "server.com AB:AB:AB" @@ -1051,7 +1070,7 @@ func TestGovcConfigureCertThumbprint(t *testing.T) { func TestGovcDatacenterExistsTrue(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) datacenter := "datacenter_1" executable.EXPECT().ExecuteWithEnv(ctx, env, "datacenter.info", datacenter).Return(*bytes.NewBufferString(""), nil) @@ -1068,7 +1087,7 @@ func TestGovcDatacenterExistsTrue(t *testing.T) { func TestGovcDatacenterExistsFalse(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) datacenter := "datacenter_1" executable.EXPECT().ExecuteWithEnv(ctx, env, "datacenter.info", datacenter).Return(*bytes.NewBufferString("datacenter_1 not found"), errors.New("exit code 1")) @@ -1085,7 +1104,7 @@ func TestGovcDatacenterExistsFalse(t *testing.T) { func TestGovcNetworkExistsTrue(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) network := "/Networks/network_1" networkName := "network_1" networkDir := "/Networks" @@ -1104,7 +1123,7 @@ func TestGovcNetworkExistsTrue(t *testing.T) { func TestGovcNetworkExistsFalse(t *testing.T) { ctx := context.Background() - g, executable, env := setup(t) + _, g, executable, env := setup(t) network := "/Networks/network_1" networkName := "network_1" networkDir := "/Networks" diff --git a/pkg/providers/vsphere/defaults.go b/pkg/providers/vsphere/defaults.go index 9dbb0b07002b..64e3e057eeca 100644 --- a/pkg/providers/vsphere/defaults.go +++ b/pkg/providers/vsphere/defaults.go @@ -130,7 +130,7 @@ func (d *Defaulter) setupDefaultTemplate(ctx context.Context, spec *Spec, machin tags := requiredTemplateTagsByCategory(spec.Spec, machineConfig) // TODO: figure out if it's worth refactoring the factory to be able to reuse across machine configs. - templateFactory := templates.NewFactory(d.govc, spec.datacenterConfig.Spec.Datacenter, machineConfig.Spec.Datastore, machineConfig.Spec.ResourcePool, defaultTemplateLibrary) + templateFactory := templates.NewFactory(d.govc, spec.datacenterConfig.Spec.Datacenter, machineConfig.Spec.Datastore, spec.datacenterConfig.Spec.Network, machineConfig.Spec.ResourcePool, defaultTemplateLibrary) // TODO: remove the factory's dependency on a machineConfig if err := templateFactory.CreateIfMissing(ctx, spec.datacenterConfig.Spec.Datacenter, machineConfig, ova.URI, tags); err != nil { diff --git a/pkg/providers/vsphere/internal/templates/factory.go b/pkg/providers/vsphere/internal/templates/factory.go index 5a3f67e668b7..14ebca3d0558 100644 --- a/pkg/providers/vsphere/internal/templates/factory.go +++ b/pkg/providers/vsphere/internal/templates/factory.go @@ -20,6 +20,7 @@ type Factory struct { client GovcClient datacenter string datastore string + network string resourcePool string templateLibrary string tagsFactory *tags.Factory @@ -27,7 +28,7 @@ type Factory struct { type GovcClient interface { CreateLibrary(ctx context.Context, datastore, library string) error - DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, resourcePool string, resizeBRDisk bool) error + DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, network, resourcePool string, resizeBRDisk bool) error SearchTemplate(ctx context.Context, datacenter string, machineConfig *v1alpha1.VSphereMachineConfig) (string, error) ImportTemplate(ctx context.Context, library, ovaURL, name string) error LibraryElementExists(ctx context.Context, library string) (bool, error) @@ -40,11 +41,12 @@ type GovcClient interface { CreateCategoryForVM(ctx context.Context, name string) error } -func NewFactory(client GovcClient, datacenter, datastore, resourcePool, templateLibrary string) *Factory { +func NewFactory(client GovcClient, datacenter, datastore, network, resourcePool, templateLibrary string) *Factory { return &Factory{ client: client, datacenter: datacenter, datastore: datastore, + network: network, resourcePool: resourcePool, templateLibrary: templateLibrary, tagsFactory: tags.NewFactory(client), @@ -92,7 +94,7 @@ func (f *Factory) createTemplate(ctx context.Context, templatePath, ovaURL, osFa if strings.EqualFold(osFamily, string(v1alpha1.Bottlerocket)) { resizeBRDisk = true } - if err := f.client.DeployTemplateFromLibrary(ctx, templateDir, templateName, f.templateLibrary, f.datacenter, f.datastore, f.resourcePool, resizeBRDisk); err != nil { + if err := f.client.DeployTemplateFromLibrary(ctx, templateDir, templateName, f.templateLibrary, f.datacenter, f.datastore, f.network, f.resourcePool, resizeBRDisk); err != nil { return fmt.Errorf("failed deploying template: %v", err) } diff --git a/pkg/providers/vsphere/internal/templates/factory_test.go b/pkg/providers/vsphere/internal/templates/factory_test.go index a8c11ab1181c..60ce07ef018b 100644 --- a/pkg/providers/vsphere/internal/templates/factory_test.go +++ b/pkg/providers/vsphere/internal/templates/factory_test.go @@ -17,6 +17,7 @@ type test struct { t *testing.T datacenter string datastore string + network string resourcePool string templateLibrary string resizeDisk2 bool @@ -47,6 +48,7 @@ func newTest(t *testing.T) *test { t: t, datacenter: "SDDC-Datacenter", datastore: "datastore", + network: "sddc-cgw-network-1", resourcePool: "*/pool/", templateLibrary: "library", resizeDisk2: false, @@ -61,6 +63,7 @@ func newTest(t *testing.T) *test { test.govc, test.datacenter, test.datastore, + test.network, test.resourcePool, test.templateLibrary, ) @@ -173,7 +176,7 @@ func TestFactoryCreateIfMissingErrorDeploy(t *testing.T) { ct.govc.EXPECT().GetLibraryElementContentVersion(ct.ctx, ct.templateInLibrary).Return(ct.libraryContentDoesNotExist, nil) ct.govc.EXPECT().ImportTemplate(ct.ctx, ct.templateLibrary, ct.ovaURL, ct.templateName).Return(nil) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(ct.dummyError) ct.assertErrorFromCreateIfMissing() @@ -187,7 +190,7 @@ func TestFactoryCreateIfMissingErrorFromTagFactory(t *testing.T) { ct.govc.EXPECT().GetLibraryElementContentVersion(ct.ctx, ct.templateInLibrary).Return(ct.libraryContentDoesNotExist, nil) ct.govc.EXPECT().ImportTemplate(ct.ctx, ct.templateLibrary, ct.ovaURL, ct.templateName).Return(nil) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(nil) // expects for tagging @@ -204,7 +207,7 @@ func TestFactoryCreateIfMissingSuccessLibraryDoesNotExist(t *testing.T) { ct.govc.EXPECT().GetLibraryElementContentVersion(ct.ctx, ct.templateInLibrary).Return(ct.libraryContentDoesNotExist, nil) ct.govc.EXPECT().ImportTemplate(ct.ctx, ct.templateLibrary, ct.ovaURL, ct.templateName).Return(nil) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(nil) // expects for tagging @@ -221,7 +224,7 @@ func TestFactoryCreateIfMissingSuccessLibraryExists(t *testing.T) { ct.govc.EXPECT().GetLibraryElementContentVersion(ct.ctx, ct.templateInLibrary).Return(ct.libraryContentDoesNotExist, nil) ct.govc.EXPECT().ImportTemplate(ct.ctx, ct.templateLibrary, ct.ovaURL, ct.templateName).Return(nil) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(nil) // expects for tagging @@ -237,7 +240,7 @@ func TestFactoryCreateIfMissingSuccessTemplateInLibraryExists(t *testing.T) { ct.govc.EXPECT().LibraryElementExists(ct.ctx, ct.templateLibrary).Return(true, nil) ct.govc.EXPECT().GetLibraryElementContentVersion(ct.ctx, ct.templateInLibrary).Return(ct.libraryContentValid, nil) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(nil) // expects for tagging @@ -255,7 +258,7 @@ func TestFactoryCreateIfMissingSuccessTemplateInLibraryCorrupted(t *testing.T) { ct.govc.EXPECT().DeleteLibraryElement(ct.ctx, ct.templateInLibrary).Return(nil) ct.govc.EXPECT().ImportTemplate(ct.ctx, ct.templateLibrary, ct.ovaURL, ct.templateName) ct.govc.EXPECT().DeployTemplateFromLibrary( - ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.resourcePool, ct.resizeDisk2, + ct.ctx, ct.templateDir, ct.templateName, ct.templateLibrary, ct.datacenter, ct.datastore, ct.network, ct.resourcePool, ct.resizeDisk2, ).Return(nil) // expects for tagging diff --git a/pkg/providers/vsphere/internal/templates/mocks/govc.go b/pkg/providers/vsphere/internal/templates/mocks/govc.go index 855cc3c54a10..5c2d0f9787a4 100644 --- a/pkg/providers/vsphere/internal/templates/mocks/govc.go +++ b/pkg/providers/vsphere/internal/templates/mocks/govc.go @@ -106,17 +106,17 @@ func (mr *MockGovcClientMockRecorder) DeleteLibraryElement(ctx, element interfac } // DeployTemplateFromLibrary mocks base method. -func (m *MockGovcClient) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, resourcePool string, resizeBRDisk bool) error { +func (m *MockGovcClient) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, network, resourcePool string, resizeBRDisk bool) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeployTemplateFromLibrary", ctx, templateDir, templateName, library, datacenter, datastore, resourcePool, resizeBRDisk) + ret := m.ctrl.Call(m, "DeployTemplateFromLibrary", ctx, templateDir, templateName, library, datacenter, datastore, network, resourcePool, resizeBRDisk) ret0, _ := ret[0].(error) return ret0 } // DeployTemplateFromLibrary indicates an expected call of DeployTemplateFromLibrary. -func (mr *MockGovcClientMockRecorder) DeployTemplateFromLibrary(ctx, templateDir, templateName, library, datacenter, datastore, resourcePool, resizeBRDisk interface{}) *gomock.Call { +func (mr *MockGovcClientMockRecorder) DeployTemplateFromLibrary(ctx, templateDir, templateName, library, datacenter, datastore, network, resourcePool, resizeBRDisk interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeployTemplateFromLibrary", reflect.TypeOf((*MockGovcClient)(nil).DeployTemplateFromLibrary), ctx, templateDir, templateName, library, datacenter, datastore, resourcePool, resizeBRDisk) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeployTemplateFromLibrary", reflect.TypeOf((*MockGovcClient)(nil).DeployTemplateFromLibrary), ctx, templateDir, templateName, library, datacenter, datastore, network, resourcePool, resizeBRDisk) } // GetLibraryElementContentVersion mocks base method. diff --git a/pkg/providers/vsphere/mocks/client.go b/pkg/providers/vsphere/mocks/client.go index d70312fd55a6..05142b3ca2be 100644 --- a/pkg/providers/vsphere/mocks/client.go +++ b/pkg/providers/vsphere/mocks/client.go @@ -141,17 +141,17 @@ func (mr *MockProviderGovcClientMockRecorder) DeleteLibraryElement(arg0, arg1 in } // DeployTemplateFromLibrary mocks base method. -func (m *MockProviderGovcClient) DeployTemplateFromLibrary(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 string, arg7 bool) error { +func (m *MockProviderGovcClient) DeployTemplateFromLibrary(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6, arg7 string, arg8 bool) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeployTemplateFromLibrary", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + ret := m.ctrl.Call(m, "DeployTemplateFromLibrary", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) ret0, _ := ret[0].(error) return ret0 } // DeployTemplateFromLibrary indicates an expected call of DeployTemplateFromLibrary. -func (mr *MockProviderGovcClientMockRecorder) DeployTemplateFromLibrary(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { +func (mr *MockProviderGovcClientMockRecorder) DeployTemplateFromLibrary(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeployTemplateFromLibrary", reflect.TypeOf((*MockProviderGovcClient)(nil).DeployTemplateFromLibrary), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeployTemplateFromLibrary", reflect.TypeOf((*MockProviderGovcClient)(nil).DeployTemplateFromLibrary), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } // GetCertThumbprint mocks base method. diff --git a/pkg/providers/vsphere/vsphere.go b/pkg/providers/vsphere/vsphere.go index fa960c84ae93..47c6673210b8 100644 --- a/pkg/providers/vsphere/vsphere.go +++ b/pkg/providers/vsphere/vsphere.go @@ -115,7 +115,7 @@ type ProviderGovcClient interface { DatacenterExists(ctx context.Context, datacenter string) (bool, error) NetworkExists(ctx context.Context, network string) (bool, error) CreateLibrary(ctx context.Context, datastore, library string) error - DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, resourcePool string, resizeDisk2 bool) error + DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, network, resourcePool string, resizeDisk2 bool) error ImportTemplate(ctx context.Context, library, ovaURL, name string) error GetTags(ctx context.Context, path string) (tags []string, err error) ListTags(ctx context.Context) ([]string, error) diff --git a/pkg/providers/vsphere/vsphere_test.go b/pkg/providers/vsphere/vsphere_test.go index 4d7daf02e3fe..00706abb988c 100644 --- a/pkg/providers/vsphere/vsphere_test.go +++ b/pkg/providers/vsphere/vsphere_test.go @@ -123,7 +123,7 @@ func (pc *DummyProviderGovcClient) CreateLibrary(ctx context.Context, datastore, return nil } -func (pc *DummyProviderGovcClient) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, resourcePool string, resizeDisk2 bool) error { +func (pc *DummyProviderGovcClient) DeployTemplateFromLibrary(ctx context.Context, templateDir, templateName, library, datacenter, datastore, network, resourcePool string, resizeDisk2 bool) error { return nil }