-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6c82a0f
Showing
28 changed files
with
2,809 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cli53 | ||
vendor/ | ||
.stfolder | ||
cli53.sublime-project | ||
release/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
language: go | ||
go: | ||
- 1.5 | ||
sudo: required | ||
before_script: | ||
- sudo apt-get -y install upx-ucl | ||
script: | ||
- make test | ||
after_success: | ||
- make release | ||
deploy: | ||
provider: releases | ||
api_key: | ||
secure: nmqbnVuj7XpuUMs5YmB2X+/Dkq5I2hoWaIUSO5Okse7D8iYW0fWPeqR5xMy3ctSlHJgNarMx3qPJZmr+lJAuwT7xZhvW2kFOJE7Ra/nJgLtuWOMu4zrJ2cLNYTgE4fN3jag5VkgnuB4Ax57QZESssWKLvyBVA7ePaV/HXe1hX7k= | ||
file: | ||
- release/cli53-linux-386 | ||
- release/cli53-linux-amd64 | ||
- release/cli53-linux-arm | ||
- release/cli53-mac-amd64 | ||
- release/cli53-windows-386.exe | ||
- release/cli53-windows-amd64.exe | ||
on: | ||
repo: barnybug/cli53 | ||
tags: true | ||
env: | ||
global: | ||
- secure: "M6bUhLlefRqTAfbVfQd2/j4/4CsifJqKQ6Szz2G5RTI0ADrbdNnS0m3SqTdk\nsbp/4cgwaQM+sgnISW2alDaGP+1PmkyXGyftZdLHM1NuGca8/yKVWy/vLW3e\nv++AiYPFLTRxoiZJ9j0bdHjGOffCMvotZhtc9xv0VXVijGdHiIM=" | ||
- secure: "lnku5GaQtu8MLapFboAAsUzm2kYm+lVoshaJPmtod0gERoxiwaOUMMkY9Muq\nrezBxXy7dvHdDEEMoU0zelpJYfpxV6ql1vPjxgusVA6KouTTl1rTV3GfP0z7\nqUylHf1RqwYWNL0DkBURG44npnfkTT+F97qcq0kCCUAlLjAoyJg=" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
export GO15VENDOREXPERIMENT=1 | ||
|
||
exe = ./cmd/cli53 | ||
buildargs = -ldflags '-X github.com/barnybug/cli53.version=${TRAVIS_BRANCH}' | ||
|
||
.PHONY: all build install test coverage deps release | ||
|
||
all: install | ||
|
||
build: | ||
go build $(exe) | ||
|
||
install: | ||
go install $(exe) | ||
|
||
release: | ||
GOOS=linux GOARCH=386 go build $(buildargs) -o release/cli53-linux-386 $(exe) | ||
GOOS=linux GOARCH=amd64 go build $(buildargs) -o release/cli53-linux-amd64 $(exe) | ||
GOOS=linux GOARCH=arm go build $(buildargs) -o release/cli53-linux-arm $(exe) | ||
GOOS=darwin GOARCH=amd64 go build $(buildargs) -o release/cli53-mac-amd64 $(exe) | ||
GOOS=windows GOARCH=386 go build $(buildargs) -o release/cli53-windows-386.exe $(exe) | ||
GOOS=windows GOARCH=amd64 go build $(buildargs) -o release/cli53-windows-amd64.exe $(exe) | ||
goupx release/cli53-linux-amd64 | ||
upx release/cli53-linux-386 release/cli53-linux-arm release/cli53-windows-386.exe release/cli53-windows-amd64.exe | ||
|
||
test-unit: | ||
go test . | ||
|
||
test-integration: build | ||
gucumber | ||
|
||
test: test-unit test-integration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
[](https://secure.travis-ci.org/barnybug/cli53) | ||
|
||
# cli53 - Command line tool to administer the Amazon Route 53 DNS service | ||
|
||
## Introduction | ||
|
||
cli53 provides import and export from BIND format and simple command line management of | ||
Route 53 domains. | ||
|
||
Features: | ||
|
||
- create hosted zones | ||
|
||
- delete hosted zones | ||
|
||
- list hosted zones | ||
|
||
- import from BIND format | ||
|
||
- export to BIND format | ||
|
||
- create resource records | ||
|
||
- delete resource records | ||
|
||
- works with BIND format zone files we all know and love | ||
|
||
- create AWS extensions: failover, geolocation, latency and weighted records | ||
|
||
- create AWS Alias records | ||
|
||
## Installation | ||
|
||
Installation is easy, just download the binary from the github releases page (builds are available for Linux, Mac and Windows): | ||
https://github.com/barnybug/cli53/releases/latest | ||
|
||
$ sudo cp cli53-my-platform /usr/local/bin | ||
$ sudo chmod +x /usr/local/bin/cli53 | ||
|
||
To configure your Amazon credentials, either place them in a file `~/.aws/credentials`: | ||
|
||
[default] | ||
aws_access_key_id = AKID1234567890 | ||
aws_secret_access_key = MY-SECRET-KEY | ||
|
||
Or set the environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. | ||
|
||
For more information, see: | ||
|
||
http://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs | ||
|
||
## Building from source | ||
|
||
To build yourself from source you will need golang 1.5 installed and 'GO15VENDOREXPERIMENT=1' set in your environment, then: | ||
|
||
$ go get github.com/barnybug/cli53 | ||
$ cd $GOPATH/src/github.com/barnybug/cli53 | ||
$ make install | ||
|
||
This will produce a binary `cli53` in `~/go/bin`, after this follow the steps as above. | ||
|
||
## Getting Started | ||
|
||
Create a hosted zone: | ||
|
||
$ cli53 create example.com --comment 'my first zone' | ||
|
||
Check what we've done: | ||
|
||
$ cli53 list | ||
|
||
Import a BIND zone file: | ||
|
||
$ cli53 import --file zonefile.txt example.com | ||
|
||
Replace with an imported zone, waiting for completion: | ||
|
||
$ cli53 import --file zonefile.txt --replace --wait example.com | ||
|
||
Manually create some records: | ||
|
||
$ cli53 rrcreate example.com 'www 3600 A 192.168.0.1' | ||
$ cli53 rrcreate --replace example.com 'www 3600 A 192.168.0.2' | ||
$ cli53 rrcreate example.com '@ MX "10 192.168.0.1" "20 192.168.0.2"' | ||
|
||
Export as a BIND zone file (for backup!): | ||
|
||
$ cli53 export example.com | ||
|
||
Create some weighted records: | ||
|
||
$ cli53 rrcreate --identifier server1 --weight 10 example.com 'www A 192.168.0.1' | ||
$ cli53 rrcreate --identifier server2 --weight 20 example.com 'www A 192.168.0.2' | ||
|
||
Create an alias to ELB: | ||
|
||
$ cli53 rrcreate example.com 'www ALIAS ABCDEFABCDE dns-name.elb.amazonaws.com.' | ||
|
||
Further documentation is available, e.g.: | ||
|
||
$ cli53 --help | ||
$ cli53 rrcreate --help | ||
|
||
## Broken CNAME exports (GoDaddy) | ||
|
||
Some DNS providers export broken bind files, without the trailing '.' | ||
on CNAME records. This is a requirement for absolute records | ||
(i.e. ones outside of the qualifying domain). | ||
|
||
If you see CNAME records being imported to route53 with an extra | ||
mydomain.com on the end (e.g. ghs.google.com.mydomain.com), then you | ||
need to fix your zone file before importing: | ||
|
||
$ perl -pe 's/(CNAME\s+[-a-zA-Z0-9.-_]+)(?!.)$/$1./i' broken.txt > fixed.txt | ||
|
||
## Private/public zones | ||
|
||
To manage zones that have both a private and a public zone, you must specify the | ||
zone ID instead the domain name, which is ambiguous. This is the 13 character ID | ||
after '/hostedzone/' you can see in the output to 'cli53 list'. eg: | ||
|
||
$ cli53 rrcreate ZZZZZZZZZZZZZ 'name A 127.0.0.1' | ||
|
||
Caveats | ||
------- | ||
As Amazon limits operations to a maximum of 100 changes, if you | ||
perform a large operation that changes over 100 resource records it | ||
will be split. An operation that involves deletes, followed by updates | ||
such as an import with --replace will very briefly leave the domain | ||
inconsistent. You have been warned! | ||
|
||
Changelog | ||
--------- | ||
0.6.0 New go version released! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package cli53 | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/miekg/dns" | ||
) | ||
|
||
const ClassAWS = 253 | ||
const TypeALIAS = 0x0F99 | ||
|
||
type ALIAS struct { | ||
Type string | ||
Target string | ||
ZoneId string | ||
EvaluateTargetHealth bool | ||
} | ||
|
||
func (rd *ALIAS) Copy(dest dns.PrivateRdata) error { | ||
d := dest.(*ALIAS) | ||
d.Type = rd.Type | ||
d.Target = rd.Target | ||
d.ZoneId = rd.ZoneId | ||
d.EvaluateTargetHealth = rd.EvaluateTargetHealth | ||
return nil | ||
} | ||
|
||
func (rd *ALIAS) Len() int { | ||
return 0 | ||
} | ||
|
||
func (rd *ALIAS) Parse(txt []string) error { | ||
if len(txt) != 4 { | ||
return errors.New("4 parts required for ALIAS: type target zoneid evaluateTargetHealth") | ||
} | ||
rd.Type = txt[0] | ||
rd.Target = txt[1] | ||
rd.ZoneId = txt[2] | ||
rd.EvaluateTargetHealth = (txt[3] == "true") | ||
return nil | ||
} | ||
|
||
func (rd *ALIAS) Pack(buf []byte) (int, error) { | ||
return 0, nil | ||
} | ||
|
||
func (rd *ALIAS) Unpack(buf []byte) (int, error) { | ||
return 0, nil | ||
} | ||
|
||
func (rr *ALIAS) String() string { | ||
return fmt.Sprintf("%s %s %s %v", | ||
rr.Type, | ||
rr.Target, | ||
rr.ZoneId, | ||
rr.EvaluateTargetHealth, | ||
) | ||
} | ||
|
||
func NewALIAS() dns.PrivateRdata { return new(ALIAS) } | ||
|
||
func init() { | ||
dns.StringToClass["AWS"] = ClassAWS | ||
dns.ClassToString[ClassAWS] = "AWS" | ||
dns.PrivateHandle("ALIAS", TypeALIAS, NewALIAS) | ||
} | ||
|
||
type AWSRoute interface { | ||
String() string | ||
Parse(KeyValues) | ||
} | ||
|
||
type AWSRR struct { | ||
dns.RR | ||
Route AWSRoute | ||
HealthCheckId *string | ||
Identifier string | ||
} | ||
|
||
func (rr *AWSRR) String() string { | ||
var kvs KeyValues | ||
if rr.HealthCheckId != nil { | ||
kvs = append(kvs, "healthCheckId", *rr.HealthCheckId) | ||
} | ||
kvs = append(kvs, "identifier", rr.Identifier) | ||
return fmt.Sprintf("%s ; AWS %s %s", | ||
rr.RR, | ||
rr.Route, | ||
kvs, | ||
) | ||
} | ||
|
||
type FailoverRoute struct { | ||
Failover string | ||
} | ||
|
||
func (f *FailoverRoute) String() string { | ||
return KeyValues{"routing", "FAILOVER", "failover", f.Failover}.String() | ||
} | ||
|
||
func (f *FailoverRoute) Parse(kvs KeyValues) { | ||
f.Failover = kvs.GetString("failover") | ||
} | ||
|
||
type GeoLocationRoute struct { | ||
CountryCode *string | ||
ContinentCode *string | ||
SubdivisionCode *string | ||
} | ||
|
||
func (f *GeoLocationRoute) String() string { | ||
args := KeyValues{"routing", "GEOLOCATION"} | ||
if f.CountryCode != nil { | ||
args = append(args, "countryCode", *f.CountryCode) | ||
} | ||
if f.ContinentCode != nil { | ||
args = append(args, "continentCode", *f.ContinentCode) | ||
} | ||
if f.SubdivisionCode != nil { | ||
args = append(args, "subdivisionCode", *f.SubdivisionCode) | ||
} | ||
return args.String() | ||
} | ||
|
||
func (f *GeoLocationRoute) Parse(kvs KeyValues) { | ||
f.CountryCode = kvs.GetOptString("countryCode") | ||
f.ContinentCode = kvs.GetOptString("continentCode") | ||
f.SubdivisionCode = kvs.GetOptString("subdivisonCode") | ||
} | ||
|
||
type LatencyRoute struct { | ||
Region string | ||
} | ||
|
||
func (f *LatencyRoute) String() string { | ||
return KeyValues{"routing", "LATENCY", "region", f.Region}.String() | ||
} | ||
|
||
func (f *LatencyRoute) Parse(kvs KeyValues) { | ||
f.Region = kvs.GetString("region") | ||
} | ||
|
||
type WeightedRoute struct { | ||
Weight int64 | ||
} | ||
|
||
func (f *WeightedRoute) String() string { | ||
return KeyValues{"routing", "WEIGHTED", "weight", f.Weight}.String() | ||
} | ||
|
||
func (f *WeightedRoute) Parse(kvs KeyValues) { | ||
f.Weight = int64(kvs.GetInt("weight")) | ||
} | ||
|
||
var RoutingTypes = map[string]func() AWSRoute{ | ||
"FAILOVER": func() AWSRoute { return &FailoverRoute{} }, | ||
"GEOLOCATION": func() AWSRoute { return &GeoLocationRoute{} }, | ||
"LATENCY": func() AWSRoute { return &LatencyRoute{} }, | ||
"WEIGHTED": func() AWSRoute { return &WeightedRoute{} }, | ||
} |
Oops, something went wrong.