<commit_before>package gaurun

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"github.com/RobotsAndPencils/buford/payload"
	"github.com/RobotsAndPencils/buford/payload/badge"
	"github.com/RobotsAndPencils/buford/push"

	"golang.org/x/net/http2"
)

func NewTransportHttp2(cert tls.Certificate) (*http.Transport, error) {
	config := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}
	config.BuildNameToCertificate()

	transport := &http.Transport{
		TLSClientConfig:     config,
		MaxIdleConnsPerHost: ConfGaurun.Ios.KeepAliveConns,
		Dial: (&net.Dialer{
			Timeout:   time.Duration(ConfGaurun.Ios.Timeout) * time.Second,
			KeepAlive: time.Duration(keepAliveInterval(ConfGaurun.Ios.KeepAliveTimeout)) * time.Second,
		}).Dial,
		IdleConnTimeout: time.Duration(ConfGaurun.Ios.KeepAliveTimeout) * time.Second,
	}

	if err := http2.ConfigureTransport(transport); err != nil {
		return nil, err
	}

	return transport, nil
}

func NewApnsClientHttp2(certPath, keyPath, keyPassphrase string) (*http.Client, error) {
	cert, err := loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase)
	if err != nil {
		return nil, err
	}

	transport, err := NewTransportHttp2(cert)
	if err != nil {
		return nil, err
	}

	return &http.Client{
		Transport: transport,
		Timeout:   time.Duration(ConfGaurun.Ios.Timeout) * time.Second,
	}, nil
}

func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.Certificate, error) {
	keyPEMBlock, err := ioutil.ReadFile(keyPath)
	if err != nil {
		return tls.Certificate{}, err
	}
	if keyPassphrase != "" {
		pemBlock, _ := pem.Decode(keyPEMBlock)
		keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase))
		if err != nil {
			return tls.Certificate{}, err
		}
		keyPEMBlock = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyPEMBlock})
	}
	certPEMBlock, err := ioutil.ReadFile(certPath)
	if err != nil {
		return tls.Certificate{}, err
	}
	cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
	if err != nil {
		return tls.Certificate{}, err
	}
	return cert, nil
}

func NewApnsServiceHttp2(client *http.Client) *push.Service {
	var host string
	if ConfGaurun.Ios.Sandbox {
		host = push.Development
	} else {
		host = push.Production
	}
	return &push.Service{
		Client: client,
		Host:   host,
	}
}

func NewApnsPayloadHttp2(req *RequestGaurunNotification) map[string]interface{} {
	p := payload.APS{
		Alert:            payload.Alert{Title: req.Title, Body: req.Message, Subtitle: req.Subtitle},
		Badge:            badge.New(uint(req.Badge)),
		Category:         req.Category,
		Sound:            req.Sound,
		ContentAvailable: req.ContentAvailable,
		MutableContent:   req.MutableContent,
	}

	pm := p.Map()

	if len(req.Extend) > 0 {
		for _, extend := range req.Extend {
			pm[extend.Key] = extend.Value
		}
	}

	return pm
}

func NewApnsHeadersHttp2(req *RequestGaurunNotification) *push.Headers {
	headers := &push.Headers{
		Topic: ConfGaurun.Ios.Topic,
	}

	if req.Expiry > 0 {
		headers.Expiration = time.Now().Add(time.Duration(int64(req.Expiry)) * time.Second).UTC()
	}

	return headers
}

func ApnsPushHttp2(token string, service *push.Service, headers *push.Headers, payload map[string]interface{}) error {
	b, err := json.Marshal(payload)
	if err != nil {
		return err
	}
	_, err = service.Push(token, headers, b)
	return err
}
<commit_msg>issue-98 add error message when pem_key_passphrase is not require<commit_after>package gaurun

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"github.com/RobotsAndPencils/buford/payload"
	"github.com/RobotsAndPencils/buford/payload/badge"
	"github.com/RobotsAndPencils/buford/push"

	"golang.org/x/net/http2"
)

func NewTransportHttp2(cert tls.Certificate) (*http.Transport, error) {
	config := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}
	config.BuildNameToCertificate()

	transport := &http.Transport{
		TLSClientConfig:     config,
		MaxIdleConnsPerHost: ConfGaurun.Ios.KeepAliveConns,
		Dial: (&net.Dialer{
			Timeout:   time.Duration(ConfGaurun.Ios.Timeout) * time.Second,
			KeepAlive: time.Duration(keepAliveInterval(ConfGaurun.Ios.KeepAliveTimeout)) * time.Second,
		}).Dial,
		IdleConnTimeout: time.Duration(ConfGaurun.Ios.KeepAliveTimeout) * time.Second,
	}

	if err := http2.ConfigureTransport(transport); err != nil {
		return nil, err
	}

	return transport, nil
}

func NewApnsClientHttp2(certPath, keyPath, keyPassphrase string) (*http.Client, error) {
	cert, err := loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase)
	if err != nil {
		return nil, err
	}

	transport, err := NewTransportHttp2(cert)
	if err != nil {
		return nil, err
	}

	return &http.Client{
		Transport: transport,
		Timeout:   time.Duration(ConfGaurun.Ios.Timeout) * time.Second,
	}, nil
}

func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.Certificate, error) {
	keyPEMBlock, err := ioutil.ReadFile(keyPath)
	if err != nil {
		return tls.Certificate{}, err
	}
	if keyPassphrase != "" {
		pemBlock, _ := pem.Decode(keyPEMBlock)
		if !x509.IsEncryptedPEMBlock(pemBlock) {
			err = errors.New(keyPath + "is not encrypted. passphrase is not required")
			return tls.Certificate{}, err
		}
		keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase))
		if err != nil {
			return tls.Certificate{}, err
		}
		keyPEMBlock = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyPEMBlock})
	}
	certPEMBlock, err := ioutil.ReadFile(certPath)
	if err != nil {
		return tls.Certificate{}, err
	}
	cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
	if err != nil {
		return tls.Certificate{}, err
	}
	return cert, nil
}

func NewApnsServiceHttp2(client *http.Client) *push.Service {
	var host string
	if ConfGaurun.Ios.Sandbox {
		host = push.Development
	} else {
		host = push.Production
	}
	return &push.Service{
		Client: client,
		Host:   host,
	}
}

func NewApnsPayloadHttp2(req *RequestGaurunNotification) map[string]interface{} {
	p := payload.APS{
		Alert:            payload.Alert{Title: req.Title, Body: req.Message, Subtitle: req.Subtitle},
		Badge:            badge.New(uint(req.Badge)),
		Category:         req.Category,
		Sound:            req.Sound,
		ContentAvailable: req.ContentAvailable,
		MutableContent:   req.MutableContent,
	}

	pm := p.Map()

	if len(req.Extend) > 0 {
		for _, extend := range req.Extend {
			pm[extend.Key] = extend.Value
		}
	}

	return pm
}

func NewApnsHeadersHttp2(req *RequestGaurunNotification) *push.Headers {
	headers := &push.Headers{
		Topic: ConfGaurun.Ios.Topic,
	}

	if req.Expiry > 0 {
		headers.Expiration = time.Now().Add(time.Duration(int64(req.Expiry)) * time.Second).UTC()
	}

	return headers
}

func ApnsPushHttp2(token string, service *push.Service, headers *push.Headers, payload map[string]interface{}) error {
	b, err := json.Marshal(payload)
	if err != nil {
		return err
	}
	_, err = service.Push(token, headers, b)
	return err
}
<|endoftext|>


<commit_before>// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"testing"
)

func TestAdminService_UpdateUserLDAPMapping(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := &UserLDAPMapping{
		LDAPDN: String("uid=asdf,ou=users,dc=github,dc=com"),
	}

	mux.HandleFunc("/admin/ldap/users/u/mapping", func(w http.ResponseWriter, r *http.Request) {
		v := new(UserLDAPMapping)
		json.NewDecoder(r.Body).Decode(v)

		testMethod(t, r, "PATCH")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
		fmt.Fprint(w, `{"id":1,"ldap_dn":"uid=asdf,ou=users,dc=github,dc=com"}`)
	})

	mapping, _, err := client.Admin.UpdateUserLDAPMapping(context.Background(), "u", input)
	if err != nil {
		t.Errorf("Admin.UpdateUserLDAPMapping returned error: %v", err)
	}

	want := &UserLDAPMapping{
		ID:     Int64(1),
		LDAPDN: String("uid=asdf,ou=users,dc=github,dc=com"),
	}
	if !reflect.DeepEqual(mapping, want) {
		t.Errorf("Admin.UpdateUserLDAPMapping returned %+v, want %+v", mapping, want)
	}
}

func TestAdminService_UpdateTeamLDAPMapping(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := &TeamLDAPMapping{
		LDAPDN: String("cn=Enterprise Ops,ou=teams,dc=github,dc=com"),
	}

	mux.HandleFunc("/admin/ldap/teams/1/mapping", func(w http.ResponseWriter, r *http.Request) {
		v := new(TeamLDAPMapping)
		json.NewDecoder(r.Body).Decode(v)

		testMethod(t, r, "PATCH")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
		fmt.Fprint(w, `{"id":1,"ldap_dn":"cn=Enterprise Ops,ou=teams,dc=github,dc=com"}`)
	})

	mapping, _, err := client.Admin.UpdateTeamLDAPMapping(context.Background(), 1, input)
	if err != nil {
		t.Errorf("Admin.UpdateTeamLDAPMapping returned error: %v", err)
	}

	want := &TeamLDAPMapping{
		ID:     Int64(1),
		LDAPDN: String("cn=Enterprise Ops,ou=teams,dc=github,dc=com"),
	}
	if !reflect.DeepEqual(mapping, want) {
		t.Errorf("Admin.UpdateTeamLDAPMapping returned %+v, want %+v", mapping, want)
	}
}
<commit_msg>Coverage: admin.go (#1195)<commit_after>// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"testing"
	"time"
)

func TestAdminService_UpdateUserLDAPMapping(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := &UserLDAPMapping{
		LDAPDN: String("uid=asdf,ou=users,dc=github,dc=com"),
	}

	mux.HandleFunc("/admin/ldap/users/u/mapping", func(w http.ResponseWriter, r *http.Request) {
		v := new(UserLDAPMapping)
		json.NewDecoder(r.Body).Decode(v)

		testMethod(t, r, "PATCH")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
		fmt.Fprint(w, `{"id":1,"ldap_dn":"uid=asdf,ou=users,dc=github,dc=com"}`)
	})

	ctx := context.Background()
	mapping, _, err := client.Admin.UpdateUserLDAPMapping(ctx, "u", input)
	if err != nil {
		t.Errorf("Admin.UpdateUserLDAPMapping returned error: %v", err)
	}

	want := &UserLDAPMapping{
		ID:     Int64(1),
		LDAPDN: String("uid=asdf,ou=users,dc=github,dc=com"),
	}
	if !reflect.DeepEqual(mapping, want) {
		t.Errorf("Admin.UpdateUserLDAPMapping returned %+v, want %+v", mapping, want)
	}

	// Test s.client.NewRequest failure
	client.BaseURL.Path = ""
	got, resp, err := client.Admin.UpdateUserLDAPMapping(ctx, "u", input)
	if got != nil {
		t.Errorf("client.BaseURL.Path='' UpdateUserLDAPMapping = %#v, want nil", got)
	}
	if resp != nil {
		t.Errorf("client.BaseURL.Path='' UpdateUserLDAPMapping resp = %#v, want nil", resp)
	}
	if err == nil {
		t.Error("client.BaseURL.Path='' UpdateUserLDAPMapping err = nil, want error")
	}

	// Test s.client.Do failure
	client.BaseURL.Path = "/api-v3/"
	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
	got, resp, err = client.Admin.UpdateUserLDAPMapping(ctx, "u", input)
	if got != nil {
		t.Errorf("rate.Reset.Time > now UpdateUserLDAPMapping = %#v, want nil", got)
	}
	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
		t.Errorf("rate.Reset.Time > now UpdateUserLDAPMapping resp = %#v, want StatusCode=%v", resp.Response, want)
	}
	if err == nil {
		t.Error("rate.Reset.Time > now UpdateUserLDAPMapping err = nil, want error")
	}
}

func TestAdminService_UpdateTeamLDAPMapping(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := &TeamLDAPMapping{
		LDAPDN: String("cn=Enterprise Ops,ou=teams,dc=github,dc=com"),
	}

	mux.HandleFunc("/admin/ldap/teams/1/mapping", func(w http.ResponseWriter, r *http.Request) {
		v := new(TeamLDAPMapping)
		json.NewDecoder(r.Body).Decode(v)

		testMethod(t, r, "PATCH")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
		fmt.Fprint(w, `{"id":1,"ldap_dn":"cn=Enterprise Ops,ou=teams,dc=github,dc=com"}`)
	})

	ctx := context.Background()
	mapping, _, err := client.Admin.UpdateTeamLDAPMapping(ctx, 1, input)
	if err != nil {
		t.Errorf("Admin.UpdateTeamLDAPMapping returned error: %v", err)
	}

	want := &TeamLDAPMapping{
		ID:     Int64(1),
		LDAPDN: String("cn=Enterprise Ops,ou=teams,dc=github,dc=com"),
	}
	if !reflect.DeepEqual(mapping, want) {
		t.Errorf("Admin.UpdateTeamLDAPMapping returned %+v, want %+v", mapping, want)
	}

	// Test s.client.NewRequest failure
	client.BaseURL.Path = ""
	got, resp, err := client.Admin.UpdateTeamLDAPMapping(ctx, 1, input)
	if got != nil {
		t.Errorf("client.BaseURL.Path='' UpdateTeamLDAPMapping = %#v, want nil", got)
	}
	if resp != nil {
		t.Errorf("client.BaseURL.Path='' UpdateTeamLDAPMapping resp = %#v, want nil", resp)
	}
	if err == nil {
		t.Error("client.BaseURL.Path='' UpdateTeamLDAPMapping err = nil, want error")
	}

	// Test s.client.Do failure
	client.BaseURL.Path = "/api-v3/"
	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
	got, resp, err = client.Admin.UpdateTeamLDAPMapping(ctx, 1, input)
	if got != nil {
		t.Errorf("rate.Reset.Time > now UpdateTeamLDAPMapping = %#v, want nil", got)
	}
	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
		t.Errorf("rate.Reset.Time > now UpdateTeamLDAPMapping resp = %#v, want StatusCode=%v", resp.Response, want)
	}
	if err == nil {
		t.Error("rate.Reset.Time > now UpdateTeamLDAPMapping err = nil, want error")
	}
}

func TestAdminService_TeamLDAPMapping_String(t *testing.T) {
	v := &TeamLDAPMapping{
		ID:              Int64(1),
		LDAPDN:          String("a"),
		URL:             String("b"),
		Name:            String("c"),
		Slug:            String("d"),
		Description:     String("e"),
		Privacy:         String("f"),
		Permission:      String("g"),
		MembersURL:      String("h"),
		RepositoriesURL: String("i"),
	}

	want := `github.TeamLDAPMapping{ID:1, LDAPDN:"a", URL:"b", Name:"c", Slug:"d", Description:"e", Privacy:"f", Permission:"g", MembersURL:"h", RepositoriesURL:"i"}`
	if got := v.String(); got != want {
		t.Errorf("TeamLDAPMapping.String = `%v`, want `%v`", got, want)
	}
}

func TestAdminService_UserLDAPMapping_String(t *testing.T) {
	v := &UserLDAPMapping{
		ID:                Int64(1),
		LDAPDN:            String("a"),
		Login:             String("b"),
		AvatarURL:         String("c"),
		GravatarID:        String("d"),
		Type:              String("e"),
		SiteAdmin:         Bool(true),
		URL:               String("f"),
		EventsURL:         String("g"),
		FollowingURL:      String("h"),
		FollowersURL:      String("i"),
		GistsURL:          String("j"),
		OrganizationsURL:  String("k"),
		ReceivedEventsURL: String("l"),
		ReposURL:          String("m"),
		StarredURL:        String("n"),
		SubscriptionsURL:  String("o"),
	}

	want := `github.UserLDAPMapping{ID:1, LDAPDN:"a", Login:"b", AvatarURL:"c", GravatarID:"d", Type:"e", SiteAdmin:true, URL:"f", EventsURL:"g", FollowingURL:"h", FollowersURL:"i", GistsURL:"j", OrganizationsURL:"k", ReceivedEventsURL:"l", ReposURL:"m", StarredURL:"n", SubscriptionsURL:"o"}`
	if got := v.String(); got != want {
		t.Errorf("UserLDAPMapping.String = `%v`, want `%v`", got, want)
	}
}
<|endoftext|>


<commit_before>package master

import (
	"bytes"
	"compress/gzip"
	"encoding/gob"
	"errors"
	"os"
	"path/filepath"
	"sync"
	"time"

	log "github.com/sirupsen/logrus"

	"github.com/PaddlePaddle/recordio"
)

const (
	dialTimeout = 5 * time.Second
)

// Store is the interface for save and load the master state.
type Store interface {
	Save([]byte) error
	Load() ([]byte, error)
}

// Chunk is a chunk of data consisted of several data instances.
type Chunk struct {
	Path  string
	Index recordio.Index // chunk index
}

// Task is the basic unit of data instances assigned to trainers.
type Task struct {
	ID     int
	Chunks []Chunk
}

type taskEntry struct {
	Epoch      int
	NumTimeout int
	Task       Task
}

type taskQueues struct {
	Todo    []taskEntry
	Pending map[int]taskEntry // map from task ID to task entry
	Done    []taskEntry
	Failed  []Task
}

// Service is the master server service.
type Service struct {
	chunksPerTask int
	timeoutDur    time.Duration
	timeoutMax    int
	ready         chan struct{}
	store         Store

	mu         sync.Mutex
	initDone   bool
	taskQueues taskQueues
}

func partition(chunks []Chunk, chunksPerTask int) []taskEntry {
	id := 0
	if chunksPerTask <= 0 {
		chunksPerTask = 1
	}

	var result []taskEntry
	var cur taskEntry
	for i, c := range chunks {
		if i%chunksPerTask == 0 && len(cur.Task.Chunks) > 0 {
			cur.Task.ID = id
			id++
			result = append(result, cur)
			cur.Task.Chunks = nil
		}

		cur.Task.Chunks = append(cur.Task.Chunks, c)
	}

	if len(cur.Task.Chunks) > 0 {
		cur.Task.ID = id
		result = append(result, cur)
	}

	return result
}

// NewService creates a new service.
func NewService(store Store, chunksPerTask int, timeoutDur time.Duration, timeoutMax int) (*Service, error) {
	s := &Service{}
	s.chunksPerTask = chunksPerTask
	s.timeoutDur = timeoutDur
	s.timeoutMax = timeoutMax
	s.taskQueues = taskQueues{}
	s.taskQueues.Pending = make(map[int]taskEntry)
	s.ready = make(chan struct{})
	s.store = store
	recovered, err := s.recover()
	if err != nil {
		return nil, err
	}

	if recovered {
		// Recovered. Now the state is already initialized,
		// and the master is ready.
		s.initDone = true
		close(s.ready)
	}

	return s, nil
}

// recover recovers service state from etcd.
func (s *Service) recover() (bool, error) {
	state, err := s.store.Load()
	if err != nil {
		return false, err
	}

	if state == nil {
		log.Infoln("No state exists, not recovered.")
		return false, nil
	}

	log.Infof("Loaded snapshot of size: %d bytes.", len(state))
	gr, err := gzip.NewReader(bytes.NewReader(state))
	if err != nil {
		return false, err
	}

	dec := gob.NewDecoder(gr)
	var tqs taskQueues
	err = dec.Decode(&tqs)
	if err != nil {
		return false, err
	}

	err = gr.Close()
	if err != nil {
		// Only close failed, recover actually succeed, so
		// just log error.
		log.Errorln(err)
	}

	s.taskQueues = tqs
	return true, nil
}

// snapshot *must* be called with s.mu being held.
func (s *Service) snapshot() error {
	// TOOD(helin): etcd request has a size limit, so the snapshot
	// size is limited by the max request size. We should either
	// divide the snapshot into smaller chunks and save under
	// different keys, or configure the request size to be big
	// enough:
	// https://github.com/coreos/etcd/blob/2f84f3d8d8ed8f9537ab6ffa44a3a1c7eddfa9b1/embed/config.go#L44
	var buf bytes.Buffer
	gw := gzip.NewWriter(&buf)
	enc := gob.NewEncoder(gw)
	err := enc.Encode(s.taskQueues)
	if err != nil {
		return err
	}
	err = gw.Close()
	if err != nil {
		return err
	}

	state := buf.Bytes()
	log.Infof("Saving snapshot of size: %d bytes.", len(state))
	return s.store.Save(state)
}

func readChunks(globPaths []string) ([]Chunk, error) {
	var chunks []Chunk
	var paths []string

	for _, s := range globPaths {
		match, err := filepath.Glob(s)
		if err != nil {
			return nil, err
		}
		paths = append(paths, match...)
	}

	if len(paths) == 0 {
		return nil, errors.New("no valid dataset specified")
	}

	for _, path := range paths {
		f, err := os.Open(path)
		if err != nil {
			return nil, err
		}

		index, err := recordio.LoadIndex(f)
		if err != nil {
			return nil, err
		}
		err = f.Close()
		if err != nil {
			return nil, err
		}

		count := index.NumChunks()
		for i := 0; i < count; i++ {
			chunk := Chunk{
				Path:  path,
				Index: *index.ChunkIndex(i),
			}
			chunks = append(chunks, chunk)
		}
	}

	return chunks, nil
}

// SetDataset sets dataset to dispatch for the master server.
//
// SetDataset can be call multiple times. But only the first call will
// be honored.
func (s *Service) SetDataset(globPaths []string, dummy *int) error {
	if len(globPaths) == 0 {
		return errors.New("no dataset specified")
	}

	s.mu.Lock()
	defer s.mu.Unlock()
	if s.initDone {
		// Already initialized. All trainer will call
		// SetDataset, but we only handle the first one. Treat
		// other calls as successful but do nothing.
		return nil
	}

	chunks, err := readChunks(globPaths)
	if err != nil {
		return err
	}

	s.taskQueues.Todo = partition(chunks, s.chunksPerTask)

	err = s.snapshot()
	if err != nil {
		log.Errorln(err)
		return err
	}

	close(s.ready)
	s.initDone = true
	return nil
}

func (s *Service) checkTimeoutFunc(taskID int, epoch int) func() {
	return func() {
		s.mu.Lock()
		defer s.mu.Unlock()

		t, ok := s.taskQueues.Pending[taskID]
		if !ok {
			return
		}

		if t.Epoch != epoch {
			// new epoch, task launched after the
			// schedule of this timeout check.
			return
		}

		defer func() {
			err := s.snapshot()
			if err != nil {
				log.Errorln(err)
			}
		}()

		delete(s.taskQueues.Pending, t.Task.ID)

		t.NumTimeout++
		if t.NumTimeout > s.timeoutMax {
			log.Warningf("Task %v timed out %d times, discard.", t.Task, t.NumTimeout)
			s.taskQueues.Failed = append(s.taskQueues.Failed, t.Task)
			return
		}

		log.Warningf("Task %v timed out %d times, retry.", t.Task, t.NumTimeout)
		s.taskQueues.Todo = append(s.taskQueues.Todo, t)
	}
}

// must be called with lock held.
func (s *Service) logFields() log.Fields {
	return log.Fields{
		"todoLen":    len(s.taskQueues.Todo),
		"pendingLen": len(s.taskQueues.Pending),
		"doneLen":    len(s.taskQueues.Done),
		"failedLen":  len(s.taskQueues.Failed),
	}
}

// GetTask gets a new task from the service.
func (s *Service) GetTask(dummy int, task *Task) error {
	select {
	case <-s.ready:
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if len(s.taskQueues.Todo) == 0 {
		if len(s.taskQueues.Done) == 0 {
			if len(s.taskQueues.Pending) == 0 {
				err := errors.New("all task failed")
				log.WithFields(s.logFields()).Warningln("All tasks failed.")
				return err
			}

			// TODO(helin): client need to retry in this
			// error case. Gotcha: RPC client can't
			// compare returned error with predefined
			// errors like io.EOF, because the error
			// instance deserialized from RPC is a
			// different instance than the error defined
			// in package. So we need to figure out a way
			// for client to check this error correctly.
			err := errors.New("no more available task")
			log.WithFields(s.logFields()).Warningln("No more available task.")
			return err
		}
		s.taskQueues.Todo = s.taskQueues.Done
		s.taskQueues.Done = nil
		log.WithFields(s.logFields()).Infoln("No more todo task, but trainer is requesting task to do. Move all done task to todo.")
	}

	t := s.taskQueues.Todo[0]
	t.Epoch++
	s.taskQueues.Todo = s.taskQueues.Todo[1:]
	s.taskQueues.Pending[t.Task.ID] = t
	err := s.snapshot()
	if err != nil {
		return err
	}

	*task = t.Task
	log.WithFields(s.logFields()).Infof("Task #%d dispatched.", task.ID)

	time.AfterFunc(s.timeoutDur, s.checkTimeoutFunc(t.Task.ID, t.Epoch))
	return nil
}

// TaskFinished tell the service that a task is finished.
func (s *Service) TaskFinished(taskID int, dummy *int) error {
	select {
	case <-s.ready:
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	t, ok := s.taskQueues.Pending[taskID]
	if !ok {
		err := errors.New("pending task not found")
		log.WithFields(s.logFields()).Warningln("Pending task #%d not found.", taskID)
		return err
	}

	// task finished, reset timeout
	t.NumTimeout = 0
	s.taskQueues.Done = append(s.taskQueues.Done, t)
	delete(s.taskQueues.Pending, taskID)

	log.WithFields(s.logFields()).Infof("Task #%d finished.", taskID)

	if len(s.taskQueues.Pending) == 0 && len(s.taskQueues.Todo) == 0 {
		log.WithFields(s.logFields()).Infoln("No more todo and pending task, start a new pass.")
		s.taskQueues.Todo = append(s.taskQueues.Todo, s.taskQueues.Done...)
		s.taskQueues.Done = nil
	}

	err := s.snapshot()
	if err != nil {
		log.Errorln(err)
	}
	return err
}
<commit_msg>add log when master recovered from saved state.<commit_after>package master

import (
	"bytes"
	"compress/gzip"
	"encoding/gob"
	"errors"
	"os"
	"path/filepath"
	"sync"
	"time"

	log "github.com/sirupsen/logrus"

	"github.com/PaddlePaddle/recordio"
)

const (
	dialTimeout = 5 * time.Second
)

// Store is the interface for save and load the master state.
type Store interface {
	Save([]byte) error
	Load() ([]byte, error)
}

// Chunk is a chunk of data consisted of several data instances.
type Chunk struct {
	Path  string
	Index recordio.Index // chunk index
}

// Task is the basic unit of data instances assigned to trainers.
type Task struct {
	ID     int
	Chunks []Chunk
}

type taskEntry struct {
	Epoch      int
	NumTimeout int
	Task       Task
}

type taskQueues struct {
	Todo    []taskEntry
	Pending map[int]taskEntry // map from task ID to task entry
	Done    []taskEntry
	Failed  []Task
}

// Service is the master server service.
type Service struct {
	chunksPerTask int
	timeoutDur    time.Duration
	timeoutMax    int
	ready         chan struct{}
	store         Store

	mu         sync.Mutex
	initDone   bool
	taskQueues taskQueues
}

func partition(chunks []Chunk, chunksPerTask int) []taskEntry {
	id := 0
	if chunksPerTask <= 0 {
		chunksPerTask = 1
	}

	var result []taskEntry
	var cur taskEntry
	for i, c := range chunks {
		if i%chunksPerTask == 0 && len(cur.Task.Chunks) > 0 {
			cur.Task.ID = id
			id++
			result = append(result, cur)
			cur.Task.Chunks = nil
		}

		cur.Task.Chunks = append(cur.Task.Chunks, c)
	}

	if len(cur.Task.Chunks) > 0 {
		cur.Task.ID = id
		result = append(result, cur)
	}

	return result
}

// NewService creates a new service.
func NewService(store Store, chunksPerTask int, timeoutDur time.Duration, timeoutMax int) (*Service, error) {
	s := &Service{}
	s.chunksPerTask = chunksPerTask
	s.timeoutDur = timeoutDur
	s.timeoutMax = timeoutMax
	s.taskQueues = taskQueues{}
	s.taskQueues.Pending = make(map[int]taskEntry)
	s.ready = make(chan struct{})
	s.store = store
	recovered, err := s.recover()
	if err != nil {
		return nil, err
	}

	if recovered {
		// Recovered. Now the state is already initialized,
		// and the master is ready.
		s.initDone = true
		close(s.ready)
		log.Info("Master recovered from saved state.")
	}

	return s, nil
}

// recover recovers service state from etcd.
func (s *Service) recover() (bool, error) {
	state, err := s.store.Load()
	if err != nil {
		return false, err
	}

	if state == nil {
		log.Infoln("No state exists, not recovered.")
		return false, nil
	}

	log.Infof("Loaded snapshot of size: %d bytes.", len(state))
	gr, err := gzip.NewReader(bytes.NewReader(state))
	if err != nil {
		return false, err
	}

	dec := gob.NewDecoder(gr)
	var tqs taskQueues
	err = dec.Decode(&tqs)
	if err != nil {
		return false, err
	}

	err = gr.Close()
	if err != nil {
		// Only close failed, recover actually succeed, so
		// just log error.
		log.Errorln(err)
	}

	s.taskQueues = tqs
	return true, nil
}

// snapshot *must* be called with s.mu being held.
func (s *Service) snapshot() error {
	// TOOD(helin): etcd request has a size limit, so the snapshot
	// size is limited by the max request size. We should either
	// divide the snapshot into smaller chunks and save under
	// different keys, or configure the request size to be big
	// enough:
	// https://github.com/coreos/etcd/blob/2f84f3d8d8ed8f9537ab6ffa44a3a1c7eddfa9b1/embed/config.go#L44
	var buf bytes.Buffer
	gw := gzip.NewWriter(&buf)
	enc := gob.NewEncoder(gw)
	err := enc.Encode(s.taskQueues)
	if err != nil {
		return err
	}
	err = gw.Close()
	if err != nil {
		return err
	}

	state := buf.Bytes()
	log.Infof("Saving snapshot of size: %d bytes.", len(state))
	return s.store.Save(state)
}

func readChunks(globPaths []string) ([]Chunk, error) {
	var chunks []Chunk
	var paths []string

	for _, s := range globPaths {
		match, err := filepath.Glob(s)
		if err != nil {
			return nil, err
		}
		paths = append(paths, match...)
	}

	if len(paths) == 0 {
		return nil, errors.New("no valid dataset specified")
	}

	for _, path := range paths {
		f, err := os.Open(path)
		if err != nil {
			return nil, err
		}

		index, err := recordio.LoadIndex(f)
		if err != nil {
			return nil, err
		}
		err = f.Close()
		if err != nil {
			return nil, err
		}

		count := index.NumChunks()
		for i := 0; i < count; i++ {
			chunk := Chunk{
				Path:  path,
				Index: *index.ChunkIndex(i),
			}
			chunks = append(chunks, chunk)
		}
	}

	return chunks, nil
}

// SetDataset sets dataset to dispatch for the master server.
//
// SetDataset can be call multiple times. But only the first call will
// be honored.
func (s *Service) SetDataset(globPaths []string, dummy *int) error {
	if len(globPaths) == 0 {
		return errors.New("no dataset specified")
	}

	s.mu.Lock()
	defer s.mu.Unlock()
	if s.initDone {
		// Already initialized. All trainer will call
		// SetDataset, but we only handle the first one. Treat
		// other calls as successful but do nothing.
		return nil
	}

	chunks, err := readChunks(globPaths)
	if err != nil {
		return err
	}

	s.taskQueues.Todo = partition(chunks, s.chunksPerTask)

	err = s.snapshot()
	if err != nil {
		log.Errorln(err)
		return err
	}

	close(s.ready)
	s.initDone = true
	return nil
}

func (s *Service) checkTimeoutFunc(taskID int, epoch int) func() {
	return func() {
		s.mu.Lock()
		defer s.mu.Unlock()

		t, ok := s.taskQueues.Pending[taskID]
		if !ok {
			return
		}

		if t.Epoch != epoch {
			// new epoch, task launched after the
			// schedule of this timeout check.
			return
		}

		defer func() {
			err := s.snapshot()
			if err != nil {
				log.Errorln(err)
			}
		}()

		delete(s.taskQueues.Pending, t.Task.ID)

		t.NumTimeout++
		if t.NumTimeout > s.timeoutMax {
			log.Warningf("Task %v timed out %d times, discard.", t.Task, t.NumTimeout)
			s.taskQueues.Failed = append(s.taskQueues.Failed, t.Task)
			return
		}

		log.Warningf("Task %v timed out %d times, retry.", t.Task, t.NumTimeout)
		s.taskQueues.Todo = append(s.taskQueues.Todo, t)
	}
}

// must be called with lock held.
func (s *Service) logFields() log.Fields {
	return log.Fields{
		"todoLen":    len(s.taskQueues.Todo),
		"pendingLen": len(s.taskQueues.Pending),
		"doneLen":    len(s.taskQueues.Done),
		"failedLen":  len(s.taskQueues.Failed),
	}
}

// GetTask gets a new task from the service.
func (s *Service) GetTask(dummy int, task *Task) error {
	select {
	case <-s.ready:
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if len(s.taskQueues.Todo) == 0 {
		if len(s.taskQueues.Done) == 0 {
			if len(s.taskQueues.Pending) == 0 {
				err := errors.New("all task failed")
				log.WithFields(s.logFields()).Warningln("All tasks failed.")
				return err
			}

			// TODO(helin): client need to retry in this
			// error case. Gotcha: RPC client can't
			// compare returned error with predefined
			// errors like io.EOF, because the error
			// instance deserialized from RPC is a
			// different instance than the error defined
			// in package. So we need to figure out a way
			// for client to check this error correctly.
			err := errors.New("no more available task")
			log.WithFields(s.logFields()).Warningln("No more available task.")
			return err
		}
		s.taskQueues.Todo = s.taskQueues.Done
		s.taskQueues.Done = nil
		log.WithFields(s.logFields()).Infoln("No more todo task, but trainer is requesting task to do. Move all done task to todo.")
	}

	t := s.taskQueues.Todo[0]
	t.Epoch++
	s.taskQueues.Todo = s.taskQueues.Todo[1:]
	s.taskQueues.Pending[t.Task.ID] = t
	err := s.snapshot()
	if err != nil {
		return err
	}

	*task = t.Task
	log.WithFields(s.logFields()).Infof("Task #%d dispatched.", task.ID)

	time.AfterFunc(s.timeoutDur, s.checkTimeoutFunc(t.Task.ID, t.Epoch))
	return nil
}

// TaskFinished tell the service that a task is finished.
func (s *Service) TaskFinished(taskID int, dummy *int) error {
	select {
	case <-s.ready:
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	t, ok := s.taskQueues.Pending[taskID]
	if !ok {
		err := errors.New("pending task not found")
		log.WithFields(s.logFields()).Warningln("Pending task #%d not found.", taskID)
		return err
	}

	// task finished, reset timeout
	t.NumTimeout = 0
	s.taskQueues.Done = append(s.taskQueues.Done, t)
	delete(s.taskQueues.Pending, taskID)

	log.WithFields(s.logFields()).Infof("Task #%d finished.", taskID)

	if len(s.taskQueues.Pending) == 0 && len(s.taskQueues.Todo) == 0 {
		log.WithFields(s.logFields()).Infoln("No more todo and pending task, start a new pass.")
		s.taskQueues.Todo = append(s.taskQueues.Todo, s.taskQueues.Done...)
		s.taskQueues.Done = nil
	}

	err := s.snapshot()
	if err != nil {
		log.Errorln(err)
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "fmt"
    "encoding/hex"
    "github.com/fuzxxl/nfc/2.0/nfc"
    "github.com/fuzxxl/freefare/0.3/freefare"
)

func padUID(block []byte) ([]byte, bool) {
	blockLen := len(block)
	if blockLen >= 32 {
		panic("PadBlock input must be less than 32 bytes.")
	}

	result := make([]byte, 32)
	copy(result, block)
	result[blockLen] = 0x80

	if blockLen == 31 {
	   return result, false
	}

	return result, true
}

func main() {
    dat, err := ioutil.ReadFile("keys.yaml")
    if err != nil {
        panic(err)
    }

    keymap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(dat), &keymap);
    if err != nil {
        panic(err)
    }

    dat2, err := ioutil.ReadFile("apps.yaml")
    if err != nil {
        panic(err)
    }

    appmap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(dat2), &appmap);
    if err != nil {
        panic(err)
    }

    appkey_str := keymap["aclapp"].(map[interface{}]interface{})["read"].(string)
    appkey, err := hex.DecodeString(appkey_str)
    if err != nil {
        panic(err)
    }
    fmt.Println(appkey)

    aid_str := appmap["aclapp"].(map[interface{}]interface{})["aid"].(string)
    aid, err := hex.DecodeString(aid_str)
    if err != nil {
        panic(err)
    }
    fmt.Println(aid)

    d, err := nfc.Open("");
    if err != nil {
        panic(err)
    }

    tags, err := freefare.GetTags(d);
    if err != nil {
        panic(err)
    }

    for i := 0; i < len(tags); i++ {
        tag := tags[i]
        uidstr := tag.UID()
        uidbytes, err := hex.DecodeString(uidstr);
        if err != nil {
            panic(err);
        }
        fmt.Println(uidstr)
        fmt.Println(uidbytes)

    	uidaid := make([]byte, len(uidbytes)+len(aid)+1)
    	uidaid[0] =0x01
    	copy(uidaid[1:], uidbytes)
    	copy(uidaid[len(uidbytes)+1:], aid)

        fmt.Println("Found tag", uidstr)

        D, padded := padUID(uidaid)
        fmt.Println("D=", D, " padded=", padded)
    }

}

<commit_msg>pass D to cmac module but what next ?<commit_after>package main

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "fmt"
    "encoding/hex"
    "github.com/fuzxxl/nfc/2.0/nfc"
    "github.com/fuzxxl/freefare/0.3/freefare"
    "github.com/jacobsa/crypto/cmac"
)

func padUID(block []byte) ([]byte, bool) {
	blockLen := len(block)
	if blockLen >= 32 {
		panic("PadBlock input must be less than 32 bytes.")
	}

	result := make([]byte, 32)
	copy(result, block)
	result[blockLen] = 0x80

	if blockLen == 31 {
	   return result, false
	}

	return result, true
}

func main() {
    dat, err := ioutil.ReadFile("keys.yaml")
    if err != nil {
        panic(err)
    }

    keymap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(dat), &keymap);
    if err != nil {
        panic(err)
    }

    dat2, err := ioutil.ReadFile("apps.yaml")
    if err != nil {
        panic(err)
    }

    appmap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(dat2), &appmap);
    if err != nil {
        panic(err)
    }

    appkey_str := keymap["aclapp"].(map[interface{}]interface{})["read"].(string)
    appkey, err := hex.DecodeString(appkey_str)
    if err != nil {
        panic(err)
    }
    fmt.Println(appkey)

    aid_str := appmap["aclapp"].(map[interface{}]interface{})["aid"].(string)
    aid, err := hex.DecodeString(aid_str)
    if err != nil {
        panic(err)
    }
    fmt.Println(aid)

    d, err := nfc.Open("");
    if err != nil {
        panic(err)
    }

    tags, err := freefare.GetTags(d);
    if err != nil {
        panic(err)
    }

    for i := 0; i < len(tags); i++ {
        tag := tags[i]
        uidstr := tag.UID()
        uidbytes, err := hex.DecodeString(uidstr);
        if err != nil {
            panic(err);
        }
        fmt.Println(uidstr)
        fmt.Println(uidbytes)

    	uidaid := make([]byte, len(uidbytes)+len(aid)+1)
    	uidaid[0] =0x01
    	copy(uidaid[1:], uidbytes)
    	copy(uidaid[len(uidbytes)+1:], aid)

        fmt.Printf("Found tag %s\n", uidstr)

        D, padded := padUID(uidaid)
        fmt.Println("D=", D, "padded=", padded)

        foo, err := cmac.New(D)
        fmt.Println(foo)
// dafuq, how are we supposed to access those subkeys
//        fmt.Println(foo.k1)
//        fmt.Println(foo.k2)
    }

}

<|endoftext|>


<commit_before>package google

import (
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

const (
	// Copied from the official Google Cloud auto-generated client.
	ProjectRegex         = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))"
	ProjectRegexWildCard = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)|-)"
	RegionRegex          = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"
	SubnetworkRegex      = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"

	SubnetworkLinkRegex = "projects/(" + ProjectRegex + ")/regions/(" + RegionRegex + ")/subnetworks/(" + SubnetworkRegex + ")$"

	RFC1035NameTemplate = "[a-z](?:[-a-z0-9]{%d,%d}[a-z0-9])"
	CloudIoTIdRegex     = "^[a-zA-Z][-a-zA-Z0-9._+~%]{2,254}$"

	// Format of default Compute service accounts created by Google
	// ${PROJECT_ID}-compute@developer.gserviceaccount.com where PROJECT_ID is an int64 (max 20 digits)
	ComputeServiceAccountNameRegex = "[0-9]{1,20}-compute@developer.gserviceaccount.com"

	// https://cloud.google.com/iam/docs/understanding-custom-roles#naming_the_role
	IAMCustomRoleIDRegex = "^[a-zA-Z0-9_\\.]{3,64}$"
)

var (
	// Service account name must have a length between 6 and 30.
	// The first and last characters have different restrictions, than
	// the middle characters. The middle characters length must be between
	// 4 and 28 since the first and last character are excluded.
	ServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28)

	ServiceAccountLinkRegexPrefix = "projects/" + ProjectRegexWildCard + "/serviceAccounts/"
	PossibleServiceAccountNames   = []string{
		ServiceDefaultAccountNameRegex,
		ComputeServiceAccountNameRegex,
		CreatedServiceAccountNameRegex,
	}
	ServiceAccountLinkRegex = ServiceAccountLinkRegexPrefix + "(" + strings.Join(PossibleServiceAccountNames, "|") + ")"

	ServiceAccountKeyNameRegex = ServiceAccountLinkRegexPrefix + "(.+)/keys/(.+)"

	// Format of service accounts created through the API
	CreatedServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28) + "@" + ProjectNameInDNSFormRegex + "\\.iam\\.gserviceaccount\\.com$"

	// Format of service-created service account
	// examples are:
	// 		$PROJECTID@cloudbuild.gserviceaccount.com
	// 		$PROJECTID@cloudservices.gserviceaccount.com
	// 		$PROJECTID@appspot.gserviceaccount.com
	ServiceDefaultAccountNameRegex = ProjectRegex + "@[a-z]+.gserviceaccount.com$"

	ProjectNameInDNSFormRegex = "[-a-z0-9\\.]{1,63}"
	ProjectNameRegex          = "^[A-Za-z0-9-'\"\\s!]{4,30}$"
)

var rfc1918Networks = []string{
	"10.0.0.0/8",
	"172.16.0.0/12",
	"192.168.0.0/16",
}

func validateGCPName(v interface{}, k string) (ws []string, errors []error) {
	re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
	return validateRegexp(re)(v, k)
}

func validateRegexp(re string) schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)
		if !regexp.MustCompile(re).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q (%q) doesn't match regexp %q", k, value, re))
		}

		return
	}
}

func validateRFC1918Network(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {

		s, es = validation.CIDRNetwork(min, max)(i, k)
		if len(es) > 0 {
			return
		}

		v, _ := i.(string)
		ip, _, _ := net.ParseCIDR(v)
		for _, c := range rfc1918Networks {
			if _, ipnet, _ := net.ParseCIDR(c); ipnet.Contains(ip) {
				return
			}
		}

		es = append(es, fmt.Errorf("expected %q to be an RFC1918-compliant CIDR, got: %s", k, v))

		return
	}
}

func validateRFC3339Time(v interface{}, k string) (warnings []string, errors []error) {
	time := v.(string)
	if len(time) != 5 || time[2] != ':' {
		errors = append(errors, fmt.Errorf("%q (%q) must be in the format HH:mm (RFC3399)", k, time))
		return
	}
	if hour, err := strconv.ParseUint(time[:2], 10, 0); err != nil || hour > 23 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid hour (00-23)", k, time))
		return
	}
	if min, err := strconv.ParseUint(time[3:], 10, 0); err != nil || min > 59 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid minute (00-59)", k, time))
		return
	}
	return
}

func validateRFC1035Name(min, max int) schema.SchemaValidateFunc {
	if min < 2 || max < min {
		return func(i interface{}, k string) (s []string, errors []error) {
			if min < 2 {
				errors = append(errors, fmt.Errorf("min must be at least 2. Got: %d", min))
			}
			if max < min {
				errors = append(errors, fmt.Errorf("max must greater than min. Got [%d, %d]", min, max))
			}
			return
		}
	}

	return validateRegexp(fmt.Sprintf("^"+RFC1035NameTemplate+"$", min-2, max-2))
}

func validateIpCidrRange(v interface{}, k string) (warnings []string, errors []error) {
	_, _, err := net.ParseCIDR(v.(string))
	if err != nil {
		errors = append(errors, fmt.Errorf("%q is not a valid IP CIDR range: %s", k, err))
	}
	return
}

func validateIAMCustomRoleID(v interface{}, k string) (warnings []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(IAMCustomRoleIDRegex).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q (%q) doesn't match regexp %q", k, value, IAMCustomRoleIDRegex))
	}
	return
}

func orEmpty(f schema.SchemaValidateFunc) schema.SchemaValidateFunc {
	return func(i interface{}, k string) ([]string, []error) {
		v, ok := i.(string)
		if ok && v == "" {
			return nil, nil
		}
		return f(i, k)
	}
}

func validateProjectID() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile("^" + ProjectRegex + "$").MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q project_id must be 6 to 30 with lowercase letters, digits, hyphens and start with a letter. Trailing hyphens are prohibited.", value))
		}
		return
	}
}

func validateProjectName() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile(ProjectNameRegex).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q name must be 4 to 30 characters with lowercase and uppercase letters, numbers, hyphen, single-quote, double-quote, space, and exclamation point.", value))
		}
		return
	}
}

func validateDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		if _, err := time.ParseDuration(v); err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		return
	}
}

func validateNonNegativeDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		dur, err := time.ParseDuration(v)
		if err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		if dur < 0 {
			es = append(es, fmt.Errorf("duration %v must be a non-negative duration", dur))
			return
		}

		return
	}
}

func validateIpAddress(i interface{}, val string) ([]string, []error) {
	ip := net.ParseIP(i.(string))
	if ip == nil {
		return nil, []error{fmt.Errorf("could not parse %q to IP address", val)}
	}
	return nil, nil
}

// StringNotInSlice returns a SchemaValidateFunc which tests if the provided value
// is of type string and that it matches none of the element in the invalid slice.
// if ignorecase is true, case is ignored.
func StringNotInSlice(invalid []string, ignoreCase bool) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		for _, str := range invalid {
			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
				es = append(es, fmt.Errorf("expected %s to not match any of %v, got %s", k, invalid, v))
				return
			}
		}

		return
	}
}
<commit_msg>Add validation for start_time to resource_policy<commit_after>package google

import (
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

const (
	// Copied from the official Google Cloud auto-generated client.
	ProjectRegex         = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))"
	ProjectRegexWildCard = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)|-)"
	RegionRegex          = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"
	SubnetworkRegex      = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"

	SubnetworkLinkRegex = "projects/(" + ProjectRegex + ")/regions/(" + RegionRegex + ")/subnetworks/(" + SubnetworkRegex + ")$"

	RFC1035NameTemplate = "[a-z](?:[-a-z0-9]{%d,%d}[a-z0-9])"
	CloudIoTIdRegex     = "^[a-zA-Z][-a-zA-Z0-9._+~%]{2,254}$"

	// Format of default Compute service accounts created by Google
	// ${PROJECT_ID}-compute@developer.gserviceaccount.com where PROJECT_ID is an int64 (max 20 digits)
	ComputeServiceAccountNameRegex = "[0-9]{1,20}-compute@developer.gserviceaccount.com"

	// https://cloud.google.com/iam/docs/understanding-custom-roles#naming_the_role
	IAMCustomRoleIDRegex = "^[a-zA-Z0-9_\\.]{3,64}$"
)

var (
	// Service account name must have a length between 6 and 30.
	// The first and last characters have different restrictions, than
	// the middle characters. The middle characters length must be between
	// 4 and 28 since the first and last character are excluded.
	ServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28)

	ServiceAccountLinkRegexPrefix = "projects/" + ProjectRegexWildCard + "/serviceAccounts/"
	PossibleServiceAccountNames   = []string{
		ServiceDefaultAccountNameRegex,
		ComputeServiceAccountNameRegex,
		CreatedServiceAccountNameRegex,
	}
	ServiceAccountLinkRegex = ServiceAccountLinkRegexPrefix + "(" + strings.Join(PossibleServiceAccountNames, "|") + ")"

	ServiceAccountKeyNameRegex = ServiceAccountLinkRegexPrefix + "(.+)/keys/(.+)"

	// Format of service accounts created through the API
	CreatedServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28) + "@" + ProjectNameInDNSFormRegex + "\\.iam\\.gserviceaccount\\.com$"

	// Format of service-created service account
	// examples are:
	// 		$PROJECTID@cloudbuild.gserviceaccount.com
	// 		$PROJECTID@cloudservices.gserviceaccount.com
	// 		$PROJECTID@appspot.gserviceaccount.com
	ServiceDefaultAccountNameRegex = ProjectRegex + "@[a-z]+.gserviceaccount.com$"

	ProjectNameInDNSFormRegex = "[-a-z0-9\\.]{1,63}"
	ProjectNameRegex          = "^[A-Za-z0-9-'\"\\s!]{4,30}$"
)

var rfc1918Networks = []string{
	"10.0.0.0/8",
	"172.16.0.0/12",
	"192.168.0.0/16",
}

func validateGCPName(v interface{}, k string) (ws []string, errors []error) {
	re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
	return validateRegexp(re)(v, k)
}

func validateRegexp(re string) schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)
		if !regexp.MustCompile(re).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q (%q) doesn't match regexp %q", k, value, re))
		}

		return
	}
}

func validateRFC1918Network(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {

		s, es = validation.CIDRNetwork(min, max)(i, k)
		if len(es) > 0 {
			return
		}

		v, _ := i.(string)
		ip, _, _ := net.ParseCIDR(v)
		for _, c := range rfc1918Networks {
			if _, ipnet, _ := net.ParseCIDR(c); ipnet.Contains(ip) {
				return
			}
		}

		es = append(es, fmt.Errorf("expected %q to be an RFC1918-compliant CIDR, got: %s", k, v))

		return
	}
}

func validateRFC3339Time(v interface{}, k string) (warnings []string, errors []error) {
	time := v.(string)
	if len(time) != 5 || time[2] != ':' {
		errors = append(errors, fmt.Errorf("%q (%q) must be in the format HH:mm (RFC3399)", k, time))
		return
	}
	if hour, err := strconv.ParseUint(time[:2], 10, 0); err != nil || hour > 23 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid hour (00-23)", k, time))
		return
	}
	if min, err := strconv.ParseUint(time[3:], 10, 0); err != nil || min > 59 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid minute (00-59)", k, time))
		return
	}
	return
}

func validateRFC1035Name(min, max int) schema.SchemaValidateFunc {
	if min < 2 || max < min {
		return func(i interface{}, k string) (s []string, errors []error) {
			if min < 2 {
				errors = append(errors, fmt.Errorf("min must be at least 2. Got: %d", min))
			}
			if max < min {
				errors = append(errors, fmt.Errorf("max must greater than min. Got [%d, %d]", min, max))
			}
			return
		}
	}

	return validateRegexp(fmt.Sprintf("^"+RFC1035NameTemplate+"$", min-2, max-2))
}

func validateIpCidrRange(v interface{}, k string) (warnings []string, errors []error) {
	_, _, err := net.ParseCIDR(v.(string))
	if err != nil {
		errors = append(errors, fmt.Errorf("%q is not a valid IP CIDR range: %s", k, err))
	}
	return
}

func validateIAMCustomRoleID(v interface{}, k string) (warnings []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(IAMCustomRoleIDRegex).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q (%q) doesn't match regexp %q", k, value, IAMCustomRoleIDRegex))
	}
	return
}

func orEmpty(f schema.SchemaValidateFunc) schema.SchemaValidateFunc {
	return func(i interface{}, k string) ([]string, []error) {
		v, ok := i.(string)
		if ok && v == "" {
			return nil, nil
		}
		return f(i, k)
	}
}

func validateProjectID() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile("^" + ProjectRegex + "$").MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q project_id must be 6 to 30 with lowercase letters, digits, hyphens and start with a letter. Trailing hyphens are prohibited.", value))
		}
		return
	}
}

func validateProjectName() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile(ProjectNameRegex).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q name must be 4 to 30 characters with lowercase and uppercase letters, numbers, hyphen, single-quote, double-quote, space, and exclamation point.", value))
		}
		return
	}
}

func validateDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		if _, err := time.ParseDuration(v); err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		return
	}
}

func validateNonNegativeDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		dur, err := time.ParseDuration(v)
		if err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		if dur < 0 {
			es = append(es, fmt.Errorf("duration %v must be a non-negative duration", dur))
			return
		}

		return
	}
}

func validateIpAddress(i interface{}, val string) ([]string, []error) {
	ip := net.ParseIP(i.(string))
	if ip == nil {
		return nil, []error{fmt.Errorf("could not parse %q to IP address", val)}
	}
	return nil, nil
}

// StringNotInSlice returns a SchemaValidateFunc which tests if the provided value
// is of type string and that it matches none of the element in the invalid slice.
// if ignorecase is true, case is ignored.
func StringNotInSlice(invalid []string, ignoreCase bool) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		for _, str := range invalid {
			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
				es = append(es, fmt.Errorf("expected %s to not match any of %v, got %s", k, invalid, v))
				return
			}
		}

		return
	}
}

// Ensure that hourly timestamp strings "HH:MM" have the minutes zeroed out for hourly only inputs
func validateHourlyOnly(val interface{}, key string) (warns []string, errs []error) {
	v := val.(string)
	parts := strings.Split(v, ":")
	if len(parts) != 2 {
		errs = append(errs, fmt.Errorf("%q must be in the format HH:00, got: %s", key, v))
		return
	}
	if parts[1] != "00" {
		errs = append(errs, fmt.Errorf("%q does not allow minutes, it must be in the format HH:00, got: %s", key, v))
	}
	i, err := strconv.Atoi(parts[0])
	if err != nil {
		errs = append(errs, fmt.Errorf("%q cannot be parsed, it must be in the format HH:00, got: %s", key, v))
	} else if i < 0 || i > 23 {
		errs = append(errs, fmt.Errorf("%q does not specify a valid hour, it must be in the format HH:00 where HH : [00-23], got: %s", key, v))
	}
	return
}
<|endoftext|>


<commit_before>// sniped from https://github.com/rocaltair/goreadline
package golisp

/*
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#cgo LDFLAGS: -lreadline

*/
import "C"
import "unsafe"

func ReadLine(prompt *string) *string {
    var cPrompt *C.char
    if prompt != nil {
        cPrompt = C.CString(*prompt)
    }
    cLine := C.readline(cPrompt)
    if cPrompt != nil {
        C.free(unsafe.Pointer(cPrompt))
    }
    if cLine == nil {
        return nil
    }

    line := C.GoString(cLine)
    C.free(unsafe.Pointer(cLine))
    return &line
}

func AddHistory(line string) {
    cLine := C.CString(line)
    C.add_history(cLine)
    C.free(unsafe.Pointer(cLine))
}

func ClearHistory() {
    C.clear_history()
}

func WriteHistoryToFile(fileName string) {
    cFileName := C.CString(fileName)
    C.write_history(cFileName)
    C.free(unsafe.Pointer(cFileName))
}

func LoadHistoryFromFile(fileName string) {
    cFileName := C.CString(fileName)
    C.read_history(cFileName)
    C.free(unsafe.Pointer(cFileName))
}

func TruncateHistoryFile(fileName string, left int) {
    cFileName := C.CString(fileName)
    cLeft := C.int(left)
    C.history_truncate_file(cFileName, cLeft)
    C.free(unsafe.Pointer(cFileName))
}
<commit_msg>Cleanup formatting<commit_after>// sniped from https://github.com/rocaltair/goreadline
package golisp

/*
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#cgo LDFLAGS: -lreadline
*/
import "C"
import "unsafe"

func ReadLine(prompt *string) *string {
	var cPrompt *C.char
	if prompt != nil {
		cPrompt = C.CString(*prompt)
	}
	cLine := C.readline(cPrompt)
	if cPrompt != nil {
		C.free(unsafe.Pointer(cPrompt))
	}
	if cLine == nil {
		return nil
	}

	line := C.GoString(cLine)
	C.free(unsafe.Pointer(cLine))
	return &line
}

func AddHistory(line string) {
	cLine := C.CString(line)
	C.add_history(cLine)
	C.free(unsafe.Pointer(cLine))
}

func ClearHistory() {
	C.clear_history()
}

func WriteHistoryToFile(fileName string) {
	cFileName := C.CString(fileName)
	C.write_history(cFileName)
	C.free(unsafe.Pointer(cFileName))
}

func LoadHistoryFromFile(fileName string) {
	cFileName := C.CString(fileName)
	C.read_history(cFileName)
	C.free(unsafe.Pointer(cFileName))
}

func TruncateHistoryFile(fileName string, left int) {
	cFileName := C.CString(fileName)
	cLeft := C.int(left)
	C.history_truncate_file(cFileName, cLeft)
	C.free(unsafe.Pointer(cFileName))
}
<|endoftext|>


<commit_before>/*
Package graceful implements graceful shutdown for HTTP servers by closing idle
connections after receiving a signal. By default, this package listens for
interrupts (i.e., SIGINT), but when it detects that it is running under Einhorn
it will additionally listen for SIGUSR2 as well, giving your application
automatic support for graceful upgrades.

It's worth mentioning explicitly that this package is a hack to shim graceful
shutdown behavior into the net/http package provided in Go 1.2. It was written
by carefully reading the sequence of function calls net/http happened to use as
of this writing and finding enough surface area with which to add appropriate
behavior. There's a very good chance that this package will cease to work in
future versions of Go, but with any luck the standard library will add support
of its own by then (https://code.google.com/p/go/issues/detail?id=4674).

If you're interested in figuring out how this package works, we suggest you read
the documentation for WrapConn() and net.go.
*/
package graceful

import (
	"crypto/tls"
	"net"
	"net/http"
	"time"
)

/*
You might notice that these methods look awfully similar to the methods of the
same name from the go standard library--that's because they were stolen from
there! If go were more like, say, Ruby, it'd actually be possible to shim just
the Serve() method, since we can do everything we want from there. However, it's
not possible to get the other methods which call Serve() (ListenAndServe(), say)
to call your shimmed copy--they always call the original.

Since I couldn't come up with a better idea, I just copy-and-pasted both
ListenAndServe and ListenAndServeTLS here more-or-less verbatim. "Oh well!"
*/

type server http.Server

func (srv *server) Serve(l net.Listener) (err error) {
	go func() {
		<-kill
		l.Close()
	}()
	l = WrapListener(l)

	// Spawn a shadow http.Server to do the actual servering. We do this
	// because we need to sketch on some of the parameters you passed in,
	// and it's nice to keep our sketching to ourselves.
	shadow := *(*http.Server)(srv)

	if shadow.ReadTimeout == 0 {
		shadow.ReadTimeout = forever
	}
	shadow.Handler = Middleware(shadow.Handler)

	err = shadow.Serve(l)

	// We expect an error when we close the listener, so we indiscriminately
	// swallow Serve errors when we're in a shutdown state.
	select {
	case <-kill:
		return nil
	default:
		return err
	}
}

// About 200 years, also known as "forever"
const forever time.Duration = 200 * 365 * 24 * time.Hour

func (srv *server) ListenAndServe() error {
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	l, e := net.Listen("tcp", addr)
	if e != nil {
		return e
	}
	return srv.Serve(l)
}

func (srv *server) ListenAndServeTLS(certFile, keyFile string) error {
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}
	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}
	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
	}

	var err error
	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return err
	}

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	tlsListener := tls.NewListener(conn, config)
	return srv.Serve(tlsListener)
}

// ListenAndServe behaves exactly like the net/http function of the same name.
func ListenAndServe(addr string, handler http.Handler) error {
	server := &server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}

// ListenAndServeTLS behaves exactly like the net/http function of the same name.
func ListenAndServeTLS(addr, certfile, keyfile string, handler http.Handler) error {
	server := &server{Addr: addr, Handler: handler}
	return server.ListenAndServeTLS(certfile, keyfile)
}

// Serve behaves exactly like the net/http function of the same name.
func Serve(l net.Listener, handler http.Handler) error {
	server := &server{Handler: handler}
	return server.Serve(l)
}
<commit_msg>Make graceful.Server public again<commit_after>/*
Package graceful implements graceful shutdown for HTTP servers by closing idle
connections after receiving a signal. By default, this package listens for
interrupts (i.e., SIGINT), but when it detects that it is running under Einhorn
it will additionally listen for SIGUSR2 as well, giving your application
automatic support for graceful upgrades.

It's worth mentioning explicitly that this package is a hack to shim graceful
shutdown behavior into the net/http package provided in Go 1.2. It was written
by carefully reading the sequence of function calls net/http happened to use as
of this writing and finding enough surface area with which to add appropriate
behavior. There's a very good chance that this package will cease to work in
future versions of Go, but with any luck the standard library will add support
of its own by then (https://code.google.com/p/go/issues/detail?id=4674).

If you're interested in figuring out how this package works, we suggest you read
the documentation for WrapConn() and net.go.
*/
package graceful

import (
	"crypto/tls"
	"net"
	"net/http"
	"time"
)

/*
You might notice that these methods look awfully similar to the methods of the
same name from the go standard library--that's because they were stolen from
there! If go were more like, say, Ruby, it'd actually be possible to shim just
the Serve() method, since we can do everything we want from there. However, it's
not possible to get the other methods which call Serve() (ListenAndServe(), say)
to call your shimmed copy--they always call the original.

Since I couldn't come up with a better idea, I just copy-and-pasted both
ListenAndServe and ListenAndServeTLS here more-or-less verbatim. "Oh well!"
*/

// Type Server is exactly the same as an http.Server, but provides more graceful
// implementations of its methods.
type Server http.Server

func (srv *Server) Serve(l net.Listener) (err error) {
	go func() {
		<-kill
		l.Close()
	}()
	l = WrapListener(l)

	// Spawn a shadow http.Server to do the actual servering. We do this
	// because we need to sketch on some of the parameters you passed in,
	// and it's nice to keep our sketching to ourselves.
	shadow := *(*http.Server)(srv)

	if shadow.ReadTimeout == 0 {
		shadow.ReadTimeout = forever
	}
	shadow.Handler = Middleware(shadow.Handler)

	err = shadow.Serve(l)

	// We expect an error when we close the listener, so we indiscriminately
	// swallow Serve errors when we're in a shutdown state.
	select {
	case <-kill:
		return nil
	default:
		return err
	}
}

// About 200 years, also known as "forever"
const forever time.Duration = 200 * 365 * 24 * time.Hour

func (srv *Server) ListenAndServe() error {
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	l, e := net.Listen("tcp", addr)
	if e != nil {
		return e
	}
	return srv.Serve(l)
}

func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}
	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}
	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
	}

	var err error
	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return err
	}

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	tlsListener := tls.NewListener(conn, config)
	return srv.Serve(tlsListener)
}

// ListenAndServe behaves exactly like the net/http function of the same name.
func ListenAndServe(addr string, handler http.Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}

// ListenAndServeTLS behaves exactly like the net/http function of the same name.
func ListenAndServeTLS(addr, certfile, keyfile string, handler http.Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServeTLS(certfile, keyfile)
}

// Serve behaves exactly like the net/http function of the same name.
func Serve(l net.Listener, handler http.Handler) error {
	server := &Server{Handler: handler}
	return server.Serve(l)
}
<|endoftext|>


<commit_before>package images

import (
	"fmt"
	"io"
	"reflect"

	"github.com/mitchellh/mapstructure"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
)

// Image model
// Does not include the literal image data; just metadata.
// returned by listing images, and by fetching a specific image.
type Image struct {
	// ID is the image UUID
	ID string

	// Name is the human-readable display name for the image.
	Name string

	// Status is the image status. It can be "queued" or "active"
	// See imageservice/v2/images/type.go
	Status ImageStatus

	// Tags is a list of image tags. Tags are arbitrarily defined strings
	// attached to an image.
	Tags []string

	// ContainerFormat is the format of the container.
	// Valid values are ami, ari, aki, bare, and ovf.
	ContainerFormat string `mapstructure:"container_format"`

	// DiskFormat is the format of the disk.
	// If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, and iso.
	DiskFormat string `mapstructure:"disk_format"`

	// MinDiskGigabytes is the amount of disk space in GB that is required to boot the image.
	MinDiskGigabytes int `mapstructure:"min_disk"`

	// MinRAMMegabytes [optional] is the amount of RAM in MB that is required to boot the image.
	MinRAMMegabytes int `mapstructure:"min_ram"`

	// Owner is the tenant the image belongs to.
	Owner string

	// Protected is whether the image is deletable or not.
	Protected bool

	// Visibility defines who can see/use the image.
	Visibility ImageVisibility

	// Checksum is the checksum of the data that's associated with the image
	Checksum string

	// SizeBytes is the size of the data that's associated with the image.
	SizeBytes int `mapstructure:"size"`

	// Metadata is a set of metadata associated with the image.
	// Image metadata allow for meaningfully define the image properties
	// and tags. See http://docs.openstack.org/developer/glance/metadefs-concepts.html.
	Metadata map[string]string

	// Properties is a set of key-value pairs, if any, that are associated with the image.
	Properties map[string]string
}

// CreateResult model
type CreateResult struct {
	gophercloud.Result
}

// Extract build CreateResults from imput Image
func (c CreateResult) Extract() (*Image, error) {
	if c.Err != nil {
		return nil, c.Err
	}
	var image *Image

	err := mapstructure.Decode(c.Result.Body, &image)
	return image, err
}

//DeleteResult model
type DeleteResult struct {
	gophercloud.Result
}

// GetResult model
type GetResult struct {
	gophercloud.Result
}

// Extract builds GetResult
func (c GetResult) Extract() (*Image, error) {
	if c.Err != nil {
		return nil, c.Err
	}
	var image *Image

	err := mapstructure.Decode(c.Result.Body, &image)
	return image, err
}

// UpdateResult model
type UpdateResult struct {
	gophercloud.Result
}

// Extract builds UpdateResult
func (u UpdateResult) Extract() (*Image, error) {
	if u.Err != nil {
		return nil, u.Err
	}
	var image *Image

	err := mapstructure.Decode(u.Result.Body, &image)
	return image, err
}

// PutImageDataResult is model put image respose
type PutImageDataResult struct {
	gophercloud.Result
}

// GetImageDataResult model for image response
type GetImageDataResult struct {
	gophercloud.Result
}

// Extract builds images model from io.Reader
func (g GetImageDataResult) Extract() (io.Reader, error) {
	if r, ok := g.Body.(io.Reader); ok {
		return r, nil
	}
	return nil, fmt.Errorf("Expected io.Reader but got: %T(%#v)", g.Body, g.Body)
}

// ImagePage represents page
type ImagePage struct {
	pagination.LinkedPageBase
}

// IsEmpty returns true if a page contains no Images results.
func (page ImagePage) IsEmpty() (bool, error) {
	images, err := ExtractImages(page)
	if err != nil {
		return true, err
	}
	return len(images) == 0, nil
}

// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func (page ImagePage) NextPageURL() (string, error) {
	type resp struct {
		Next string `mapstructure:"next"`
	}

	var r resp
	err := mapstructure.Decode(page.Body, &r)
	if err != nil {
		return "", err
	}

	return nextPageURL(page.URL.String(), r.Next), nil
}

func toMapFromString(from reflect.Kind, to reflect.Kind, data interface{}) (interface{}, error) {
	if (from == reflect.String) && (to == reflect.Map) {
		return map[string]interface{}{}, nil
	}
	return data, nil
}

// ExtractImages interprets the results of a single page from a List() call, producing a slice of Image entities.
func ExtractImages(page pagination.Page) ([]Image, error) {
	casted := page.(ImagePage).Body

	var response struct {
		Images []Image `mapstructure:"images"`
	}

	config := &mapstructure.DecoderConfig{
		DecodeHook: toMapFromString,
		Result:     &response,
	}
	decoder, err := mapstructure.NewDecoder(config)
	if err != nil {
		return nil, err
	}

	err = decoder.Decode(casted)
	if err != nil {
		fmt.Printf("Error happened %v \n", err)
	}

	return response.Images, err
}
<commit_msg>imageservice: Factorize Get, Update and Create Extract method<commit_after>package images

import (
	"fmt"
	"io"
	"reflect"

	"github.com/mitchellh/mapstructure"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
)

// Image model
// Does not include the literal image data; just metadata.
// returned by listing images, and by fetching a specific image.
type Image struct {
	// ID is the image UUID
	ID string

	// Name is the human-readable display name for the image.
	Name string

	// Status is the image status. It can be "queued" or "active"
	// See imageservice/v2/images/type.go
	Status ImageStatus

	// Tags is a list of image tags. Tags are arbitrarily defined strings
	// attached to an image.
	Tags []string

	// ContainerFormat is the format of the container.
	// Valid values are ami, ari, aki, bare, and ovf.
	ContainerFormat string `mapstructure:"container_format"`

	// DiskFormat is the format of the disk.
	// If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, and iso.
	DiskFormat string `mapstructure:"disk_format"`

	// MinDiskGigabytes is the amount of disk space in GB that is required to boot the image.
	MinDiskGigabytes int `mapstructure:"min_disk"`

	// MinRAMMegabytes [optional] is the amount of RAM in MB that is required to boot the image.
	MinRAMMegabytes int `mapstructure:"min_ram"`

	// Owner is the tenant the image belongs to.
	Owner string

	// Protected is whether the image is deletable or not.
	Protected bool

	// Visibility defines who can see/use the image.
	Visibility ImageVisibility

	// Checksum is the checksum of the data that's associated with the image
	Checksum string

	// SizeBytes is the size of the data that's associated with the image.
	SizeBytes int `mapstructure:"size"`

	// Metadata is a set of metadata associated with the image.
	// Image metadata allow for meaningfully define the image properties
	// and tags. See http://docs.openstack.org/developer/glance/metadefs-concepts.html.
	Metadata map[string]string

	// Properties is a set of key-value pairs, if any, that are associated with the image.
	Properties map[string]string
}

type commonResult struct {
	gophercloud.Result
}

// Extract interprets any commonResult as an Image.
func (c commonResult) Extract() (*Image, error) {
	if c.Err != nil {
		return nil, c.Err
	}
	var image *Image

	err := mapstructure.Decode(c.Result.Body, &image)
	return image, err
}

// CreateResult represents the result of a Create operation
type CreateResult struct {
	commonResult
}

// UpdateResult represents the result of an Update operation
type UpdateResult struct {
	commonResult
}

// GetResult represents the result of a Get operation
type GetResult struct {
	commonResult
}

//DeleteResult model
type DeleteResult struct {
	gophercloud.Result
}

// PutImageDataResult is model put image respose
type PutImageDataResult struct {
	gophercloud.Result
}

// GetImageDataResult model for image response
type GetImageDataResult struct {
	gophercloud.Result
}

// Extract builds images model from io.Reader
func (g GetImageDataResult) Extract() (io.Reader, error) {
	if r, ok := g.Body.(io.Reader); ok {
		return r, nil
	}
	return nil, fmt.Errorf("Expected io.Reader but got: %T(%#v)", g.Body, g.Body)
}

// ImagePage represents page
type ImagePage struct {
	pagination.LinkedPageBase
}

// IsEmpty returns true if a page contains no Images results.
func (page ImagePage) IsEmpty() (bool, error) {
	images, err := ExtractImages(page)
	if err != nil {
		return true, err
	}
	return len(images) == 0, nil
}

// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func (page ImagePage) NextPageURL() (string, error) {
	type resp struct {
		Next string `mapstructure:"next"`
	}

	var r resp
	err := mapstructure.Decode(page.Body, &r)
	if err != nil {
		return "", err
	}

	return nextPageURL(page.URL.String(), r.Next), nil
}

func toMapFromString(from reflect.Kind, to reflect.Kind, data interface{}) (interface{}, error) {
	if (from == reflect.String) && (to == reflect.Map) {
		return map[string]interface{}{}, nil
	}
	return data, nil
}

// ExtractImages interprets the results of a single page from a List() call, producing a slice of Image entities.
func ExtractImages(page pagination.Page) ([]Image, error) {
	casted := page.(ImagePage).Body

	var response struct {
		Images []Image `mapstructure:"images"`
	}

	config := &mapstructure.DecoderConfig{
		DecodeHook: toMapFromString,
		Result:     &response,
	}
	decoder, err := mapstructure.NewDecoder(config)
	if err != nil {
		return nil, err
	}

	err = decoder.Decode(casted)
	if err != nil {
		fmt.Printf("Error happened %v \n", err)
	}

	return response.Images, err
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package containersource

import (
	"context"
	"fmt"
	"strings"

	"go.uber.org/zap"
	"k8s.io/client-go/rest"

	"github.com/knative/eventing-sources/pkg/apis/sources/v1alpha1"
	"github.com/knative/eventing-sources/pkg/controller/containersource/resources"
	"github.com/knative/eventing-sources/pkg/controller/sinks"
	"github.com/knative/pkg/logging"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/equality"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/record"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

type reconciler struct {
	client        client.Client
	scheme        *runtime.Scheme
	dynamicClient dynamic.Interface
	recorder      record.EventRecorder
}

// Reconcile compares the actual state with the desired, and attempts to
// converge the two.
func (r *reconciler) Reconcile(ctx context.Context, object runtime.Object) (runtime.Object, error) {
	logger := logging.FromContext(ctx)

	source, ok := object.(*v1alpha1.ContainerSource)
	if !ok {
		logger.Errorf("could not find container source %v\n", object)
		return object, nil
	}

	// See if the source has been deleted
	accessor, err := meta.Accessor(source)
	if err != nil {
		logger.Warnf("Failed to get metadata accessor: %s", zap.Error(err))
		return object, err
	}
	// No need to reconcile if the source has been marked for deletion.
	deletionTimestamp := accessor.GetDeletionTimestamp()
	if deletionTimestamp != nil {
		return object, nil
	}

	source.Status.InitializeConditions()

	args := &resources.ContainerArguments{
		Name:               source.Name,
		Namespace:          source.Namespace,
		Image:              source.Spec.Image,
		Args:               source.Spec.Args,
		Env:                source.Spec.Env,
		ServiceAccountName: source.Spec.ServiceAccountName,
	}

	err = r.setSinkURIArg(source, args)
	if err != nil {
		return source, err
	}

	deploy, err := r.getDeployment(ctx, source)
	if err != nil {
		if errors.IsNotFound(err) {
			deploy, err = r.createDeployment(ctx, source, nil, args)
			if err != nil {
				r.recorder.Eventf(source, corev1.EventTypeNormal, "DeploymentBlocked", "waiting for %v", err)
				return object, err
			}
			r.recorder.Eventf(source, corev1.EventTypeNormal, "Deployed", "Created deployment %q", deploy.Name)
			source.Status.MarkDeploying("Deploying", "Created deployment %s", deploy.Name)
			// Since the Deployment has just been created, there's nothing more
			// to do until it gets a status. This ContainerSource will be reconciled
			// again when the Deployment is updated.
			return object, nil
		}
		return object, err
	}

	// Update Deployment spec if it's changed
	expected := resources.MakeDeployment(nil, args)
	if !equality.Semantic.DeepEqual(deploy.Spec, expected.Spec) {
		deploy.Spec = expected.Spec
		err := r.client.Update(ctx, deploy)
		// if no error, update the status.
		if err == nil {
			source.Status.MarkDeploying("DeployUpdated", "Updated deployment %s", deploy.Name)
		} else {
			source.Status.MarkDeploying("DeployNeedsUpdate", "Attempting to update deployment %s", deploy.Name)
			r.recorder.Eventf(source, corev1.EventTypeWarning, "DeployNeedsUpdate", "Failed to update deployment %q", deploy.Name)
		}
		// Return after this update or error and reconcile again
		return object, err
	}

	// Update source status
	if deploy.Status.ReadyReplicas > 0 {
		source.Status.MarkDeployed()
	}

	return source, nil
}

func (r *reconciler) setSinkURIArg(source *v1alpha1.ContainerSource, args *resources.ContainerArguments) error {
	if uri, ok := sinkArg(source); ok {
		args.SinkInArgs = true
		source.Status.MarkSink(uri)
		return nil
	}

	if source.Spec.Sink == nil {
		source.Status.MarkNoSink("Missing", "")
		return fmt.Errorf("Sink missing from spec")
	}

	uri, err := sinks.GetSinkURI(r.dynamicClient, source.Spec.Sink, source.Namespace)
	if err != nil {
		source.Status.MarkNoSink("NotFound", "")
		return err
	}
	source.Status.MarkSink(uri)
	args.Sink = uri

	return nil
}

func sinkArg(source *v1alpha1.ContainerSource) (string, bool) {
	for _, a := range source.Spec.Args {
		if strings.HasPrefix(a, "--sink=") {
			return strings.Replace(a, "--sink=", "", -1), true
		}
	}
	return "", false
}

func (r *reconciler) getDeployment(ctx context.Context, source *v1alpha1.ContainerSource) (*appsv1.Deployment, error) {
	logger := logging.FromContext(ctx)

	list := &appsv1.DeploymentList{}
	err := r.client.List(
		ctx,
		&client.ListOptions{
			Namespace:     source.Namespace,
			LabelSelector: labels.Everything(),
			// TODO this is here because the fake client needs it.
			// Remove this when it's no longer needed.
			Raw: &metav1.ListOptions{
				TypeMeta: metav1.TypeMeta{
					APIVersion: appsv1.SchemeGroupVersion.String(),
					Kind:       "Deployment",
				},
			},
		},
		list)
	if err != nil {
		logger.Errorf("Unable to list deployments: %v", zap.Error(err))
		return nil, err
	}
	for _, c := range list.Items {
		if metav1.IsControlledBy(&c, source) {
			return &c, nil
		}
	}
	return nil, errors.NewNotFound(schema.GroupResource{}, "")
}

func (r *reconciler) createDeployment(ctx context.Context, source *v1alpha1.ContainerSource, org *appsv1.Deployment, args *resources.ContainerArguments) (*appsv1.Deployment, error) {
	deployment := resources.MakeDeployment(org, args)

	if err := controllerutil.SetControllerReference(source, deployment, r.scheme); err != nil {
		return nil, err
	}

	if err := r.client.Create(ctx, deployment); err != nil {
		return nil, err
	}
	return deployment, nil
}

func (r *reconciler) InjectClient(c client.Client) error {
	r.client = c
	return nil
}

func (r *reconciler) InjectConfig(c *rest.Config) error {
	var err error
	r.dynamicClient, err = dynamic.NewForConfig(c)
	return err
}
<commit_msg>Use DeepDerivative instead of DeepEqual (#108)<commit_after>/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package containersource

import (
	"context"
	"fmt"
	"strings"

	"go.uber.org/zap"
	"k8s.io/client-go/rest"

	"github.com/knative/eventing-sources/pkg/apis/sources/v1alpha1"
	"github.com/knative/eventing-sources/pkg/controller/containersource/resources"
	"github.com/knative/eventing-sources/pkg/controller/sinks"
	"github.com/knative/pkg/logging"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/equality"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/record"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

type reconciler struct {
	client        client.Client
	scheme        *runtime.Scheme
	dynamicClient dynamic.Interface
	recorder      record.EventRecorder
}

// Reconcile compares the actual state with the desired, and attempts to
// converge the two.
func (r *reconciler) Reconcile(ctx context.Context, object runtime.Object) (runtime.Object, error) {
	logger := logging.FromContext(ctx)

	source, ok := object.(*v1alpha1.ContainerSource)
	if !ok {
		logger.Errorf("could not find container source %v\n", object)
		return object, nil
	}

	// See if the source has been deleted
	accessor, err := meta.Accessor(source)
	if err != nil {
		logger.Warnf("Failed to get metadata accessor: %s", zap.Error(err))
		return object, err
	}
	// No need to reconcile if the source has been marked for deletion.
	deletionTimestamp := accessor.GetDeletionTimestamp()
	if deletionTimestamp != nil {
		return object, nil
	}

	source.Status.InitializeConditions()

	args := &resources.ContainerArguments{
		Name:               source.Name,
		Namespace:          source.Namespace,
		Image:              source.Spec.Image,
		Args:               source.Spec.Args,
		Env:                source.Spec.Env,
		ServiceAccountName: source.Spec.ServiceAccountName,
	}

	err = r.setSinkURIArg(source, args)
	if err != nil {
		return source, err
	}

	deploy, err := r.getDeployment(ctx, source)
	if err != nil {
		if errors.IsNotFound(err) {
			deploy, err = r.createDeployment(ctx, source, nil, args)
			if err != nil {
				r.recorder.Eventf(source, corev1.EventTypeNormal, "DeploymentBlocked", "waiting for %v", err)
				return object, err
			}
			r.recorder.Eventf(source, corev1.EventTypeNormal, "Deployed", "Created deployment %q", deploy.Name)
			source.Status.MarkDeploying("Deploying", "Created deployment %s", deploy.Name)
			// Since the Deployment has just been created, there's nothing more
			// to do until it gets a status. This ContainerSource will be reconciled
			// again when the Deployment is updated.
			return object, nil
		}
		return object, err
	}

	// Update Deployment spec if it's changed
	expected := resources.MakeDeployment(nil, args)
	// Since the Deployment spec has fields defaulted by the webhook, it won't
	// be equal to expected. Use DeepDerivative to compare only the fields that
	// are set in expected.
	if !equality.Semantic.DeepDerivative(expected.Spec, deploy.Spec) {
		deploy.Spec = expected.Spec
		err := r.client.Update(ctx, deploy)
		// if no error, update the status.
		if err == nil {
			source.Status.MarkDeploying("DeployUpdated", "Updated deployment %s", deploy.Name)
		} else {
			source.Status.MarkDeploying("DeployNeedsUpdate", "Attempting to update deployment %s", deploy.Name)
			r.recorder.Eventf(source, corev1.EventTypeWarning, "DeployNeedsUpdate", "Failed to update deployment %q", deploy.Name)
		}
		// Return after this update or error and reconcile again
		return object, err
	}

	// Update source status
	if deploy.Status.ReadyReplicas > 0 {
		source.Status.MarkDeployed()
	}

	return source, nil
}

func (r *reconciler) setSinkURIArg(source *v1alpha1.ContainerSource, args *resources.ContainerArguments) error {
	if uri, ok := sinkArg(source); ok {
		args.SinkInArgs = true
		source.Status.MarkSink(uri)
		return nil
	}

	if source.Spec.Sink == nil {
		source.Status.MarkNoSink("Missing", "")
		return fmt.Errorf("Sink missing from spec")
	}

	uri, err := sinks.GetSinkURI(r.dynamicClient, source.Spec.Sink, source.Namespace)
	if err != nil {
		source.Status.MarkNoSink("NotFound", "")
		return err
	}
	source.Status.MarkSink(uri)
	args.Sink = uri

	return nil
}

func sinkArg(source *v1alpha1.ContainerSource) (string, bool) {
	for _, a := range source.Spec.Args {
		if strings.HasPrefix(a, "--sink=") {
			return strings.Replace(a, "--sink=", "", -1), true
		}
	}
	return "", false
}

func (r *reconciler) getDeployment(ctx context.Context, source *v1alpha1.ContainerSource) (*appsv1.Deployment, error) {
	logger := logging.FromContext(ctx)

	list := &appsv1.DeploymentList{}
	err := r.client.List(
		ctx,
		&client.ListOptions{
			Namespace:     source.Namespace,
			LabelSelector: labels.Everything(),
			// TODO this is here because the fake client needs it.
			// Remove this when it's no longer needed.
			Raw: &metav1.ListOptions{
				TypeMeta: metav1.TypeMeta{
					APIVersion: appsv1.SchemeGroupVersion.String(),
					Kind:       "Deployment",
				},
			},
		},
		list)
	if err != nil {
		logger.Errorf("Unable to list deployments: %v", zap.Error(err))
		return nil, err
	}
	for _, c := range list.Items {
		if metav1.IsControlledBy(&c, source) {
			return &c, nil
		}
	}
	return nil, errors.NewNotFound(schema.GroupResource{}, "")
}

func (r *reconciler) createDeployment(ctx context.Context, source *v1alpha1.ContainerSource, org *appsv1.Deployment, args *resources.ContainerArguments) (*appsv1.Deployment, error) {
	deployment := resources.MakeDeployment(org, args)

	if err := controllerutil.SetControllerReference(source, deployment, r.scheme); err != nil {
		return nil, err
	}

	if err := r.client.Create(ctx, deployment); err != nil {
		return nil, err
	}
	return deployment, nil
}

func (r *reconciler) InjectClient(c client.Client) error {
	r.client = c
	return nil
}

func (r *reconciler) InjectConfig(c *rest.Config) error {
	var err error
	r.dynamicClient, err = dynamic.NewForConfig(c)
	return err
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Jetstack cert-manager contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package acmedns

import (
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
)

var (
	acmednsLiveTest     bool
	acmednsHost         string
	acmednsAccountsJson []byte
	acmednsDomain       string
)

func init() {
	acmednsHost = os.Getenv("ACME_DNS_HOST")
	acmednsAccountsJson = []byte(os.Getenv("ACME_DNS_ACCOUNTS_JSON"))
	acmednsDomain = os.Getenv("ACME_DNS_DOMAIN")
	if len(acmednsHost) > 0 && len(acmednsAccountsJson) > 0 {
		acmednsLiveTest = true
	}
}

func TestLiveAcmeDnsPresent(t *testing.T) {
	if !acmednsLiveTest {
		t.Skip("skipping live test")
	}
	provider, err := NewDNSProviderHostBytes(acmednsHost, acmednsAccountsJson)
	assert.NoError(t, err)

	// ACME-DNS requires 43 character keys or it throws a bad TXT error
	err = provider.Present(acmednsDomain, "", "LG3tptA6W7T1vw4ujbmDxH2lLu6r8TUIqLZD3pzPmgE")
	assert.NoError(t, err)
}
<commit_msg>Fix test for acme-dns provider<commit_after>/*
Copyright 2018 The Jetstack cert-manager contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package acmedns

import (
	"github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util"
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
)

var (
	acmednsLiveTest    bool
	acmednsHost        string
	acmednsAccountJson []byte
	acmednsDomain      string
)

func init() {
	acmednsHost = os.Getenv("ACME_DNS_HOST")
	acmednsAccountJson = []byte(os.Getenv("ACME_DNS_ACCOUNTS_JSON"))
	acmednsDomain = os.Getenv("ACME_DNS_DOMAIN")
	if len(acmednsHost) > 0 && len(acmednsAccountJson) > 0 {
		acmednsLiveTest = true
	}
}

func TestLiveAcmeDnsPresent(t *testing.T) {
	if !acmednsLiveTest {
		t.Skip("skipping live test")
	}
	provider, err := NewDNSProviderHostBytes(acmednsHost, acmednsAccountJson, util.RecursiveNameservers)
	assert.NoError(t, err)

	// ACME-DNS requires 43 character keys or it throws a bad TXT error
	err = provider.Present(acmednsDomain, "", "LG3tptA6W7T1vw4ujbmDxH2lLu6r8TUIqLZD3pzPmgE")
	assert.NoError(t, err)
}
<|endoftext|>