func NewNetworkManager(ctx context.Context, sm subnet.Manager) (*Manager, error) { iface, iaddr, err := lookupExtIface(opts.iface) if err != nil { return nil, err } if iface.MTU == 0 { return nil, fmt.Errorf("Failed to determine MTU for %s interface", iaddr) } var eaddr net.IP if len(opts.publicIP) > 0 { eaddr = net.ParseIP(opts.publicIP) if eaddr == nil { return nil, fmt.Errorf("Invalid public IP address", opts.publicIP) } } if eaddr == nil { eaddr = iaddr } log.Infof("Using %s as external interface", iaddr) log.Infof("Using %s as external endpoint", eaddr) manager := &Manager{ ctx: ctx, sm: sm, allowedNetworks: make(map[string]bool), networks: make(map[string]*Network), watch: opts.watchNetworks, ipMasq: opts.ipMasq, extIface: iface, iaddr: iaddr, eaddr: eaddr, } for _, name := range strings.Split(opts.networks, ",") { manager.allowedNetworks[name] = true } if manager.isMultiNetwork() { // Get list of existing networks result, err := manager.sm.WatchNetworks(ctx, nil) if err != nil { return nil, err } for _, n := range result.Snapshot { if manager.isNetAllowed(n) { manager.networks[n] = NewNetwork(ctx, sm, n, manager.ipMasq) } } } else { manager.networks[""] = NewNetwork(ctx, sm, "", manager.ipMasq) } return manager, nil }
func run(be backend.Backend, exit chan int) { var err error defer func() { if err == nil || err == task.ErrCanceled { exit <- 0 } else { log.Error(err) exit <- 1 } }() iface, ipaddr, err := lookupIface() if err != nil { return } if iface.MTU == 0 { err = fmt.Errorf("Failed to determine MTU for %s interface", ipaddr) return } log.Infof("Using %s as external interface", ipaddr) sn, err := be.Init(iface, ipaddr, opts.ipMasq) if err != nil { log.Error("Could not init %v backend: %v", be.Name(), err) return } writeSubnetFile(sn) daemon.SdNotify("READY=1") log.Infof("%s mode initialized", be.Name()) be.Run() }
func initAndRun(ctx context.Context, sm subnet.Manager, netnames []string) { iface, iaddr, err := lookupIface() if err != nil { log.Error(err) return } if iface.MTU == 0 { log.Errorf("Failed to determine MTU for %s interface", iaddr) return } var eaddr net.IP if len(opts.publicIP) > 0 { eaddr = net.ParseIP(opts.publicIP) } if eaddr == nil { eaddr = iaddr } log.Infof("Using %s as external interface", iaddr) log.Infof("Using %s as external endpoint", eaddr) nets := []*network.Network{} for _, n := range netnames { nets = append(nets, network.New(sm, n, opts.ipMasq)) } wg := sync.WaitGroup{} for _, n := range nets { go func(n *network.Network) { wg.Add(1) defer wg.Done() sn := n.Init(ctx, iface, iaddr, eaddr) if sn != nil { if isMultiNetwork() { path := filepath.Join(opts.subnetDir, n.Name) + ".env" if err := writeSubnetFile(path, n.Config.Network, sn); err != nil { return } } else { if err := writeSubnetFile(opts.subnetFile, n.Config.Network, sn); err != nil { return } daemon.SdNotify("READY=1") } n.Run(ctx) log.Infof("%v exited", n.Name) } }(n) } wg.Wait() }
func (vb *VXLANBackend) handleInitialSubnetEvents(batch []subnet.Event) error { log.Infof("Handling initial subnet events") fdbTable, err := vb.dev.GetL2List() if err != nil { return fmt.Errorf("Error fetching L2 table: %v", err) } for _, fdbEntry := range fdbTable { log.Infof("fdb already populated with: %s %s ", fdbEntry.IP, fdbEntry.HardwareAddr) } evtMarker := make([]bool, len(batch)) leaseAttrsList := make([]vxlanLeaseAttrs, len(batch)) fdbEntryMarker := make([]bool, len(fdbTable)) for i, evt := range batch { if evt.Lease.Attrs.BackendType != "vxlan" { log.Warningf("Ignoring non-vxlan subnet: type=%v", evt.Lease.Attrs.BackendType) evtMarker[i] = true continue } if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &leaseAttrsList[i]); err != nil { log.Error("Error decoding subnet lease JSON: ", err) evtMarker[i] = true continue } for j, fdbEntry := range fdbTable { if evt.Lease.Attrs.PublicIP.ToIP().Equal(fdbEntry.IP) && bytes.Equal([]byte(leaseAttrsList[i].VtepMAC), []byte(fdbEntry.HardwareAddr)) { evtMarker[i] = true fdbEntryMarker[j] = true break } } vb.rts.set(evt.Lease.Subnet, net.HardwareAddr(leaseAttrsList[i].VtepMAC)) } for j, marker := range fdbEntryMarker { if !marker && fdbTable[j].IP != nil { err := vb.dev.DelL2(neigh{IP: ip.FromIP(fdbTable[j].IP), MAC: fdbTable[j].HardwareAddr}) if err != nil { log.Error("Delete L2 failed: ", err) } } } for i, marker := range evtMarker { if !marker { err := vb.dev.AddL2(neigh{IP: batch[i].Lease.Attrs.PublicIP, MAC: net.HardwareAddr(leaseAttrsList[i].VtepMAC)}) if err != nil { log.Error("Add L2 failed: ", err) } } } return nil }
func lookupExtIface(ifname string) (*backend.ExternalInterface, error) { var iface *net.Interface var iaddr net.IP var err error if len(ifname) > 0 { if iaddr = net.ParseIP(ifname); iaddr != nil { iface, err = ip.GetInterfaceByIP(iaddr) if err != nil { return nil, fmt.Errorf("error looking up interface %s: %s", ifname, err) } } else { iface, err = net.InterfaceByName(ifname) if err != nil { return nil, fmt.Errorf("error looking up interface %s: %s", ifname, err) } } } else { log.Info("Determining IP address of default interface") if iface, err = ip.GetDefaultGatewayIface(); err != nil { return nil, fmt.Errorf("failed to get default interface: %s", err) } } if iaddr == nil { iaddr, err = ip.GetIfaceIP4Addr(iface) if err != nil { return nil, fmt.Errorf("failed to find IPv4 address for interface %s", iface.Name) } } if iface.MTU == 0 { return nil, fmt.Errorf("failed to determine MTU for %s interface", iaddr) } var eaddr net.IP if len(opts.publicIP) > 0 { eaddr = net.ParseIP(opts.publicIP) if eaddr == nil { return nil, fmt.Errorf("invalid public IP address", opts.publicIP) } } if eaddr == nil { eaddr = iaddr } log.Infof("Using %s as external interface", iaddr) log.Infof("Using %s as external endpoint", eaddr) return &backend.ExternalInterface{ Iface: iface, IfaceAddr: iaddr, ExtAddr: eaddr, }, nil }
func (m *Manager) watchNetworks() { wg := sync.WaitGroup{} defer wg.Wait() events := make(chan []subnet.Event) wg.Add(1) go func() { subnet.WatchNetworks(m.ctx, m.sm, events) wg.Done() }() // skip over the initial snapshot <-events for { select { case <-m.ctx.Done(): return case evtBatch := <-events: for _, e := range evtBatch { netname := e.Network if !m.isNetAllowed(netname) { log.Infof("Network %q is not allowed", netname) continue } switch e.Type { case subnet.EventAdded: n := NewNetwork(m.ctx, m.sm, m.bm, netname, m.ipMasq) if err := m.addNetwork(n); err != nil { log.Infof("Network %q: %v", netname, err) continue } log.Infof("Network added: %v", netname) wg.Add(1) go func() { m.runNetwork(n) wg.Done() }() case subnet.EventRemoved: log.Infof("Network removed: %v", netname) n, ok := m.getNetwork(netname) if !ok { log.Warningf("Network %v unknown; ignoring EventRemoved", netname) continue } n.Cancel() } } } } }
func (m *EtcdManager) tryAcquireLease(ctx context.Context, network string, config *Config, extIP ip.IP4, attrs *LeaseAttrs) (*Lease, error) { var err error leases, _, err := m.getLeases(ctx, network) if err != nil { return nil, err } attrBytes, err := json.Marshal(attrs) if err != nil { return nil, err } // try to reuse a subnet if there's one that matches our IP if l := findLeaseByIP(leases, extIP); l != nil { // make sure the existing subnet is still within the configured network if isSubnetConfigCompat(config, l.Subnet) { log.Infof("Found lease (%v) for current IP (%v), reusing", l.Subnet, extIP) resp, err := m.registry.updateSubnet(ctx, network, l.Key(), string(attrBytes), subnetTTL) if err != nil { return nil, err } l.Attrs = attrs l.Expiration = *resp.Node.Expiration return l, nil } else { log.Infof("Found lease (%v) for current IP (%v) but not compatible with current config, deleting", l.Subnet, extIP) if _, err := m.registry.deleteSubnet(ctx, network, l.Key()); err != nil { return nil, err } } } // no existing match, grab a new one sn, err := m.allocateSubnet(config, leases) if err != nil { return nil, err } resp, err := m.registry.createSubnet(ctx, network, sn.StringSep(".", "-"), string(attrBytes), subnetTTL) switch { case err == nil: return &Lease{ Subnet: sn, Attrs: attrs, Expiration: *resp.Node.Expiration, }, nil // if etcd returned Key Already Exists, try again. case err.(*etcd.EtcdError).ErrorCode == etcdKeyAlreadyExists: return nil, nil default: return nil, err } }
func (m *LocalManager) tryAcquireLease(ctx context.Context, network string, config *Config, extIaddr ip.IP4, attrs *LeaseAttrs) (*Lease, error) { leases, _, err := m.registry.getSubnets(ctx, network) if err != nil { return nil, err } // try to reuse a subnet if there's one that matches our IP if l := findLeaseByIP(leases, extIaddr); l != nil { // make sure the existing subnet is still within the configured network if isSubnetConfigCompat(config, l.Subnet) { log.Infof("Found lease (%v) for current IP (%v), reusing", l.Subnet, extIaddr) ttl := time.Duration(0) if !l.Expiration.IsZero() { // Not a reservation ttl = subnetTTL } exp, err := m.registry.updateSubnet(ctx, network, l.Subnet, attrs, ttl, 0) if err != nil { return nil, err } l.Attrs = *attrs l.Expiration = exp return l, nil } else { log.Infof("Found lease (%v) for current IP (%v) but not compatible with current config, deleting", l.Subnet, extIaddr) if err := m.registry.deleteSubnet(ctx, network, l.Subnet); err != nil { return nil, err } } } // no existing match, grab a new one sn, err := m.allocateSubnet(config, leases) if err != nil { return nil, err } exp, err := m.registry.createSubnet(ctx, network, sn, attrs, subnetTTL) switch { case err == nil: return &Lease{ Subnet: sn, Attrs: *attrs, Expiration: exp, }, nil case isErrEtcdNodeExist(err): return nil, errTryAgain default: return nil, err } }
func (m *LocalManager) tryAcquireLease(ctx context.Context, network string, config *Config, extIaddr ip.IP4, attrs *LeaseAttrs) (*Lease, error) { var err error leases, _, err := m.registry.getSubnets(ctx, network) if err != nil { return nil, err } // try to reuse a subnet if there's one that matches our IP if l := findLeaseByIP(leases, extIaddr); l != nil { // make sure the existing subnet is still within the configured network if isSubnetConfigCompat(config, l.Subnet) { log.Infof("Found lease (%v) for current IP (%v), reusing", l.Subnet, extIaddr) exp, err := m.registry.updateSubnet(ctx, network, l.Subnet, attrs, subnetTTL, 0) if err != nil { return nil, err } l.Attrs = *attrs l.Expiration = exp return l, nil } else { log.Infof("Found lease (%v) for current IP (%v) but not compatible with current config, deleting", l.Subnet, extIaddr) if err := m.registry.deleteSubnet(ctx, network, l.Subnet); err != nil { return nil, err } } } // no existing match, grab a new one sn, err := m.allocateSubnet(config, leases) if err != nil { return nil, err } exp, err := m.registry.createSubnet(ctx, network, sn, attrs, subnetTTL) if err == nil { return &Lease{ Subnet: sn, Attrs: *attrs, Expiration: exp, }, nil } if etcdErr, ok := err.(etcd.Error); ok && etcdErr.Code == etcd.ErrorCodeNodeExist { // if etcd returned Key Already Exists, try again. return nil, nil } return nil, err }
func (vb *VXLANBackend) handleL3Miss(miss *netlink.Neigh) { log.Infof("L3 miss: %v", miss.IP) rt := vb.rts.findByNetwork(ip.FromIP(miss.IP)) if rt == nil { log.Infof("Route for %v not found", miss.IP) return } if err := vb.dev.AddL3(neigh{IP: ip.FromIP(miss.IP), MAC: rt.vtepMAC}); err != nil { log.Errorf("AddL3 failed: %v", err) } else { log.Info("AddL3 succeeded") } }
func (rb *HostgwBackend) checkSubnetExistInRoutes() { routeList, err := netlink.RouteList(nil, netlink.FAMILY_V4) if err == nil { for _, route := range rb.rl { exist := false for _, r := range routeList { if r.Dst == nil { continue } if routeEqual(r, route) { exist = true break } } if !exist { if err := netlink.RouteAdd(&route); err != nil { if nerr, ok := err.(net.Error); !ok { log.Errorf("Error recovering route to %v: %v, %v", route.Dst, route.Gw, nerr) } continue } else { log.Infof("Route recovered %v : %v", route.Dst, route.Gw) } } } } }
func (dev *vxlanDevice) DelL2(n neigh) error { log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC) return netlink.NeighDel(&netlink.Neigh{ LinkIndex: dev.link.Index, Family: syscall.AF_BRIDGE, Flags: netlink.NTF_SELF, IP: n.IP.ToIP(), HardwareAddr: n.MAC, }) }
func (dev *vxlanDevice) DelL3(n neigh) error { log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC) return netlink.NeighDel(&netlink.Neigh{ LinkIndex: dev.link.Index, State: netlink.NUD_REACHABLE, Type: syscall.RTN_UNICAST, IP: n.IP.ToIP(), HardwareAddr: n.MAC, }) }
func (vb *VXLANBackend) handleMiss(miss *netlink.Neigh) { switch { case len(miss.IP) == 0 && len(miss.HardwareAddr) == 0: log.Info("Ignoring nil miss") case len(miss.HardwareAddr) == 0: vb.handleL3Miss(miss) default: log.Infof("Ignoring not a miss: %v, %v", miss.HardwareAddr, miss.IP) } }
func (g *GCEBackend) insertRoute(subnet string) (*compute.Operation, error) { log.Infof("Inserting route for subnet: %v", subnet) route := &compute.Route{ Name: formatRouteName(subnet), DestRange: subnet, Network: g.gceNetwork.SelfLink, NextHopInstance: g.gceInstance.SelfLink, Priority: 1000, Tags: []string{}, } return g.computeService.Routes.Insert(g.project, route).Do() }
func (m *Manager) RunNetwork(net *Network) { sn := net.Init(m.extIface, m.iaddr, m.eaddr) if sn != nil { if m.isMultiNetwork() { path := filepath.Join(opts.subnetDir, net.Name) + ".env" if err := writeSubnetFile(path, net.Config.Network, m.ipMasq, sn); err != nil { log.Warningf("%v failed to write subnet file: %s", net.Name, err) return } } else { if err := writeSubnetFile(opts.subnetFile, net.Config.Network, m.ipMasq, sn); err != nil { log.Warningf("%v failed to write subnet file: %s", net.Name, err) return } daemon.SdNotify("READY=1") } log.Infof("Running network %v", net.Name) net.Run() log.Infof("%v exited", net.Name) } }
func (m *Manager) runNetwork(n *Network) { n.Run(m.extIface, func(bn backend.Network) { if m.isMultiNetwork() { log.Infof("%v: lease acquired: %v", n.Name, bn.Lease().Subnet) path := filepath.Join(opts.subnetDir, n.Name) + ".env" if err := writeSubnetFile(path, n.Config.Network, m.ipMasq, bn); err != nil { log.Warningf("%v failed to write subnet file: %s", n.Name, err) return } } else { log.Infof("Lease acquired: %v", bn.Lease().Subnet) if err := writeSubnetFile(opts.subnetFile, n.Config.Network, m.ipMasq, bn); err != nil { log.Warningf("%v failed to write subnet file: %s", n.Name, err) return } daemon.SdNotify("READY=1") } }) m.delNetwork(n) }
func (rb *HostgwBackend) handleSubnetEvents(batch []subnet.Event) { for _, evt := range batch { switch evt.Type { case subnet.SubnetAdded: log.Infof("Subnet added: %v via %v", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP) if evt.Lease.Attrs.BackendType != "host-gw" { log.Warningf("Ignoring non-host-gw subnet: type=%v", evt.Lease.Attrs.BackendType) continue } route := netlink.Route{ Dst: evt.Lease.Subnet.ToIPNet(), Gw: evt.Lease.Attrs.PublicIP.ToIP(), LinkIndex: rb.extIface.Index, } if rb.extIaddr.Equal(route.Gw) { continue } if err := netlink.RouteAdd(&route); err != nil { log.Errorf("Error adding route to %v via %v: %v", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP, err) continue } rb.addToRouteList(route) case subnet.SubnetRemoved: log.Info("Subnet removed: ", evt.Lease.Subnet) if evt.Lease.Attrs.BackendType != "host-gw" { log.Warningf("Ignoring non-host-gw subnet: type=%v", evt.Lease.Attrs.BackendType) continue } route := netlink.Route{ Dst: evt.Lease.Subnet.ToIPNet(), Gw: evt.Lease.Attrs.PublicIP.ToIP(), LinkIndex: rb.extIface.Index, } if err := netlink.RouteDel(&route); err != nil { log.Errorf("Error deleting route to %v: %v", evt.Lease.Subnet, err) continue } rb.removeFromRouteList(route) default: log.Error("Internal error: unknown event type: ", int(evt.Type)) } } }
func main() { // glog will log to tmp files by default. override so all entries // can flow into journald (if running under systemd) flag.Set("logtostderr", "true") // now parse command line args flag.Parse() if opts.help { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0]) flag.PrintDefaults() os.Exit(0) } if opts.version { fmt.Fprintln(os.Stderr, Version) os.Exit(0) } be, err := newBackend() if err != nil { log.Info(err) os.Exit(1) } // Register for SIGINT and SIGTERM and wait for one of them to arrive log.Info("Installing signal handlers") sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) exit := make(chan int) go run(be, exit) for { select { case <-sigs: // unregister to get default OS nuke behaviour in case we don't exit cleanly signal.Stop(sigs) log.Info("Exiting...") be.Stop() case code := <-exit: log.Infof("%s mode exited", be.Name()) os.Exit(code) } } }
func (g *GCEBackend) pollOperationStatus(operationName string) error { for i := 0; i < 100; i++ { operation, err := g.computeService.GlobalOperations.Get(g.project, operationName).Do() if err != nil { return fmt.Errorf("error fetching operation status: %v", err) } if operation.Error != nil { return fmt.Errorf("error running operation: %v", operation.Error) } if i%5 == 0 { log.Infof("%v operation status: %v waiting for completion...", operation.OperationType, operation.Status) } if operation.Status == "DONE" { return nil } time.Sleep(time.Second) } return fmt.Errorf("timeout waiting for operation to finish") }
func (m *EtcdManager) allocateSubnet(config *Config, leases []Lease) (ip.IP4Net, error) { log.Infof("Picking subnet in range %s ... %s", config.SubnetMin, config.SubnetMax) var bag []ip.IP4 sn := ip.IP4Net{IP: config.SubnetMin, PrefixLen: config.SubnetLen} OuterLoop: for ; sn.IP <= config.SubnetMax && len(bag) < 100; sn = sn.Next() { for _, l := range leases { if sn.Overlaps(l.Subnet) { continue OuterLoop } } bag = append(bag, sn.IP) } if len(bag) == 0 { return ip.IP4Net{}, errors.New("out of subnets") } else { i := randInt(0, len(bag)) return ip.IP4Net{IP: bag[i], PrefixLen: config.SubnetLen}, nil } }
func Register(name string, ctor BackendCtor) { log.Infof("Register: %v", name) backendCtors[name] = ctor }
func (m *AwsVpcBackend) Init(extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) { // Parse our configuration if len(m.config.Backend) > 0 { if err := json.Unmarshal(m.config.Backend, &m.cfg); err != nil { return nil, fmt.Errorf("error decoding VPC backend config: %v", err) } } // Acquire the lease form subnet manager attrs := subnet.LeaseAttrs{ PublicIP: ip.FromIP(extEaddr), } l, err := m.sm.AcquireLease(m.ctx, m.network, &attrs) switch err { case nil: m.lease = l case context.Canceled, context.DeadlineExceeded: return nil, err default: return nil, fmt.Errorf("failed to acquire lease: %v", err) } // Figure out this machine's EC2 instance ID and region identity, err := getInstanceIdentity() if err != nil { return nil, fmt.Errorf("error getting EC2 instance identity: %v", err) } instanceID, ok := identity["instanceId"].(string) if !ok { return nil, fmt.Errorf("invalid EC2 instance ID: %v", identity["instanceId"]) } regionVal, _ := identity["region"].(string) region, ok := aws.Regions[regionVal] if !ok { return nil, fmt.Errorf("invalid AWS region: %v", identity["region"]) } // Setup the EC2 client auth, err := aws.GetAuth("", "") if err != nil { return nil, fmt.Errorf("error getting AWS credentials from environment: %v", err) } ec2c := ec2.New(auth, region) if _, err = m.disableSrcDestCheck(instanceID, ec2c); err != nil { log.Infof("Warning- disabling source destination check failed: %v", err) } if m.cfg.RouteTableID == "" { log.Infof("RouteTableID not passed as config parameter, detecting ...") if err := m.detectRouteTableID(instanceID, ec2c); err != nil { return nil, err } } log.Info("RouteRouteTableID: ", m.cfg.RouteTableID) matchingRouteFound, err := m.checkMatchingRoutes(instanceID, l.Subnet.String(), ec2c) if err != nil { log.Errorf("Error describing route tables: %v", err) if ec2Err, ok := err.(*ec2.Error); ok { if ec2Err.Code == "UnauthorizedOperation" { log.Errorf("Note: DescribeRouteTables permission cannot be bound to any resource") } } } if !matchingRouteFound { if _, err := ec2c.DeleteRoute(m.cfg.RouteTableID, l.Subnet.String()); err != nil { if ec2err, ok := err.(*ec2.Error); !ok || ec2err.Code != "InvalidRoute.NotFound" { // an error other than the route not already existing occurred return nil, fmt.Errorf("error deleting existing route for %s: %v", l.Subnet.String(), err) } } // Add the route for this machine's subnet if _, err := m.createRoute(instanceID, l.Subnet.String(), ec2c); err != nil { return nil, fmt.Errorf("unable to add route %s: %v", l.Subnet.String(), err) } } return &backend.SubnetDef{ Net: l.Subnet, MTU: extIface.MTU, }, nil }
func (dev *vxlanDevice) GetL2List() ([]netlink.Neigh, error) { log.Infof("calling GetL2List() dev.link.Index: %d ", dev.link.Index) return netlink.NeighList(dev.link.Index, syscall.AF_BRIDGE) }
func (m *AwsVpcBackend) Init(extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) { // Parse our configuration if len(m.config.Backend) > 0 { if err := json.Unmarshal(m.config.Backend, &m.cfg); err != nil { return nil, fmt.Errorf("error decoding VPC backend config: %v", err) } } // Acquire the lease form subnet manager attrs := subnet.LeaseAttrs{ PublicIP: ip.FromIP(extEaddr), } l, err := m.sm.AcquireLease(m.ctx, m.network, &attrs) switch err { case nil: m.lease = l case context.Canceled, context.DeadlineExceeded: return nil, err default: return nil, fmt.Errorf("failed to acquire lease: %v", err) } // Figure out this machine's EC2 instance ID and region metadataClient := ec2metadata.New(nil) region, err := metadataClient.Region() if err != nil { return nil, fmt.Errorf("error getting EC2 region name: %v", err) } instanceID, err := metadataClient.GetMetadata("instance-id") if err != nil { return nil, fmt.Errorf("error getting EC2 instance ID: %v", err) } ec2c := ec2.New(&aws.Config{Region: aws.String(region)}) if _, err = m.disableSrcDestCheck(instanceID, ec2c); err != nil { log.Infof("Warning- disabling source destination check failed: %v", err) } if m.cfg.RouteTableID == "" { log.Infof("RouteTableID not passed as config parameter, detecting ...") if err := m.detectRouteTableID(instanceID, ec2c); err != nil { return nil, err } } log.Info("RouteRouteTableID: ", m.cfg.RouteTableID) matchingRouteFound, err := m.checkMatchingRoutes(instanceID, l.Subnet.String(), ec2c) if err != nil { log.Errorf("Error describing route tables: %v", err) if ec2Err, ok := err.(awserr.Error); ok { if ec2Err.Code() == "UnauthorizedOperation" { log.Errorf("Note: DescribeRouteTables permission cannot be bound to any resource") } } } if !matchingRouteFound { cidrBlock := l.Subnet.String() deleteRouteInput := &ec2.DeleteRouteInput{RouteTableId: &m.cfg.RouteTableID, DestinationCidrBlock: &cidrBlock} if _, err := ec2c.DeleteRoute(deleteRouteInput); err != nil { if ec2err, ok := err.(awserr.Error); !ok || ec2err.Code() != "InvalidRoute.NotFound" { // an error other than the route not already existing occurred return nil, fmt.Errorf("error deleting existing route for %s: %v", l.Subnet.String(), err) } } // Add the route for this machine's subnet if _, err := m.createRoute(instanceID, l.Subnet.String(), ec2c); err != nil { return nil, fmt.Errorf("unable to add route %s: %v", l.Subnet.String(), err) } } return &backend.SubnetDef{ Net: l.Subnet, MTU: extIface.MTU, }, nil }
func (lh httpLoggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { resp := &httpResp{w, 0} lh.h.ServeHTTP(resp, r) log.Infof("%v %v - %v", r.Method, r.RequestURI, resp.status) }
func (m *AwsVpcBackend) Init(extIface *net.Interface, extIP net.IP) (*backend.SubnetDef, error) { // Parse our configuration if len(m.config.Backend) > 0 { if err := json.Unmarshal(m.config.Backend, &m.cfg); err != nil { return nil, fmt.Errorf("error decoding VPC backend config: %v", err) } } // Acquire the lease form subnet manager attrs := subnet.LeaseAttrs{ PublicIP: ip.FromIP(extIP), } l, err := m.sm.AcquireLease(m.ctx, m.network, &attrs) switch err { case nil: m.lease = l case context.Canceled, context.DeadlineExceeded: return nil, err default: return nil, fmt.Errorf("failed to acquire lease: %v", err) } // Figure out this machine's EC2 instance ID and region identity, err := getInstanceIdentity() if err != nil { return nil, fmt.Errorf("error getting EC2 instance identity: %v", err) } instanceID, ok := identity["instanceId"].(string) if !ok { return nil, fmt.Errorf("invalid EC2 instance ID: %v", identity["instanceId"]) } regionVal, _ := identity["region"].(string) region, ok := aws.Regions[regionVal] if !ok { return nil, fmt.Errorf("invalid AWS region: %v", identity["region"]) } // Setup the EC2 client auth, err := aws.GetAuth("", "") if err != nil { return nil, fmt.Errorf("error getting AWS credentials from environment: %v", err) } ec2c := ec2.New(auth, region) if m.cfg.RouteTableID == "" { log.Infof("RouteTableID not passed as config parameter, attempting to detect") routeTableID, err := m.DetectRouteTableID(instanceID, ec2c) if err != nil { return nil, err } log.Info("Detected routeRouteTableID: ", routeTableID) m.cfg.RouteTableID = routeTableID } filter := ec2.NewFilter() filter.Add("route.destination-cidr-block", l.Subnet.String()) filter.Add("route.state", "active") resp, err := ec2c.DescribeRouteTables([]string{m.cfg.RouteTableID}, filter) if err != nil { log.Errorf("Error describing route tables: %v", err) if ec2Err, ok := err.(*ec2.Error); ok { if ec2Err.Code == "UnauthorizedOperation" { log.Errorf("Note: describeRouteTables permission cannot be bound to any resource") } } } else { for _, routeTable := range resp.RouteTables { for _, route := range routeTable.Routes { if l.Subnet.String() == route.DestinationCidrBlock && route.State == "active" { log.Errorf("Matching *active* entry to: %s that will be deleted: %s, %s \n", l.Subnet.String(), route.DestinationCidrBlock, route.GatewayId) } } } } // Delete route for this machine's subnet if it already exists if _, err := ec2c.DeleteRoute(m.cfg.RouteTableID, l.Subnet.String()); err != nil { if ec2err, ok := err.(*ec2.Error); !ok || ec2err.Code != "InvalidRoute.NotFound" { // an error other than the route not already existing occurred return nil, fmt.Errorf("error deleting existing route for %s: %v", l.Subnet.String(), err) } } // Add the route for this machine's subnet route := &ec2.CreateRoute{ RouteTableId: m.cfg.RouteTableID, InstanceId: instanceID, DestinationCidrBlock: l.Subnet.String(), } if _, err := ec2c.CreateRoute(route); err != nil { return nil, fmt.Errorf("unable to add route %+v: %v", route, err) } return &backend.SubnetDef{ Net: l.Subnet, MTU: extIface.MTU, }, nil }