auth

Paddy 2015-06-29 Parent:b0d1b3e39fc8 Child:4b68bac597b7

176:fc68085eb40d Go to Latest

auth/client/client.go

Add kubernetes definitions. Define a replication controller that will spin up authd servers (using Ducky right now--other instances should rename the ducky parts appropriately). Also, my understanding of which labels go where may be shaky, which is probably evidenced by the fact that all of these things share the same lables. _Whatever_. It also hooks the generated pods up to the JWT secret volume, so they can properly read the JWT secret. Also, created a LoadBalancer Service that will route traffic to the pods created by the Replication Controller.

History
paddy@172 1 package client
paddy@172 2
paddy@172 3 import (
paddy@172 4 "bytes"
paddy@172 5 "encoding/json"
paddy@172 6 "errors"
paddy@172 7 "io"
paddy@172 8 "net/http"
paddy@172 9 "strings"
paddy@173 10 "time"
paddy@172 11
paddy@172 12 "code.secondbit.org/auth.hg"
paddy@173 13 "code.secondbit.org/uuid.hg"
paddy@172 14 )
paddy@172 15
paddy@172 16 var (
paddy@172 17 ErrNilClient = errors.New("nil client wrapper")
paddy@172 18 ErrNilHTTPClient = errors.New("nil client")
paddy@172 19 )
paddy@172 20
paddy@172 21 type Client struct {
paddy@172 22 client *http.Client
paddy@172 23 address string
paddy@173 24 ID uuid.ID
paddy@172 25 }
paddy@172 26
paddy@173 27 func New(address string, id uuid.ID) *Client {
paddy@172 28 address = strings.TrimRight(address, "/")
paddy@172 29 return &Client{
paddy@172 30 address: address,
paddy@172 31 client: &http.Client{},
paddy@173 32 ID: id,
paddy@172 33 }
paddy@172 34 }
paddy@172 35
paddy@173 36 func (c *Client) do(method, url string, request interface{}, scopes []string, subject uuid.ID) (auth.Response, error) {
paddy@172 37 if c == nil {
paddy@172 38 return auth.Response{}, ErrNilClient
paddy@172 39 }
paddy@172 40 if c.client == nil {
paddy@172 41 return auth.Response{}, ErrNilHTTPClient
paddy@172 42 }
paddy@172 43 var response auth.Response
paddy@172 44 if !strings.HasPrefix(url, "http") {
paddy@172 45 url = strings.TrimLeft(url, "/")
paddy@172 46 url = "/" + url
paddy@172 47 url = c.address + url
paddy@172 48 }
paddy@172 49 var body io.Reader
paddy@172 50 if request != nil {
paddy@172 51 data, err := json.Marshal(request)
paddy@172 52 if err != nil {
paddy@172 53 return response, err
paddy@172 54 }
paddy@172 55 body = bytes.NewBuffer(data)
paddy@172 56 }
paddy@172 57 req, err := http.NewRequest(method, url, body)
paddy@172 58 if err != nil {
paddy@172 59 return response, err
paddy@172 60 }
paddy@173 61 req.Header.Set("Ducky-Scope", strings.Join(scopes, " "))
paddy@173 62 req.Header.Set("Ducky-Issuer", c.ID.String())
paddy@173 63 if subject != nil {
paddy@173 64 req.Header.Set("Ducky-Subject", subject.String())
paddy@173 65 }
paddy@173 66 req.Header.Set("Ducky-Expires", time.Now().Add(time.Hour).String())
paddy@173 67 req.Header.Set("Ducky-Issued-At", time.Now().String())
paddy@173 68 req.Header.Set("Ducky-Not-Before", time.Now().Add(-5*time.Minute).String())
paddy@172 69 resp, err := c.client.Do(req)
paddy@172 70 if err != nil {
paddy@172 71 return response, err
paddy@172 72 }
paddy@172 73 defer resp.Body.Close()
paddy@172 74 switch resp.Header.Get("Content-Type") {
paddy@172 75 case "application/json":
paddy@172 76 dec := json.NewDecoder(resp.Body)
paddy@172 77 err = dec.Decode(&response)
paddy@172 78 if err != nil {
paddy@172 79 return response, err
paddy@172 80 }
paddy@172 81 default:
paddy@172 82 dec := json.NewDecoder(resp.Body)
paddy@172 83 err = dec.Decode(&response)
paddy@172 84 if err != nil {
paddy@172 85 return response, err
paddy@172 86 }
paddy@172 87 }
paddy@172 88 return response, nil
paddy@172 89 }
paddy@172 90
paddy@173 91 func (c *Client) Get(url string, scopes []string, subject uuid.ID) (auth.Response, error) {
paddy@173 92 return c.do("GET", url, nil, scopes, subject)
paddy@172 93 }