Implement Fargate cluster and client
This commit is contained in:
48
providers/aws/fargate/client.go
Normal file
48
providers/aws/fargate/client.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package fargate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ecs"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client communicates with the regional AWS Fargate service.
|
||||||
|
type Client struct {
|
||||||
|
region string
|
||||||
|
svc *ecs.ECS
|
||||||
|
api ecsiface.ECSAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
var client *Client
|
||||||
|
|
||||||
|
// NewClient creates a new Fargate client in the given region.
|
||||||
|
func newClient(region string) (*Client, error) {
|
||||||
|
var client Client
|
||||||
|
|
||||||
|
// Initialize client session configuration.
|
||||||
|
config := aws.NewConfig()
|
||||||
|
config.Region = aws.String(region)
|
||||||
|
|
||||||
|
session, err := session.NewSessionWithOptions(
|
||||||
|
session.Options{
|
||||||
|
Config: *config,
|
||||||
|
SharedConfigState: session.SharedConfigEnable,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Fargate service client.
|
||||||
|
client.region = region
|
||||||
|
client.svc = ecs.New(session)
|
||||||
|
client.api = client.svc
|
||||||
|
|
||||||
|
log.Println("Created Fargate service client.")
|
||||||
|
|
||||||
|
return &client, nil
|
||||||
|
}
|
||||||
134
providers/aws/fargate/cluster.go
Normal file
134
providers/aws/fargate/cluster.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user