135 lines
3.4 KiB
Go
135 lines
3.4 KiB
Go
package fargate
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/service/ecs"
|
|
)
|
|
|
|
// ClusterConfig contains a Fargate cluster's configurable parameters.
|
|
type ClusterConfig struct {
|
|
Region string
|
|
Name string
|
|
NodeName string
|
|
Subnets []string
|
|
SecurityGroups []string
|
|
AssignPublicIPv4Address bool
|
|
PlatformVersion string
|
|
}
|
|
|
|
// Cluster represents a Fargate cluster.
|
|
type Cluster struct {
|
|
region string
|
|
name string
|
|
nodeName string
|
|
arn string
|
|
subnets []string
|
|
securityGroups []string
|
|
assignPublicIPv4Address bool
|
|
platformVersion string
|
|
sync.RWMutex
|
|
}
|
|
|
|
// NewCluster creates a new Cluster object.
|
|
func NewCluster(config *ClusterConfig) (*Cluster, error) {
|
|
var err error
|
|
|
|
// Cluster name cannot contain '_' as it is used as a separator in task tags.
|
|
if strings.Contains(config.Name, "_") {
|
|
return nil, fmt.Errorf("cluster name should not contain the '_' character")
|
|
}
|
|
|
|
// Check if Fargate is available in the given region.
|
|
if !FargateRegions.Include(config.Region) {
|
|
return nil, fmt.Errorf("Fargate is not available in region %s", config.Region)
|
|
}
|
|
|
|
// Create the client to the regional Fargate service.
|
|
client, err = newClient(config.Region)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create Fargate client: %v", err)
|
|
}
|
|
|
|
// Initialize the cluster.
|
|
cluster := &Cluster{
|
|
region: config.Region,
|
|
name: config.Name,
|
|
nodeName: config.NodeName,
|
|
subnets: config.Subnets,
|
|
securityGroups: config.SecurityGroups,
|
|
assignPublicIPv4Address: config.AssignPublicIPv4Address,
|
|
platformVersion: config.PlatformVersion,
|
|
}
|
|
|
|
// Check if the cluster already exists.
|
|
err = cluster.describe()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If not, try to create it.
|
|
// This might fail if the role doesn't have the necessary permission.
|
|
if cluster.arn == "" {
|
|
err = cluster.create()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return cluster, nil
|
|
}
|
|
|
|
// Create creates a new Fargate cluster.
|
|
func (c *Cluster) create() error {
|
|
api := client.api
|
|
|
|
input := &ecs.CreateClusterInput{
|
|
ClusterName: aws.String(c.name),
|
|
}
|
|
|
|
log.Printf("Creating Fargate cluster %s in region %s", c.name, c.region)
|
|
|
|
output, err := api.CreateCluster(input)
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to create cluster: %v", err)
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
|
|
c.arn = *output.Cluster.ClusterArn
|
|
log.Printf("Created Fargate cluster %s in region %s", c.name, c.region)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Describe loads information from an existing Fargate cluster.
|
|
func (c *Cluster) describe() error {
|
|
api := client.api
|
|
|
|
input := &ecs.DescribeClustersInput{
|
|
Clusters: aws.StringSlice([]string{c.name}),
|
|
}
|
|
|
|
log.Printf("Looking for Fargate cluster %s in region %s.", c.name, c.region)
|
|
|
|
output, err := api.DescribeClusters(input)
|
|
if err != nil || len(output.Clusters) > 1 {
|
|
err = fmt.Errorf("failed to describe cluster: %v", err)
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
|
|
if len(output.Clusters) == 0 {
|
|
log.Printf("Fargate cluster %s in region %s does not exist.", c.name, c.region)
|
|
} else {
|
|
log.Printf("Found Fargate cluster %s in region %s.", c.name, c.region)
|
|
c.arn = *output.Clusters[0].ClusterArn
|
|
}
|
|
|
|
return nil
|
|
}
|