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