Example #1
0
func TestToken(t *testing.T) {
	token := "toooookkkkkeeeeennnnnn"
	upgrade := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		tok := r.Header.Get("Authorization")
		if tok != "Scope-Probe token="+token {
			t.Fatal("Did not get authorisation header, got: " + tok)
		}
		_, err := Upgrade(w, r, nil)
		if err != nil {
			t.Fatal(err)
		}
	})

	srv := httptest.NewServer(upgrade)
	defer srv.Close()

	url, _ := url.Parse(srv.URL)
	url.Scheme = "ws"

	ws, err := Dial(http.DefaultClient, flux.Token(token), url)
	if err != nil {
		t.Fatal(err)
	}
	defer ws.Close()
}
Example #2
0
func (opts *rootOpts) PersistentPreRunE(cmd *cobra.Command, _ []string) error {
	opts.URL = getFromEnvIfNotSet(cmd.Flags(), "url", envVariableURL, opts.URL)
	if _, err := url.Parse(opts.URL); err != nil {
		return errors.Wrapf(err, "parsing URL")
	}
	opts.Token = getFromEnvIfNotSet(cmd.Flags(), "token", envVariableToken, opts.Token)
	opts.API = transport.NewClient(http.DefaultClient, transport.NewRouter(), opts.URL, flux.Token(opts.Token))
	return nil
}
Example #3
0
func TestByteStream(t *testing.T) {
	mx := sync.Mutex{}
	buf := &bytes.Buffer{}
	upgrade := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ws, err := Upgrade(w, r, nil)
		if err != nil {
			t.Fatal(err)
		}
		mx.Lock()
		defer mx.Unlock()
		if _, err := io.Copy(buf, ws); err != nil {
			t.Fatal(err)
		}
	})

	srv := httptest.NewServer(upgrade)

	url, _ := url.Parse(srv.URL)
	url.Scheme = "ws"

	ws, err := Dial(http.DefaultClient, flux.Token(""), url)
	if err != nil {
		t.Fatal(err)
	}

	checkWrite := func(msg string) {
		if _, err := ws.Write([]byte(msg)); err != nil {
			t.Fatal(err)
		}
	}

	checkWrite("hey")
	checkWrite(" there")
	checkWrite(" champ")
	if err := ws.Close(); err != nil {
		t.Fatal(err)
	}

	// Make sure the server reads everything from the connection
	srv.Close()
	mx.Lock()
	defer mx.Unlock()
	if buf.String() != "hey there champ" {
		t.Fatalf("did not collect message as expected, got %s", buf.String())
	}
}
Example #4
0
func main() {
	// Flag domain.
	fs := pflag.NewFlagSet("default", pflag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "DESCRIPTION\n")
		fmt.Fprintf(os.Stderr, "  fluxd is the agent of flux.\n")
		fmt.Fprintf(os.Stderr, "\n")
		fmt.Fprintf(os.Stderr, "FLAGS\n")
		fs.PrintDefaults()
	}
	// This mirrors how kubectl extracts information from the environment.
	var (
		listenAddr        = fs.StringP("listen", "l", ":3031", "Listen address where /metrics will be served")
		fluxsvcAddress    = fs.String("fluxsvc-address", "wss://cloud.weave.works/api/flux", "Address of the fluxsvc to connect to.")
		token             = fs.String("token", "", "Token to use to authenticate with flux service")
		kubernetesKubectl = fs.String("kubernetes-kubectl", "", "Optional, explicit path to kubectl tool")
	)
	fs.Parse(os.Args)

	// Logger component.
	var logger log.Logger
	{
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
		logger = log.NewContext(logger).With("caller", log.DefaultCaller)
	}

	// Platform component.
	var k8s platform.Platform
	{
		restClientConfig, err := restclient.InClusterConfig()
		if err != nil {
			logger.Log("err", err)
			os.Exit(1)
		}

		// When adding a new platform, don't just bash it in. Create a Platform
		// or Cluster interface in package platform, and have kubernetes.Cluster
		// and your new platform implement that interface.
		logger := log.NewContext(logger).With("component", "platform")
		logger.Log("host", restClientConfig.Host)

		cluster, err := kubernetes.NewCluster(restClientConfig, *kubernetesKubectl, logger)
		if err != nil {
			logger.Log("err", err)
			os.Exit(1)
		}

		if services, err := cluster.AllServices("", nil); err != nil {
			logger.Log("services", err)
		} else {
			logger.Log("services", len(services))
		}

		k8s = cluster
	}

	// Instrumentation
	var (
		daemonMetrics transport.DaemonMetrics
	)
	{
		k8s = platform.Instrument(k8s, platform.NewMetrics())
		daemonMetrics.ConnectionDuration = prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
			Namespace: "flux",
			Subsystem: "fluxd",
			Name:      "connection_duration_seconds",
			Help:      "Duration in seconds of the current connection to fluxsvc. Zero means unconnected.",
		}, []string{"target"})
	}

	// Connect to fluxsvc
	daemonLogger := log.NewContext(logger).With("component", "client")
	daemon, err := transport.NewDaemon(
		http.DefaultClient,
		flux.Token(*token),
		transport.NewRouter(),
		*fluxsvcAddress,
		k8s,
		daemonLogger,
		daemonMetrics,
	)
	if err != nil {
		logger.Log("err", err)
		os.Exit(1)
	}
	defer daemon.Close()

	// Mechanical components.
	errc := make(chan error)
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errc <- fmt.Errorf("%s", <-c)
	}()

	// HTTP transport component, for metrics
	go func() {
		logger.Log("addr", *listenAddr)
		mux := http.NewServeMux()
		mux.Handle("/metrics", promhttp.Handler())
		errc <- http.ListenAndServe(*listenAddr, mux)
	}()

	// Go!
	logger.Log("exiting", <-errc)
}