cloudapi: split GetTarget() into functions

Separate the handling of each individual target type into its own
function called by GetTarget()'s case switch.  This makes the function
more readable and the target object creation reusable.

Added an empty line after each creation of irTarget to make it easier to
visually distinguish the cases that fall through.
This commit is contained in:
Achilleas Koutsou 2023-10-13 18:46:26 +02:00 committed by Sanne Raymaekers
parent 27beb73365
commit b011b9845a

View file

@ -36,9 +36,193 @@ func (ir *ImageRequest) GetImageOptions(imageType distro.ImageType, bp blueprint
return distro.ImageOptions{Size: size, PartitioningMode: disk.AutoLVMPartitioningMode}
}
func newAWSTarget(ir *ImageRequest, imageType distro.ImageType) (*target.Target, error) {
var awsUploadOptions AWSEC2UploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &awsUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
// For service maintenance, images are discovered by the "Name:composer-api-*"
// tag filter. Currently all image names in the service are generated, so they're
// guaranteed to be unique as well. If users are ever allowed to name their images,
// an extra tag should be added.
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
var amiBootMode *string
switch imageType.BootMode() {
case distro.BOOT_HYBRID:
amiBootMode = common.ToPtr(ec2.BootModeValuesUefiPreferred)
case distro.BOOT_UEFI:
amiBootMode = common.ToPtr(ec2.BootModeValuesUefi)
case distro.BOOT_LEGACY:
amiBootMode = common.ToPtr(ec2.BootModeValuesLegacyBios)
}
t := target.NewAWSTarget(&target.AWSTargetOptions{
Region: awsUploadOptions.Region,
Key: key,
ShareWithAccounts: awsUploadOptions.ShareWithAccounts,
BootMode: amiBootMode,
})
if awsUploadOptions.SnapshotName != nil {
t.ImageName = *awsUploadOptions.SnapshotName
} else {
t.ImageName = key
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
func newAWSS3Target(ir *ImageRequest, imageType distro.ImageType) (*target.Target, error) {
var awsS3UploadOptions AWSS3UploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &awsS3UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
public := false
if awsS3UploadOptions.Public != nil && *awsS3UploadOptions.Public {
public = true
}
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
t := target.NewAWSS3Target(&target.AWSS3TargetOptions{
Region: awsS3UploadOptions.Region,
Key: key,
Public: public,
})
t.ImageName = key
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
func newContainerTarget(ir *ImageRequest, request *ComposeRequest, imageType distro.ImageType) (*target.Target, error) {
var containerUploadOptions ContainerUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &containerUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
var name = request.Distribution
var tag = uuid.New().String()
if containerUploadOptions.Name != nil {
name = *containerUploadOptions.Name
if containerUploadOptions.Tag != nil {
tag = *containerUploadOptions.Tag
}
}
t := target.NewContainerTarget(&target.ContainerTargetOptions{})
t.ImageName = fmt.Sprintf("%s:%s", name, tag)
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
func newGCPTarget(ir *ImageRequest, imageType distro.ImageType) (*target.Target, error) {
var gcpUploadOptions GCPUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &gcpUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
var share []string
if gcpUploadOptions.ShareWithAccounts != nil {
share = *gcpUploadOptions.ShareWithAccounts
}
imageName := fmt.Sprintf("composer-api-%s", uuid.New().String())
var bucket string
if gcpUploadOptions.Bucket != nil {
bucket = *gcpUploadOptions.Bucket
}
t := target.NewGCPTarget(&target.GCPTargetOptions{
Region: gcpUploadOptions.Region,
Os: imageType.Arch().Distro().Name(), // not exposed in cloudapi
Bucket: bucket,
// the uploaded object must have a valid extension
Object: fmt.Sprintf("%s.tar.gz", imageName),
ShareWithAccounts: share,
})
// Import will fail if an image with this name already exists
if gcpUploadOptions.ImageName != nil {
t.ImageName = *gcpUploadOptions.ImageName
} else {
t.ImageName = imageName
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
func newAzureTarget(ir *ImageRequest, imageType distro.ImageType) (*target.Target, error) {
var azureUploadOptions AzureUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &azureUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
rgLocation := ""
if azureUploadOptions.Location != nil {
rgLocation = *azureUploadOptions.Location
}
t := target.NewAzureImageTarget(&target.AzureImageTargetOptions{
TenantID: azureUploadOptions.TenantId,
Location: rgLocation,
SubscriptionID: azureUploadOptions.SubscriptionId,
ResourceGroup: azureUploadOptions.ResourceGroup,
})
if azureUploadOptions.ImageName != nil {
t.ImageName = *azureUploadOptions.ImageName
} else {
// if ImageName wasn't given, generate a random one
t.ImageName = fmt.Sprintf("composer-api-%s", uuid.New().String())
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
func newOCITarget(ir *ImageRequest, imageType distro.ImageType) (*target.Target, error) {
var ociUploadOptions OCIUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &ociUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
t := target.NewOCIObjectStorageTarget(&target.OCIObjectStorageTargetOptions{})
t.ImageName = key
t.OsbuildArtifact.ExportFilename = imageType.Filename()
return t, nil
}
// GetImageTarget returns the target for the selected image type
func (ir *ImageRequest) GetTarget(request *ComposeRequest, imageType distro.ImageType) (irTarget *target.Target, err error) {
/* oneOf is not supported by the openapi generator so marshal and unmarshal the uploadrequest based on the type */
// oneOf is not supported by the openapi generator so marshal and unmarshal the uploadrequest based on the type
switch ir.ImageType {
case ImageTypesAws:
fallthrough
@ -47,46 +231,8 @@ func (ir *ImageRequest) GetTarget(request *ComposeRequest, imageType distro.Imag
case ImageTypesAwsHaRhui:
fallthrough
case ImageTypesAwsSapRhui:
var awsUploadOptions AWSEC2UploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &awsUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
irTarget, err = newAWSTarget(ir, imageType)
// For service maintenance, images are discovered by the "Name:composer-api-*"
// tag filter. Currently all image names in the service are generated, so they're
// guaranteed to be unique as well. If users are ever allowed to name their images,
// an extra tag should be added.
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
var amiBootMode *string
switch imageType.BootMode() {
case distro.BOOT_HYBRID:
amiBootMode = common.ToPtr(ec2.BootModeValuesUefiPreferred)
case distro.BOOT_UEFI:
amiBootMode = common.ToPtr(ec2.BootModeValuesUefi)
case distro.BOOT_LEGACY:
amiBootMode = common.ToPtr(ec2.BootModeValuesLegacyBios)
}
t := target.NewAWSTarget(&target.AWSTargetOptions{
Region: awsUploadOptions.Region,
Key: key,
ShareWithAccounts: awsUploadOptions.ShareWithAccounts,
BootMode: amiBootMode,
})
if awsUploadOptions.SnapshotName != nil {
t.ImageName = *awsUploadOptions.SnapshotName
} else {
t.ImageName = key
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
case ImageTypesGuestImage:
fallthrough
case ImageTypesVsphere:
@ -108,98 +254,18 @@ func (ir *ImageRequest) GetTarget(request *ComposeRequest, imageType distro.Imag
case ImageTypesIotCommit:
fallthrough
case ImageTypesIotRawImage:
var awsS3UploadOptions AWSS3UploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &awsS3UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
irTarget, err = newAWSS3Target(ir, imageType)
public := false
if awsS3UploadOptions.Public != nil && *awsS3UploadOptions.Public {
public = true
}
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
t := target.NewAWSS3Target(&target.AWSS3TargetOptions{
Region: awsS3UploadOptions.Region,
Key: key,
Public: public,
})
t.ImageName = key
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
case ImageTypesEdgeContainer:
fallthrough
case ImageTypesIotContainer:
var containerUploadOptions ContainerUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &containerUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
irTarget, err = newContainerTarget(ir, request, imageType)
var name = request.Distribution
var tag = uuid.New().String()
if containerUploadOptions.Name != nil {
name = *containerUploadOptions.Name
if containerUploadOptions.Tag != nil {
tag = *containerUploadOptions.Tag
}
}
t := target.NewContainerTarget(&target.ContainerTargetOptions{})
t.ImageName = fmt.Sprintf("%s:%s", name, tag)
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
case ImageTypesGcp:
fallthrough
case ImageTypesGcpRhui:
var gcpUploadOptions GCPUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &gcpUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
irTarget, err = newGCPTarget(ir, imageType)
var share []string
if gcpUploadOptions.ShareWithAccounts != nil {
share = *gcpUploadOptions.ShareWithAccounts
}
imageName := fmt.Sprintf("composer-api-%s", uuid.New().String())
var bucket string
if gcpUploadOptions.Bucket != nil {
bucket = *gcpUploadOptions.Bucket
}
t := target.NewGCPTarget(&target.GCPTargetOptions{
Region: gcpUploadOptions.Region,
Os: imageType.Arch().Distro().Name(), // not exposed in cloudapi
Bucket: bucket,
// the uploaded object must have a valid extension
Object: fmt.Sprintf("%s.tar.gz", imageName),
ShareWithAccounts: share,
})
// Import will fail if an image with this name already exists
if gcpUploadOptions.ImageName != nil {
t.ImageName = *gcpUploadOptions.ImageName
} else {
t.ImageName = imageName
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
case ImageTypesAzure:
fallthrough
case ImageTypesAzureRhui:
@ -207,54 +273,17 @@ func (ir *ImageRequest) GetTarget(request *ComposeRequest, imageType distro.Imag
case ImageTypesAzureEap7Rhui:
fallthrough
case ImageTypesAzureSapRhui:
var azureUploadOptions AzureUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &azureUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
rgLocation := ""
if azureUploadOptions.Location != nil {
rgLocation = *azureUploadOptions.Location
}
t := target.NewAzureImageTarget(&target.AzureImageTargetOptions{
TenantID: azureUploadOptions.TenantId,
Location: rgLocation,
SubscriptionID: azureUploadOptions.SubscriptionId,
ResourceGroup: azureUploadOptions.ResourceGroup,
})
irTarget, err = newAzureTarget(ir, imageType)
if azureUploadOptions.ImageName != nil {
t.ImageName = *azureUploadOptions.ImageName
} else {
// if ImageName wasn't given, generate a random one
t.ImageName = fmt.Sprintf("composer-api-%s", uuid.New().String())
}
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
case ImageTypesOci:
var ociUploadOptions OCIUploadOptions
jsonUploadOptions, err := json.Marshal(*ir.UploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONMarshallingError)
}
err = json.Unmarshal(jsonUploadOptions, &ociUploadOptions)
if err != nil {
return nil, HTTPError(ErrorJSONUnMarshallingError)
}
irTarget, err = newOCITarget(ir, imageType)
key := fmt.Sprintf("composer-api-%s", uuid.New().String())
t := target.NewOCIObjectStorageTarget(&target.OCIObjectStorageTargetOptions{})
t.ImageName = key
t.OsbuildArtifact.ExportFilename = imageType.Filename()
irTarget = t
default:
return nil, HTTPError(ErrorUnsupportedImageType)
}
if err != nil {
return nil, err
}
irTarget.OsbuildArtifact.ExportName = imageType.Exports()[0]
return irTarget, nil