diff --git a/api/openapi.gen.json b/api/openapi.gen.json index bdc705e6..7c6ae716 100644 --- a/api/openapi.gen.json +++ b/api/openapi.gen.json @@ -684,6 +684,7 @@ "type": "string" }, "name": { + "description": "Name of the instance, to keep names unique, it will be suffixed with UUID. Optional, defaults to 'redhat-vm''", "type": "string" }, "poweroff": { diff --git a/api/openapi.gen.yaml b/api/openapi.gen.yaml index 515ce01c..15fb3cc5 100644 --- a/api/openapi.gen.yaml +++ b/api/openapi.gen.yaml @@ -98,6 +98,7 @@ components: description: Location (also known as region) to deploy the VM into, be aware it needs to be the same as the image location. Defaults to the Resource Group location, or 'eastus' when also creating the resource group. name: type: string + description: Name of the instance, to keep names unique, it will be suffixed with UUID. Optional, defaults to 'redhat-vm'' poweroff: type: boolean pubkey_id: diff --git a/internal/jobs/launch_instance_azure.go b/internal/jobs/launch_instance_azure.go index bd061ada..465589a0 100644 --- a/internal/jobs/launch_instance_azure.go +++ b/internal/jobs/launch_instance_azure.go @@ -23,7 +23,7 @@ import ( const ( DefaultAzureResourceGroupName = "redhat-deployed" location = "eastus" - vmNamePrefix = "redhat-vm" + DefaultVMName = "redhat-vm" ) var LaunchInstanceAzureSteps = []string{"Prepare resource group", "Launch instance(s)"} @@ -49,6 +49,9 @@ type LaunchInstanceAzureTaskArgs struct { // The Subscription fetched from Sources which is linked to a specific source Subscription *clients.Authentication + + // The Name is used as prefix for a final name, for uniqueness we add uuid suffix to each instance name + Name string } func HandleLaunchInstanceAzure(ctx context.Context, job *worker.Job) { @@ -82,6 +85,9 @@ func HandleLaunchInstanceAzure(ctx context.Context, job *worker.Job) { args.Location = args.Location[0 : len(args.Location)-2] } } + if args.Name == "" { + args.Name = DefaultVMName + } // ensure panic finishes the job defer func() { @@ -195,7 +201,7 @@ func DoLaunchInstanceAzure(ctx context.Context, args *LaunchInstanceAzureTaskArg }, } - instanceDescriptions, err := azureClient.CreateVMs(ctx, vmParams, reservation.Detail.Amount, vmNamePrefix) + instanceDescriptions, err := azureClient.CreateVMs(ctx, vmParams, reservation.Detail.Amount, args.Name) if err != nil { span.SetStatus(codes.Error, "failed to create instances") return fmt.Errorf("cannot create Azure instance: %w", err) diff --git a/internal/payloads/reservation_payload.go b/internal/payloads/reservation_payload.go index 3ea48e0a..1427d6db 100644 --- a/internal/payloads/reservation_payload.go +++ b/internal/payloads/reservation_payload.go @@ -97,8 +97,9 @@ type AzureReservationResponse struct { ResourceGroup string `json:"resource_group" yaml:"resource_group"` - // Azure Location. - Location string `json:"location" yaml:"location"` + // Azure Location. Included only if it was explicitly passed by User. + // If it was induced from Resource Group, it will be empty and thus not included in response. + Location string `json:"location,omitempty" yaml:"location,omitempty"` // Azure Instance size. InstanceSize string `json:"instance_size" yaml:"instance_size"` @@ -211,8 +212,8 @@ type AzureReservationRequest struct { // Amount of instances to provision of size: InstanceSize. Amount int64 `json:"amount" yaml:"amount"` - // Name of the instance(s). - Name string `json:"name" yaml:"name"` + // Name of the instance(s). Defaults to redhat-vm. + Name string `json:"name" yaml:"name" description:"Name of the instance, to keep names unique, it will be suffixed with UUID. Optional, defaults to 'redhat-vm''"` // Immediately power off the system after initialization. PowerOff bool `json:"poweroff" yaml:"poweroff"` diff --git a/internal/services/azure_reservation_service.go b/internal/services/azure_reservation_service.go index b8c21d80..d9d56e7d 100644 --- a/internal/services/azure_reservation_service.go +++ b/internal/services/azure_reservation_service.go @@ -167,6 +167,7 @@ func CreateAzureReservation(w http.ResponseWriter, r *http.Request) { SourceID: reservation.SourceID, AzureImageID: azureImageName, Subscription: authentication, + Name: name, }, } diff --git a/internal/services/azure_reservation_service_test.go b/internal/services/azure_reservation_service_test.go index 5d0df08f..36d78a1b 100644 --- a/internal/services/azure_reservation_service_test.go +++ b/internal/services/azure_reservation_service_test.go @@ -12,6 +12,7 @@ import ( "github.com/RHEnVision/provisioning-backend/internal/dao/stubs" "github.com/RHEnVision/provisioning-backend/internal/jobs" "github.com/RHEnVision/provisioning-backend/internal/models" + "github.com/RHEnVision/provisioning-backend/internal/payloads" "github.com/RHEnVision/provisioning-backend/internal/queue/stub" "github.com/RHEnVision/provisioning-backend/internal/services" "github.com/RHEnVision/provisioning-backend/internal/testing/factories" @@ -40,6 +41,7 @@ func TestCreateAzureReservationHandler(t *testing.T) { var err error values := map[string]interface{}{ + "name": "azureVM", "source_id": source.ID, "image_id": "92ea98f8-7697-472e-80b1-7454fa0e7fa7", "resource_group": "testGroup", @@ -60,6 +62,11 @@ func TestCreateAzureReservationHandler(t *testing.T) { handler.ServeHTTP(rr, req) require.Equal(t, http.StatusOK, rr.Code, "Handler returned wrong status code") + response := payloads.AzureReservationResponse{} + err = json.Unmarshal(rr.Body.Bytes(), &response) + require.NoError(t, err, "failed to parse the response body") + + assert.Equal(t, "azureVM", response.Name) stubCount := stubs.AzureReservationStubCount(ctx) assert.Equal(t, 1, stubCount, "Reservation has not been Created through DAO") @@ -68,6 +75,7 @@ func TestCreateAzureReservationHandler(t *testing.T) { assert.IsType(t, jobs.LaunchInstanceAzureTaskArgs{}, stub.EnqueuedJobs(ctx)[0].Args, "Unexpected type of arguments for the planned job") jobArgs := stub.EnqueuedJobs(ctx)[0].Args.(jobs.LaunchInstanceAzureTaskArgs) assert.Equal(t, "testGroup", jobArgs.ResourceGroupName) + assert.Equal(t, "azureVM", jobArgs.Name) assert.Equal(t, "/subscriptions/4b9d213f-712f-4d17-a483-8a10bbe9df3a/resourceGroups/myTestGroup/providers/Microsoft.Compute/images/composer-api-92ea98f8-7697-472e-80b1-7454fa0e7fa7", jobArgs.AzureImageID, "Expected translated image to real name - one from IB client stub") })