Implement Fargate cluster and client

This commit is contained in:
Onur Filiz
2018-03-28 16:52:42 -07:00
committed by Robbie Zhang
parent 20ceae03f7
commit 64864ffdab
2 changed files with 182 additions and 0 deletions

View 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
}

View 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
}