func ExampleNew() { ip := net.IPv4(byte(203), byte(43), byte(55), byte(2)) subdomain := "foo.com" expires := time.Now().Add(15 * time.Minute) secret := "turnip4tea" fmt.Println(hostname.New(ip, subdomain, expires, secret)) }
func TestEncodeDecode(t *testing.T) { ip := net.IPv4(byte(203), byte(43), byte(55), byte(2)) subdomain := "foo.com" expires := time.Now().Add(15 * time.Minute) secret := "turnip4tea" // encode fqdn := hostname.New(ip, subdomain, expires, secret) // decode ip2, expires2, _, err := hostname.Decode(fqdn, secret, subdomain) if err != nil { t.Fatalf("Error when creating hostname: %v", err) } if ip.String() != ip2.String() { t.Fatalf("Incorrect IP - got %v but was expecting %v", ip, ip2) } if expires.Unix() != expires2.Unix() { t.Fatalf("Incorrect Expiry - got %v but was expecting %v", expires, expires2) } }
func main() { arguments, err := docopt.Parse(usage, nil, true, version, false, true) if err != nil { fmt.Println("Error parsing command line arguments!") os.Exit(1) } // Validate IP ipString := arguments["IP"].(string) ip := net.ParseIP(ipString) if ip == nil { fmt.Fprintf(os.Stderr, "create-hostname: ERR 64: Invalid IP '%s'\n", ipString) os.Exit(64) } ip = ip.To4() if ip == nil { fmt.Fprintf(os.Stderr, "create-hostname: ERR 65: IPv6 given for IP (should be IPv4) '%s'\n", ipString) os.Exit(65) } // TODO: Validate SUBDOMAIN subdomain := arguments["SUBDOMAIN"].(string) // Validate EXPIRES expiresString := arguments["EXPIRES"].(string) expires, err := time.Parse(time.RFC3339Nano, expiresString) if err != nil { fmt.Fprintf(os.Stderr, "create-hostname: ERR 67: Invalid EXPIRES '%s'\n", expiresString) os.Exit(67) } // TODO: Validate SECRET secret := arguments["SECRET"].(string) name := hostname.New(ip, subdomain, expires, secret) fmt.Println(name) }
// NewLocalServer creates a WebHookServer that listens on publicIP, publicPort // and uses stateless-dns-server to obtain a hostname. // // If networkInterface is non-empty and localPort is non-zero then server will // listen on the localPort for the given networkInterface. This is useful if // running inside a container. func NewLocalServer( publicIP []byte, publicPort int, networkInterface string, localPort int, subdomain, dnsSecret, tlsCert, tlsKey string, expiration time.Duration, ) (*LocalServer, error) { s := &LocalServer{ hooks: make(map[string]http.Handler), } // Address that we should be listening on localAddress := net.TCPAddr{ IP: publicIP, Port: publicPort, } if localPort != 0 { localAddress.Port = localPort } // If network interface is specified we listen to that, instead of the public // IP address. This is necessary when running inside a docker container where // the local network interface isn't assigned to a public IP. if networkInterface != "" { iface, err := net.InterfaceByName(networkInterface) if err != nil { return nil, fmt.Errorf( "Unable to find interface: %s, error: %s", networkInterface, err, ) } addrs, err := iface.Addrs() if err != nil { return nil, fmt.Errorf( "Couldn't list addresses of interface: %s, error: %s", networkInterface, err, ) } gotIP := false for _, addr := range addrs { if a, ok := addr.(*net.IPNet); ok && a.IP.To4() != nil { localAddress.IP = a.IP.To4() gotIP = true break } } if !gotIP { return nil, fmt.Errorf("Interface: %s has no IPv4 address", networkInterface) } } // Setup server s.server = &graceful.Server{ Timeout: 35 * time.Second, Server: &http.Server{ Addr: localAddress.String(), Handler: http.HandlerFunc(s.handle), }, NoSignalHandling: true, } // Setup server TLS configuration if tlsCert != "" && tlsKey != "" { cert, err := tls.X509KeyPair( []byte(tlsCert), []byte(tlsKey), ) if err != nil { return nil, err } s.server.TLSConfig = &tls.Config{ NextProtos: []string{"http/1.1"}, Certificates: []tls.Certificate{cert}, } } // Construct hostname (using stateless-dns-go) host := hostname.New( publicIP, subdomain, time.Now().Add(expiration), dnsSecret, ) // Construct URL proto := "http" port := "" if s.server.TLSConfig != nil { proto = "https" if publicPort != 443 { port = fmt.Sprintf(":%d", publicPort) } } else { if publicPort != 80 { port = fmt.Sprintf(":%d", publicPort) } } s.url = proto + "://" + host + port + "/" return s, nil }