func main() { if accessKey == "" { die("AWS_ACCESS_KEY is not set") } if secretKey == "" { die("AWS_SECRET_KEY is not set") } if hostedZone == "" { die("ROUTE53_HOSTED_ZONE is not set") } opts := &dnsclient.Options{ Creds: credentials.NewStaticCredentials(accessKey, secretKey, ""), HostedZone: hostedZone, Log: logging.NewCustom("dnsclient", os.Getenv("ROUTE53_DEBUG") == "1"), SyncTimeout: 5 * time.Minute, } if d, err := time.ParseDuration(os.Getenv("ROUTE53_TIMEOUT")); err == nil { opts.SyncTimeout = d } opts.Log.Debug("Options: %# v", opts) var err error client, err = dnsclient.NewRoute53Client(opts) if err != nil { die(err) } if err := Resources.Main(os.Args[1:]); err != nil { die(err) } }
func (cmd *GroupFixDomain) Valid() error { if err := cmd.groupValues.Valid(); err != nil { return err } if len(cmd.values) == 0 { return errors.New("no usernames provided for -users flag") } if cmd.machine == "" { return errors.New("no value provided for -machine flag") } if cmd.env == "" { return errors.New("no value provided for -env flag") } zone := dnsZones[cmd.env] if zone == "" { return errors.New("invalid value provided for -env flag") } if cmd.access == "" { return errors.New("no value provided for -access flag") } if cmd.secret == "" { return errors.New("no value provided for -secret flag") } dnsOpts := &dnsclient.Options{ Creds: credentials.NewStaticCredentials(cmd.access, cmd.secret, ""), HostedZone: zone, Log: logging.NewCustom("dns", flagDebug), } dns, err := dnsclient.NewRoute53Client(dnsOpts) if err != nil { return err } cmd.dns = dns return nil }
func (c *Config) cleanupRoute53() { if len(c.CleanRoute53) == 0 { c.Log.Info("no Route53 domains to clean") return } dnsOpts := &dnsclient.Options{ Creds: c.creds(), HostedZone: c.HostedZone, Log: c.Log, } dns, err := dnsclient.NewRoute53Client(dnsOpts) if err != nil { c.Log.Warning("failed to clean Route53 domains: %s", err) return } records, err := dns.GetAll("") if err != nil { c.Log.Warning("failed to get Route53 domains: %s", err) return } for _, suffix := range c.CleanRoute53 { for _, rec := range records { if strings.HasSuffix(rec.Name, suffix) { err := dns.DeleteRecord(rec) if err != nil { c.Log.Warning("failed to delete record %q: %s", rec.Name, err) continue } c.Log.Info("deleted %q record", rec.Name) } } } }
// NewServer gives new tunneling server for the given options. func NewServer(opts *ServerOptions) (*Server, error) { optsCopy := *opts if optsCopy.ServerAddr == "" { ip, err := publicIP() if err != nil { return nil, err } optsCopy.ServerAddr = ip } if optsCopy.Log == nil { optsCopy.Log = logging.NewCustom("tunnelserver", optsCopy.Debug) } optsCopy.Log.Debug("Initial server options: %# v", &optsCopy) if optsCopy.BaseVirtualHost == "" { optsCopy.BaseVirtualHost = optsCopy.HostedZone } if optsCopy.BaseVirtualHost == "" { return nil, errors.New("either BaseVirtualHost or HostedZone parameter is required to be non-empty") } optsCopy.BaseVirtualHost = customPort(optsCopy.BaseVirtualHost, opts.Port, 80, 443) optsCopy.ServerAddr = customPort(optsCopy.ServerAddr, opts.Port) if optsCopy.TCPRangeFrom == 0 { optsCopy.TCPRangeFrom = 20000 } if optsCopy.TCPRangeTo == 0 { optsCopy.TCPRangeTo = 50000 } tunnelCfg := &tunnel.ServerConfig{ Debug: optsCopy.Debug, Log: optsCopy.Log, } server, err := tunnel.NewServer(tunnelCfg) if err != nil { return nil, err } if optsCopy.NoCNAME && (optsCopy.AccessKey == "" || optsCopy.SecretKey == "") { return nil, errors.New("no valid Route53 configuration found") } var dns *dnsclient.Route53 if optsCopy.AccessKey != "" && optsCopy.SecretKey != "" { dnsOpts := &dnsclient.Options{ Creds: credentials.NewStaticCredentials(optsCopy.AccessKey, optsCopy.SecretKey, ""), HostedZone: optsCopy.HostedZone, Log: optsCopy.Log, Debug: optsCopy.Debug, } dns, err = dnsclient.NewRoute53Client(dnsOpts) if err != nil { return nil, err } } // Inserts DNS records for the tunnelserver. Host-routing requires an A record pointing // to the tunnelserver and a wildcard CNAME record pointing to that A record. // In other words if tunnel.example.com resolves to the tunnelserver, then // *.tunnel.example.com must also resolve to the very same tunnelserver instance. // // If there are not route53 credentials passed, we assume the DNS records are // taken care externally. if !optsCopy.NoCNAME && dns != nil { id, err := instanceID() if err != nil { if optsCopy.Test { username := os.Getenv("USER") if u, err := user.Current(); err == nil { username = u.Username } id = "koding-" + username } } if id != "" { optsCopy.BaseVirtualHost = strings.TrimPrefix(id, "i-") + "." + optsCopy.BaseVirtualHost } ip := host(optsCopy.ServerAddr) base := host(optsCopy.BaseVirtualHost) tunnelRec := &dnsclient.Record{ Name: base, IP: ip, Type: "A", TTL: 300, } allRec := &dnsclient.Record{ Name: "\\052." + base, IP: base, Type: "CNAME", TTL: 300, } // TODO(rjeczalik): add retries to pkg/dnsclient (TMS-2052) for i := 0; i < 5; i++ { if err = dns.UpsertRecords(tunnelRec, allRec); err == nil { break } time.Sleep(time.Duration(i) * time.Second) // linear backoff, overall time: 30s } if err != nil { return nil, err } } optsCopy.Log.Debug("Server options: %# v", &optsCopy) s := &Server{ Server: server, DNS: dns, opts: &optsCopy, privateIP: "0.0.0.0", record: dnsclient.ParseRecord("", optsCopy.ServerAddr), idents: make(map[string]string), services: make(map[int]net.Listener), tunnels: newTunnels(), } // Do not bind to private address for testing. if !s.opts.Test { if ip, err := privateIP(); err == nil { s.privateIP = ip } } return s, nil }
func providers() (*awsprovider.Provider, *softlayer.Provider) { c := credentials.NewStaticCredentials(os.Getenv("KLOUD_ACCESSKEY"), os.Getenv("KLOUD_SECRETKEY"), "") mongoURL := os.Getenv("KLOUD_MONGODB_URL") if mongoURL == "" { panic("KLOUD_MONGODB_URL is not set") } modelhelper.Initialize(mongoURL) db := modelhelper.Mongo dnsOpts := &dnsclient.Options{ Creds: c, HostedZone: "dev.koding.io", Log: logging.NewCustom("dns", true), } dnsInstance, err := dnsclient.NewRoute53Client(dnsOpts) if err != nil { panic(err) } dnsStorage := dnsstorage.NewMongodbStorage(db) usd := &userdata.Userdata{ Keycreator: &keycreator.Key{ KontrolURL: conf.KontrolURL, KontrolPrivateKey: testkeys.Private, KontrolPublicKey: testkeys.Public, }, Bucket: userdata.NewBucket("koding-klient", "development/latest", c), } opts := &amazon.ClientOptions{ Credentials: c, Regions: amazon.ProductionRegions, Log: logging.NewCustom("koding", true), } ec2clients, err := amazon.NewClients(opts) if err != nil { panic(err) } slclient := sl.NewSoftlayer( os.Getenv("KLOUD_TESTACCOUNT_SLUSERNAME"), os.Getenv("KLOUD_TESTACCOUNT_SLAPIKEY"), ) awsp := &awsprovider.Provider{ DB: db, Log: logging.NewCustom("kloud-aws", true), DNSClient: dnsInstance, DNSStorage: dnsStorage, Kite: kloudKite, Userdata: usd, } slp := &softlayer.Provider{ DB: db, Log: logging.NewCustom("kloud-softlayer", true), DNSClient: dnsInstance, DNSStorage: dnsStorage, SLClient: slclient, Kite: kloudKite, Userdata: usd, } return kdp, awsp, slp }
func NewCleaner(conf *Config) *Cleaner { creds := credentials.NewStaticCredentials( conf.Aws.AccessKey, conf.Aws.SecretKey, "", ) opts := &amazon.ClientOptions{ Credentials: creds, Regions: amazon.ProductionRegions, Log: logging.NewCustom("cleaner", conf.Debug), MaxResults: int64(conf.MaxResults), Debug: conf.Debug, } m := lookup.NewMongoDB(conf.MongoURL) l, err := lookup.NewAWS(opts) if err != nil { panic(err) } dnsOpts := &dnsclient.Options{ Creds: creds, HostedZone: conf.HostedZone, Log: logging.NewCustom("dns", conf.Debug), } dns, err := dnsclient.NewRoute53Client(dnsOpts) if err != nil { panic(err) } dnsdevOpts := &dnsclient.Options{ Creds: creds, HostedZone: "dev.koding.io", Log: logging.NewCustom("dnsdev", conf.Debug), } dnsdev, err := dnsclient.NewRoute53Client(dnsdevOpts) if err != nil { panic(err) } domains := dnsstorage.NewMongodbStorage(m.DB) p := lookup.NewPostgres(&lookup.PostgresConfig{ Host: conf.Postgres.Host, Port: conf.Postgres.Port, Username: conf.Postgres.Username, Password: conf.Postgres.Password, DBName: conf.Postgres.DBName, }) // TODO: change once the code is moved to koding/monitoring hook := Hook{ URL: conf.Slack.URL, Channel: "#reports", Username: "******", } return &Cleaner{ AWS: l, MongoDB: m, SandboxMongoDB: lookup.NewMongoDB(conf.SandboxMongoURL), Postgres: p, DNS: dns, DNSDev: dnsdev, Domains: domains, Hook: hook, Log: logging.NewCustom("cleaner", conf.Debug), Config: conf, } }