154 lines
5.1 KiB
Go
154 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
smithy "github.com/aws/smithy-go"
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/cloud/awscloud"
|
|
"github.com/osbuild/osbuild-composer/internal/worker"
|
|
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
|
|
)
|
|
|
|
func getAWS(awsCreds, region string) (*awscloud.AWS, error) {
|
|
if awsCreds != "" {
|
|
return awscloud.NewFromFile(awsCreds, region)
|
|
}
|
|
return awscloud.NewDefault(region)
|
|
}
|
|
|
|
type AWSEC2CopyJobImpl struct {
|
|
AWSCreds string
|
|
}
|
|
|
|
func (impl *AWSEC2CopyJobImpl) Run(job worker.Job) error {
|
|
logWithId := logrus.WithField("jobId", job.Id())
|
|
result := worker.AWSEC2CopyJobResult{}
|
|
|
|
defer func() {
|
|
err := job.Update(&result)
|
|
if err != nil {
|
|
logWithId.Errorf("Error reporting job result: %v", err)
|
|
}
|
|
}()
|
|
|
|
var args worker.AWSEC2CopyJob
|
|
err := job.Args(&args)
|
|
if err != nil {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorParsingJobArgs, fmt.Sprintf("Error parsing arguments: %v", err), nil)
|
|
return err
|
|
}
|
|
|
|
aws, err := getAWS(impl.AWSCreds, args.TargetRegion)
|
|
if err != nil {
|
|
logWithId.Errorf("Error creating aws client: %v", err)
|
|
result.JobError = clienterrors.New(clienterrors.ErrorInvalidConfig, "Invalid worker config", nil)
|
|
return err
|
|
}
|
|
|
|
ami, err := aws.CopyImage(args.TargetName, args.Ami, args.SourceRegion)
|
|
if err != nil {
|
|
logWithId.Errorf("Error copying ami: %v", err)
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Error copying ami %s", args.Ami), nil)
|
|
|
|
var apiErr smithy.APIError
|
|
if errors.As(err, &apiErr) {
|
|
switch apiErr.ErrorCode() {
|
|
case "InvalidRegion":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Invalid source region '%s'", args.SourceRegion), nil)
|
|
case "InvalidAMIID.Malformed":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Malformed source ami id '%s'", args.Ami), nil)
|
|
case "InvalidAMIID.NotFound":
|
|
fallthrough // CopyImage returns InvalidRequest instead of InvalidAMIID.NotFound
|
|
case "InvalidRequest":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Source ami '%s' not found", args.Ami), nil)
|
|
}
|
|
} else {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Unknown error copying ami '%s'", args.Ami), err.Error())
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
result.Ami = ami
|
|
result.Region = args.TargetRegion
|
|
return nil
|
|
}
|
|
|
|
type AWSEC2ShareJobImpl struct {
|
|
AWSCreds string
|
|
}
|
|
|
|
func (impl *AWSEC2ShareJobImpl) Run(job worker.Job) error {
|
|
logWithId := logrus.WithField("jobId", job.Id())
|
|
result := worker.AWSEC2ShareJobResult{}
|
|
|
|
defer func() {
|
|
err := job.Update(&result)
|
|
if err != nil {
|
|
logWithId.Errorf("Error reporting job result: %v", err)
|
|
}
|
|
}()
|
|
|
|
var args worker.AWSEC2ShareJob
|
|
err := job.Args(&args)
|
|
if err != nil {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorParsingJobArgs, fmt.Sprintf("Error parsing arguments: %v", err), nil)
|
|
return err
|
|
}
|
|
|
|
if args.Ami == "" || args.Region == "" {
|
|
if job.NDynamicArgs() != 1 {
|
|
logWithId.Error("No arguments given and dynamic args empty")
|
|
result.JobError = clienterrors.New(clienterrors.ErrorNoDynamicArgs, "An ec2 share job should have args or depend on an ec2 copy job", nil)
|
|
return nil
|
|
}
|
|
var cjResult worker.AWSEC2CopyJobResult
|
|
err = job.DynamicArgs(0, &cjResult)
|
|
if err != nil {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorParsingDynamicArgs, "Error parsing dynamic args as ec2 copy job", nil)
|
|
return err
|
|
}
|
|
if cjResult.JobError != nil {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorJobDependency, "AWSEC2CopyJob dependency failed", nil)
|
|
return nil
|
|
}
|
|
|
|
args.Ami = cjResult.Ami
|
|
args.Region = cjResult.Region
|
|
}
|
|
|
|
aws, err := getAWS(impl.AWSCreds, args.Region)
|
|
if err != nil {
|
|
logWithId.Errorf("Error creating aws client: %v", err)
|
|
result.JobError = clienterrors.New(clienterrors.ErrorInvalidConfig, "Invalid worker config", nil)
|
|
return err
|
|
}
|
|
|
|
err = aws.ShareImage(args.Ami, args.ShareWithAccounts)
|
|
if err != nil {
|
|
logWithId.Errorf("Error sharing image: %v", err)
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Error sharing image with target %v", args.ShareWithAccounts), nil)
|
|
var apiErr smithy.APIError
|
|
if errors.As(err, &apiErr) {
|
|
switch apiErr.ErrorCode() {
|
|
case "InvalidAMIID.Malformed":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Malformed ami id '%s'", args.Ami), nil)
|
|
case "InvalidAMIID.NotFound":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Ami '%s' not found in region '%s'", args.Ami, args.Region), nil)
|
|
case "InvalidAMIAttributeItemValue":
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Invalid user id to share ami with: %v", args.ShareWithAccounts), nil)
|
|
}
|
|
} else {
|
|
result.JobError = clienterrors.New(clienterrors.ErrorSharingTarget, fmt.Sprintf("Unknown error sharing ami '%s' with %v", args.Ami, args.ShareWithAccounts), err.Error())
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
result.Ami = args.Ami
|
|
result.Region = args.Region
|
|
return nil
|
|
}
|