Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ericchiang committed Jul 26, 2016
0 parents commit cab271f
Show file tree
Hide file tree
Showing 1,438 changed files with 335,968 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bin
dist
55 changes: 55 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
PROJ="poke"
ORG_PATH="github.com/coreos"
REPO_PATH="$(ORG_PATH)/$(PROJ)"

export GOBIN=$(PWD)/bin
export GO15VENDOREXPERIMENT=1

GOOS=$(shell go env GOOS)
GOARCH=$(shell go env GOARCH)

COMMIT=$(shell git rev-parse HEAD)

# check if the current commit has a matching tag
TAG=$(shell git describe --exact-match --abbrev=0 --tags $(COMMIT) 2> /dev/null || true)

ifeq ($(TAG),)
VERSION=$(TAG)
else
VERSION=$(COMMIT)
endif


build: bin/poke bin/pokectl

bin/poke: FORCE
@go install $(REPO_PATH)/cmd/poke

bin/pokectl: FORCE
@go install $(REPO_PATH)/cmd/pokectl

test:
@go test -v $(shell go list ./... | grep -v '/vendor/')

testrace:
@go test -v --race $(shell go list ./... | grep -v '/vendor/')

vet:
@go vet $(shell go list ./... | grep -v '/vendor/')

fmt:
@go fmt $(shell go list ./... | grep -v '/vendor/')

lint:
@for package in $(shell go list ./... | grep -v '/vendor/'); do \
golint $$package; \
done

clean:
rm bin/poke bin/pokectl

testall: testrace vet fmt lint

FORCE:

.PHONY: test testrace vet fmt lint testall
126 changes: 126 additions & 0 deletions cmd/poke/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package main

import (
"fmt"

"github.com/coreos/poke/connector"
"github.com/coreos/poke/connector/github"
"github.com/coreos/poke/connector/ldap"
"github.com/coreos/poke/connector/mock"
"github.com/coreos/poke/storage"
"github.com/coreos/poke/storage/kubernetes"
)

// Config is the config format for the main application.
type Config struct {
Issuer string `yaml:"issuer"`
Storage Storage `yaml:"storage"`
Connectors []Connector `yaml:"connectors"`
Web Web `yaml:"web"`
}

// Web is the config format for the HTTP server.
type Web struct {
HTTP string `yaml:"http"`
HTTPS string `yaml:"https"`
TLSCert string `yaml:"tlsCert"`
TLSKey string `yaml:"tlsKey"`
}

// Storage holds app's storage configuration.
type Storage struct {
Type string `yaml:"type"`
Config StorageConfig `yaml:"config"`
}

// UnmarshalYAML allows Storage to unmarshal its config field dynamically
// depending on the type of storage.
func (s *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error {
var storageMeta struct {
Type string `yaml:"type"`
}
if err := unmarshal(&storageMeta); err != nil {
return err
}
s.Type = storageMeta.Type
var c struct {
Config StorageConfig `yaml:"config"`
}
switch storageMeta.Type {
case "kubernetes":
c.Config = &kubernetes.Config{}
default:
return fmt.Errorf("unknown storage type %q", storageMeta.Type)
}
if err := unmarshal(c); err != nil {
return err
}
s.Config = c.Config
return nil
}

// StorageConfig is a configuration that can create a storage.
type StorageConfig interface {
Open() (storage.Storage, error)
}

// Connector is a magical type that can unmarshal YAML dynamically. The
// Type field determines the connector type, which is then customized for Config.
type Connector struct {
Type string `yaml:"type"`
Name string `yaml:"name"`
ID string `yaml:"id"`

Config ConnectorConfig `yaml:"config"`
}

// ConnectorConfig is a configuration that can open a connector.
type ConnectorConfig interface {
Open() (connector.Connector, error)
}

// UnmarshalYAML allows Connector to unmarshal its config field dynamically
// depending on the type of connector.
func (c *Connector) UnmarshalYAML(unmarshal func(interface{}) error) error {
var connectorMetadata struct {
Type string `yaml:"type"`
Name string `yaml:"name"`
ID string `yaml:"id"`
}
if err := unmarshal(&connectorMetadata); err != nil {
return err
}
c.Type = connectorMetadata.Type
c.Name = connectorMetadata.Name
c.ID = connectorMetadata.ID

switch c.Type {
case "mock":
var config struct {
Config mock.Config `yaml:"config"`
}
if err := unmarshal(&config); err != nil {
return err
}
c.Config = &config.Config
case "ldap":
var config struct {
Config ldap.Config `yaml:"config"`
}
if err := unmarshal(&config); err != nil {
return err
}
c.Config = &config.Config
case "github":
var config struct {
Config github.Config `yaml:"config"`
}
if err := unmarshal(&config); err != nil {
return err
}
c.Config = &config.Config
default:
return fmt.Errorf("unknown connector type %q", c.Type)
}
return nil
}
1 change: 1 addition & 0 deletions cmd/poke/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main
28 changes: 28 additions & 0 deletions cmd/poke/poke.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

func commandRoot() *cobra.Command {
rootCmd := &cobra.Command{
Use: "poke",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
os.Exit(2)
},
}
rootCmd.AddCommand(commandServe())
rootCmd.AddCommand(commandVersion())
return rootCmd
}

func main() {
if err := commandRoot().Execute(); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(2)
}
}
111 changes: 111 additions & 0 deletions cmd/poke/serve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package main

import (
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"

yaml "gopkg.in/yaml.v2"

"github.com/coreos/poke/server"
"github.com/spf13/cobra"
)

func commandServe() *cobra.Command {
return &cobra.Command{
Use: "serve [ config file ]",
Short: "Connect to the storage and begin serving requests.",
Long: ``,
Example: "poke serve c.yaml",
RunE: serve,
}
}

func serve(cmd *cobra.Command, args []string) error {
switch len(args) {
default:
return errors.New("surplus arguments")
case 0:
// TODO(ericchiang): Consider having a default config file location.
return errors.New("no config file specified")
case 1:
}

configFile := args[0]
configData, err := ioutil.ReadFile(configFile)
if err != nil {
return fmt.Errorf("read config file %s: %v", configFile, err)
}

var c Config
if err := yaml.Unmarshal(configData, &c); err != nil {
return fmt.Errorf("parse config file %s: %v", configFile, err)
}

// Fast checks. Perform these first for a more responsive CLI.
checks := []struct {
bad bool
errMsg string
}{
{c.Issuer == "", "no issuer specified in config file"},
{len(c.Connectors) == 0, "no connectors supplied in config file"},
{c.Storage.Config == nil, "no storage suppied in config file"},
{c.Web.HTTP == "" && c.Web.HTTPS == "", "must supply a HTTP/HTTPS address to listen on"},
{c.Web.HTTPS != "" && c.Web.TLSCert == "", "no cert specified for HTTPS"},
{c.Web.HTTPS != "" && c.Web.TLSKey == "", "no private key specified for HTTPS"},
}

for _, check := range checks {
if check.bad {
return errors.New(check.errMsg)
}
}

connectors := make([]server.Connector, len(c.Connectors))
for i, conn := range c.Connectors {
if conn.Config == nil {
return fmt.Errorf("no config field for connector %q", conn.ID)
}
c, err := conn.Config.Open()
if err != nil {
return fmt.Errorf("open %s: %v", conn.ID, err)
}
connectors[i] = server.Connector{
ID: conn.ID,
DisplayName: conn.Name,
Connector: c,
}
}

s, err := c.Storage.Config.Open()
if err != nil {
return fmt.Errorf("initializing storage: %v", err)
}

serverConfig := server.Config{
Issuer: c.Issuer,
Connectors: connectors,
Storage: s,
}

serv, err := server.New(serverConfig)
if err != nil {
return fmt.Errorf("initializing server: %v", err)
}
errc := make(chan error, 2)
if c.Web.HTTP != "" {
go func() {
log.Printf("listening on %s", c.Web.HTTP)
errc <- http.ListenAndServe(c.Web.HTTP, serv)
}()
}
if c.Web.HTTPS != "" {
go func() {
log.Printf("listening on %s", c.Web.HTTPS)
errc <- http.ListenAndServeTLS(c.Web.HTTPS, c.Web.TLSCert, c.Web.TLSKey, serv)
}()
}
return <-errc
}
19 changes: 19 additions & 0 deletions cmd/poke/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"fmt"
"runtime"

"github.com/coreos/poke/version"
"github.com/spf13/cobra"
)

func commandVersion() *cobra.Command {
return &cobra.Command{
Use: "version",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf(`v%s %s %s %s
`, version.Version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
},
}
}
24 changes: 24 additions & 0 deletions cmd/pokectl/pokectl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "pokectl",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}

func init() {}

func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
}
Loading

0 comments on commit cab271f

Please sign in to comment.