Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/eks/eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *EKSArgs) (err error) {
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/fedora/fedora.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ func Create(ctx *mc.ContextArgs, args *FedoraArgs) (err error) {
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return err
Expand Down
20 changes: 14 additions & 6 deletions pkg/provider/aws/action/kind/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ type kindRequest struct {
}

func (r *kindRequest) validate() error {
v := validator.New(validator.WithRequiredStructEnabled())
err := v.Var(r.mCtx, "required")
if err != nil {
validate := validator.New()
if err := validate.Struct(r); err != nil {
return err
}
return v.Struct(r)
return nil
}

type KindResultsMetadata struct {
Expand Down Expand Up @@ -89,7 +88,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *KindArgs) (kr *KindResultsMetadata,
&amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -160,6 +160,11 @@ func (r *kindRequest) deploy(ctx *pulumi.Context) error {
// Networking
// LB is required if we use as which is used for spot feature
createLB := r.allocationData.SpotPrice != nil
// For on-demand, we also create LB to be identical to spot
if !createLB {
createLB = true
}

nr := network.NetworkRequest{
Prefix: *r.prefix,
ID: awsKindID,
Expand Down Expand Up @@ -193,6 +198,7 @@ func (r *kindRequest) deploy(ctx *pulumi.Context) error {
if err != nil {
return err
}

// Build LB target groups including both default and extra ports
lbTargetGroups := []int{22, portAPI, portHTTP, portHTTPS}
lbTargetGroups = append(lbTargetGroups, extraHostPorts...)
Expand Down Expand Up @@ -383,6 +389,7 @@ func kubeconfig(ctx *pulumi.Context,
if err != nil {
return pulumi.StringOutput{}, err
}

// Get content for /opt/kubeconfig
getKCCmd := ("cat /home/fedora/kubeconfig")
getKC, err := c.RunCommand(ctx,
Expand All @@ -393,7 +400,8 @@ func kubeconfig(ctx *pulumi.Context,
if err != nil {
return pulumi.StringOutput{}, err
}
kubeconfig := pulumi.All(getKC.Stdout, c.LBEIP.PublicIp).ApplyT(

kubeconfig := pulumi.All(getKC.Stdout, c.GetHostIP(true)).ApplyT(
func(args []interface{}) string {
re := regexp.MustCompile(`https://[^:]+:\d+`)
return re.ReplaceAllString(
Expand Down
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/openshift-snc/openshift-snc.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *OpenshiftSNCArgs) (_ *OpenshiftSncRe
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return nil, err
Expand Down
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/rhel-ai/rhelai.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *RHELAIArgs) (err error) {
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/rhel/rhel.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *RHELArgs) (err error) {
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion pkg/provider/aws/action/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ func Create(mCtxArgs *mc.ContextArgs, args *WindowsServerArgs) (err error) {
&args.Prefix, &amiProduct, nil, args.ComputeRequest)
},
func() (*allocation.AllocationData, error) {
return allocation.AllocationDataOnDemand()
return allocation.AllocationDataOnDemand(mCtx, &args.Prefix,
&amiProduct, nil, args.ComputeRequest)
})
if err != nil {
return err
Expand Down
43 changes: 39 additions & 4 deletions pkg/provider/aws/modules/allocation/allocation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allocation

import (
"fmt"
"os"

mc "github.com/redhat-developer/mapt/pkg/manager/context"
Expand Down Expand Up @@ -57,12 +58,46 @@ func AllocationDataOnSpot(mCtx *mc.Context, prefix, amiProductDescription, amiNa
}, nil
}

func AllocationDataOnDemand() (ad *AllocationData, err error) {
ad = &AllocationData{}
func AllocationDataOnDemand(mCtx *mc.Context, prefix, amiProductDescription, amiName *string, computeRequest *cr.ComputeRequestArgs) (*AllocationData, error) {
var err error
computeTypes := computeRequest.ComputeSizes
if len(computeTypes) == 0 {
computeTypes, err = data.NewComputeSelector().Select(computeRequest)
if err != nil {
return nil, err
}
}

region := os.Getenv("AWS_DEFAULT_REGION")
ad.Region = &region
if region == "" {
region = "us-east-1"
}

ad := &AllocationData{}
ad.AZ, err = data.GetRandomAvailabilityZone(region, nil)
return
if err != nil {
return nil, err
}

availableInstanceTypes, err := data.FilterInstaceTypesOfferedByRegion(computeTypes, region)
if err != nil {
return nil, err
}

// Ensure we have at least one instance type
if len(availableInstanceTypes) == 0 {
return nil, fmt.Errorf("no instance types available in region %s for the specified compute requirements", region)
}

// Note: For on-demand, we don't need to handle AMI name like spot does
// since we're not searching for spot pricing across regions

return &AllocationData{
Region: &region,
AZ: ad.AZ,
SpotPrice: nil, // No spot pricing for on-demand
InstanceTypes: availableInstanceTypes,
}, nil
}

// Calculate a bid price for spot using a increased rate set by user
Expand Down
42 changes: 37 additions & 5 deletions pkg/provider/aws/modules/ec2/compute/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,32 @@ type Compute struct {
func (r *ComputeRequest) NewCompute(ctx *pulumi.Context) (*Compute, error) {
if r.Spot {
asg, err := r.spotInstance(ctx)
if err != nil {
return nil, err
}
return &Compute{
AutoscalingGroup: asg,
LB: r.LB,
LBEIP: r.LBEIP,
Dependencies: []pulumi.Resource{asg, r.LB, r.LBEIP}}, err
}
i, err := r.onDemandInstance(ctx)
return &Compute{Instance: i,
if err != nil {
return nil, err
}
return &Compute{
Instance: i,
LB: r.LB,
LBEIP: r.LBEIP,
Dependencies: []pulumi.Resource{i}}, err
}

// Create on demand instance
func (r *ComputeRequest) onDemandInstance(ctx *pulumi.Context) (*ec2.Instance, error) {
if len(r.InstaceTypes) == 0 {
return nil, fmt.Errorf("no instance types available for on-demand instance")
}

args := ec2.InstanceArgs{
SubnetId: r.Subnet.ID(),
Ami: pulumi.String(r.AMI.Id),
Expand All @@ -108,6 +121,7 @@ func (r *ComputeRequest) onDemandInstance(ctx *pulumi.Context) (*ec2.Instance, e
},
Tags: r.MCtx.ResourceTags(),
}

if r.InstanceProfile != nil {
args.IamInstanceProfile = r.InstanceProfile
}
Expand All @@ -117,14 +131,23 @@ func (r *ComputeRequest) onDemandInstance(ctx *pulumi.Context) (*ec2.Instance, e
if r.Airgap {
args.AssociatePublicIpAddress = pulumi.Bool(false)
}
return ec2.NewInstance(ctx,
resourcesUtil.GetResourceName(r.Prefix, r.ID, "instance"),

instance, err := ec2.NewInstance(ctx,
r.ID, // Use the same ID as spot instances for consistent naming
&args,
pulumi.DependsOn(r.DependsOn))
if err != nil {
return nil, err
}
return instance, nil
}

// create asg with 1 instance forced by spot
func (r ComputeRequest) spotInstance(ctx *pulumi.Context) (*autoscaling.Group, error) {
if len(r.InstaceTypes) == 0 {
return nil, fmt.Errorf("no instance types available for spot instance")
}

// Logging information
r.Subnet.AvailabilityZone.ApplyT(func(az string) error {
logging.Debugf("Requesting a spot instance of types: %s at %s paying: %f",
Expand Down Expand Up @@ -254,7 +277,11 @@ func (c *Compute) GetHostIP(public bool) (ip pulumi.StringInput) {
if c.LBEIP != nil {
return c.LBEIP.PublicIp
}
return c.LB.DnsName
if c.LB != nil {
return c.LB.DnsName
}
// Fallback to empty string if neither LB nor LBEIP is available
return pulumi.String("")
}

// Check if compute is healthy based on running a remote cmd
Expand Down Expand Up @@ -294,14 +321,19 @@ func (compute *Compute) RunCommand(ctx *pulumi.Context,
if !loggingCmdStd {
ca.Logging = remote.LoggingNone
}
return remote.NewCommand(ctx,

remoteCmd, err := remote.NewCommand(ctx,
resourcesUtil.GetResourceName(prefix, id, "cmd"),
ca,
pulumi.Timeouts(
&pulumi.CustomTimeouts{
Create: command.RemoteTimeout,
Update: command.RemoteTimeout}),
pulumi.DependsOn(dependecies))
if err != nil {
return nil, err
}
return remoteCmd, nil
}

// helper function to set the connection args
Expand Down
10 changes: 7 additions & 3 deletions pkg/provider/aws/modules/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (r *NetworkRequest) Network(ctx *pulumi.Context, mCtx *mc.Context) (
b, err = br.Create(ctx, mCtx)
}
if r.CreateLoadBalancer != nil && *r.CreateLoadBalancer {
lb, lbEIP, err = r.createLoadBalancer(ctx, targetSubnet)
lb, lbEIP, err = r.createLoadBalancer(ctx, targetSubnet, mCtx)
}
return
}
Expand Down Expand Up @@ -119,10 +119,12 @@ func (r *NetworkRequest) manageAirgapNetworking(ctx *pulumi.Context, mCtx *mc.Co
}

func (r *NetworkRequest) createLoadBalancer(ctx *pulumi.Context,
subnet *ec2.Subnet) (*lb.LoadBalancer, *ec2.Eip, error) {
subnet *ec2.Subnet,
mCtx *mc.Context) (*lb.LoadBalancer, *ec2.Eip, error) {
lbArgs := &lb.LoadBalancerArgs{
LoadBalancerType: pulumi.String("network"),
EnableDeletionProtection: pulumi.Bool(false),
Tags: mCtx.ResourceTags(),
}
snMapping := &lb.LoadBalancerSubnetMappingArgs{
SubnetId: subnet.ID()}
Expand All @@ -139,7 +141,9 @@ func (r *NetworkRequest) createLoadBalancer(ctx *pulumi.Context,
// It load balancer is public facing
lbEIP, err = ec2.NewEip(ctx,
resourcesUtil.GetResourceName(r.Prefix, r.ID, "lbeip"),
&ec2.EipArgs{})
&ec2.EipArgs{
Tags: mCtx.ResourceTags(),
})
if err != nil {
return nil, nil, err
}
Expand Down