Skip to content

Commit

Permalink
Support AWS, implement dry-run and quiet modes
Browse files Browse the repository at this point in the history
  • Loading branch information
bpineau committed Mar 15, 2018
1 parent dadf8c0 commit b8d5ec2
Show file tree
Hide file tree
Showing 10 changed files with 518 additions and 29 deletions.
102 changes: 94 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,103 @@
# cloud-floating-ip

NOT YET READY.
Implement a floating IP by modifying GCP or AWS routes.

Implement a floating IP by modifying GCE or AWS routes.
## Usage

## Build
All ec2/gce instances that may carry the floating IP (become "primary")
should be allowed to route traffic: SourceDestCheck (EC2) or canIpForward
(GCE) must be enabled.

Assuming you have go 1.9 and glide in the path, and GOPATH configured:
Those instances should accept the traffic to the floating IP. The IP may
be assigned to a loopback or a dummy interface on all instances:

```shell
make deps
make build
```bash
ip link add dummy0 type dummy
ip address add 10.200.0.50/32 dev dummy0
```

## Usage
To route the floating IP to the current instance (which becomes "primary"):
```bash
# see what would be changed
cloud-floating-ip -i 10.200.0.50 --dry-run preempt

# apply the change
cloud-floating-ip -i 10.200.0.50 preempt
```

The IP can be preempted, using the same `preempt` command, by other
instances in the VPC.

To verify the status ("primary" or "standby") of any instance:
```bash
cloud-floating-ip -i 10.200.0.50 status
```

To store the configuration (avoid those repetitive `-i ...` arguments):
```bash
cat<<EOF > /etc/cloud-floating-ip.yaml
ip: 10.200.0.50
quiet: true
EOF
```

## Options

The --ip argument is mandatory. Other settings can be collected from
instance's metadata (and instance profile or service account) when
running from an AWS or GCE instance.


```
Usage:
cloud-floating-ip [flags]
cloud-floating-ip [command]
Available Commands:
destroy Delete the routes managed by cloud-floating-ip
help Help about any command
preempt Preempt an IP address and route it to the instance
status Display the status of the instance (owner or standby)
Flags:
-c, --config string config file (default is /etc/cloud-floating-ip.yaml)
-i, --ip string IP address
-d, --dry-run dry-run mode
-q, --quiet quiet mode
-h, --help help for cloud-floating-ip
-o, --hoster string hosting provider (aws or gce)
-t, --instance string instance name
-m, --ignore-main-table (AWS) ignore routes in main table
-a, --aws-access-key-id string (AWS) access key Id
-k, --aws-secret-key string (AWS) secret key
-p, --project string (GCP) project id
-r, --region string (AWS) region name
-z, --zone string (GCP) zone name
```

## Required privileges

On EC2, the account running `cloud-floating-ip` must have the following rights:
```
ec2:DescribeInstances
ec2:CreateRoute
ec2:DescribeRouteTables
ec2:ReplaceRoute
ec2:DeleteRoute
```

On GCE:
```
compute.routes.get
compute.routes.create
compute.routes.delete
compute.instances.get
container.operations.get
container.operations.list
```

## Limitations

* `cloud-floating-ip` does not support instances with multiple interfaces in the VPC yet.
* On GCE, `cloud-floating-ip` won't remove already created, pre-existing routes with a custom name

4 changes: 2 additions & 2 deletions cmd/preempt.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

var preemptCmd = &cobra.Command{
Use: "preempt",
Short: "Preempt an IP address and route it to an instanced",
Long: `Preempt an IP address and route it to an instance`,
Short: "Preempt an IP address and route it to the instance",
Long: `Preempt an IP address and route it to the instance`,
Run: func(cmd *cobra.Command, args []string) {
run.Run(newCfiConfig(), operation.CfiPreempt)
},
Expand Down
26 changes: 18 additions & 8 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ var (
dryrun bool
quiet bool
project string
region string
zone string
nomain bool
accessk string
secretk string
)
Expand All @@ -35,7 +37,9 @@ func newCfiConfig() *config.CfiConfig {
DryRun: viper.GetBool("dry-run"),
Quiet: viper.GetBool("quiet"),
Project: viper.GetString("project"),
Region: viper.GetString("region"),
Zone: viper.GetString("zone"),
NoMain: viper.GetBool("ignore-main-table"),
AwsAccesKeyID: viper.GetString("aws-access-key-id"),
AwsSecretKey: viper.GetString("aws-secret-key"),
}
Expand All @@ -56,8 +60,8 @@ var rootCmd = &cobra.Command{
Use: "cloud-floating-ip",
Short: "Implement a floating IP by modifying GCE or AWS routes.",
Long: `Implement a floating IP by modifying GCE or AWS routes.
Most of the arguments (except the floating IP address) can be guessed from
instance's metadata (when running from an AWS or GCE instance).
The --ip argument is mandatory. Other settings can be guessed from
instance's metadata when running from an AWS or GCE instance.
`,
Run: func(cmd *cobra.Command, args []string) {
run.Run(newCfiConfig(), operation.CfiStatus)
Expand Down Expand Up @@ -100,17 +104,23 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&quiet, "quiet", "q", false, "quiet mode")
bindPFlag("quiet", "quiet")

rootCmd.PersistentFlags().StringVarP(&project, "project", "p", "", "GCP project id")
rootCmd.PersistentFlags().StringVarP(&project, "project", "p", "", "(GCP) project id")
bindPFlag("project", "project")

rootCmd.PersistentFlags().StringVarP(&zone, "zone", "z", "", "zone name")
rootCmd.PersistentFlags().StringVarP(&region, "region", "r", "", "(AWS) region name")
bindPFlag("region", "region")

rootCmd.PersistentFlags().StringVarP(&zone, "zone", "z", "", "(GCP) zone name")
bindPFlag("zone", "zone")

rootCmd.PersistentFlags().StringVarP(&accessk, "aws-access-key-id", "a", "", "AWS access key Id")
bindPFlag("accessk", "accessk")
rootCmd.PersistentFlags().BoolVarP(&nomain, "ignore-main-table", "m", false, "(AWS) ignore routes in main table")
bindPFlag("ignore-main-table", "ignore-main-table")

rootCmd.PersistentFlags().StringVarP(&accessk, "aws-access-key-id", "a", "", "(AWS) access key Id")
bindPFlag("aws-access-key-id", "aws-access-key-id")

rootCmd.PersistentFlags().StringVarP(&secretk, "aws-secret-key", "k", "", "AWS secret key")
bindPFlag("secretk", "secretk")
rootCmd.PersistentFlags().StringVarP(&secretk, "aws-secret-key", "k", "", "(AWS) secret key")
bindPFlag("aws-secret-key", "aws-secret-key")
}

// initConfig reads in config file and ENV variables if set.
Expand Down
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ type CfiConfig struct {
// Zone is the AWS or GCP zone of the target instance
Zone string

// Region is the AWS region
Region string

// Ignore tables associated with the main route table
NoMain bool

// AwsAccesKeyID (AWS only) is the acccess key to use (if we don't use an instance profile's role)
AwsAccesKeyID string

Expand Down
59 changes: 57 additions & 2 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ import:
- package: google.golang.org/api
subpackages:
- compute/v0.beta
- package: github.com/aws/aws-sdk-go
version: ^1.13.11
Loading

0 comments on commit b8d5ec2

Please sign in to comment.