<commit_before>package terraform

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/plans"
	"github.com/hashicorp/terraform/providers"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/states"
)

// NodeDestroyResourceInstance represents a resource instance that is to be
// destroyed.
type NodeDestroyResourceInstance struct {
	*NodeAbstractResourceInstance

	// If DeposedKey is set to anything other than states.NotDeposed then
	// this node destroys a deposed object of the associated instance
	// rather than its current object.
	DeposedKey states.DeposedKey

	CreateBeforeDestroyOverride *bool
}

var (
	_ GraphNodeResource            = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeResourceInstance    = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeDestroyer           = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeDestroyerCBD        = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeReferenceable       = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeReferencer          = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeEvalable            = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeProviderConsumer    = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeProvisionerConsumer = (*NodeDestroyResourceInstance)(nil)
)

func (n *NodeDestroyResourceInstance) Name() string {
	if n.DeposedKey != states.NotDeposed {
		return fmt.Sprintf("%s (destroy deposed %s)", n.ResourceInstanceAddr(), n.DeposedKey)
	}
	return n.ResourceInstanceAddr().String() + " (destroy)"
}

// GraphNodeDestroyer
func (n *NodeDestroyResourceInstance) DestroyAddr() *addrs.AbsResourceInstance {
	addr := n.ResourceInstanceAddr()
	return &addr
}

// GraphNodeDestroyerCBD
func (n *NodeDestroyResourceInstance) CreateBeforeDestroy() bool {
	if n.CreateBeforeDestroyOverride != nil {
		return *n.CreateBeforeDestroyOverride
	}

	// If we have no config, we just assume no
	if n.Config == nil || n.Config.Managed == nil {
		return false
	}

	return n.Config.Managed.CreateBeforeDestroy
}

// GraphNodeDestroyerCBD
func (n *NodeDestroyResourceInstance) ModifyCreateBeforeDestroy(v bool) error {
	n.CreateBeforeDestroyOverride = &v
	return nil
}

// GraphNodeReferenceable, overriding NodeAbstractResource
func (n *NodeDestroyResourceInstance) ReferenceableAddrs() []addrs.Referenceable {
	normalAddrs := n.NodeAbstractResourceInstance.ReferenceableAddrs()
	destroyAddrs := make([]addrs.Referenceable, len(normalAddrs))

	phaseType := addrs.ResourceInstancePhaseDestroy
	if n.CreateBeforeDestroy() {
		phaseType = addrs.ResourceInstancePhaseDestroyCBD
	}

	for i, normalAddr := range normalAddrs {
		switch ta := normalAddr.(type) {
		case addrs.Resource:
			destroyAddrs[i] = ta.Phase(phaseType)
		case addrs.ResourceInstance:
			destroyAddrs[i] = ta.Phase(phaseType)
		default:
			destroyAddrs[i] = normalAddr
		}
	}

	return destroyAddrs
}

// GraphNodeReferencer, overriding NodeAbstractResource
func (n *NodeDestroyResourceInstance) References() []*addrs.Reference {
	// If we have a config, then we need to include destroy-time dependencies
	if c := n.Config; c != nil && c.Managed != nil {
		var result []*addrs.Reference

		// We include conn info and config for destroy time provisioners
		// as dependencies that we have.
		for _, p := range c.Managed.Provisioners {
			schema := n.ProvisionerSchemas[p.Type]

			if p.When == configs.ProvisionerWhenDestroy {
				if p.Connection != nil {
					result = append(result, ReferencesFromConfig(p.Connection.Config, connectionBlockSupersetSchema)...)
				}
				result = append(result, ReferencesFromConfig(p.Config, schema)...)
			}
		}

		return result
	}

	return nil
}

// GraphNodeEvalable
func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
	addr := n.ResourceInstanceAddr()

	// Get our state
	rs := n.ResourceState
	var is *states.ResourceInstance
	if rs != nil {
		is = rs.Instance(n.InstanceKey)
	}
	if is == nil {
		log.Printf("[WARN] NodeDestroyResourceInstance for %s with no state", addr)
	}

	var changeApply *plans.ResourceInstanceChange
	var provider providers.Interface
	var providerSchema *ProviderSchema
	var state *states.ResourceInstanceObject
	var err error
	return &EvalOpFilter{
		Ops: []walkOperation{walkApply, walkDestroy},
		Node: &EvalSequence{
			Nodes: []EvalNode{
				&EvalGetProvider{
					Addr:   n.ResolvedProvider,
					Output: &provider,
					Schema: &providerSchema,
				},

				// Get the saved diff for apply
				&EvalReadDiff{
					Addr:           addr.Resource,
					ProviderSchema: &providerSchema,
					Change:         &changeApply,
				},

				&EvalReduceDiff{
					Addr:      addr.Resource,
					InChange:  &changeApply,
					Destroy:   true,
					OutChange: &changeApply,
				},

				// EvalReduceDiff may have simplified our planned change
				// into a NoOp if it does not require destroying.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						if changeApply == nil || changeApply.Action == plans.NoOp {
							return true, EvalEarlyExitError{}
						}
						return true, nil
					},
					Then: EvalNoop{},
				},

				&EvalReadState{
					Addr:           addr.Resource,
					Output:         &state,
					Provider:       &provider,
					ProviderSchema: &providerSchema,
				},
				&EvalRequireState{
					State: &state,
				},

				// Call pre-apply hook
				&EvalApplyPre{
					Addr:   addr.Resource,
					State:  &state,
					Change: &changeApply,
				},

				// Run destroy provisioners if not tainted
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						if state != nil && state.Status == states.ObjectTainted {
							return false, nil
						}

						return true, nil
					},

					Then: &EvalApplyProvisioners{
						Addr:           addr.Resource,
						State:          &state,
						ResourceConfig: n.Config,
						Error:          &err,
						When:           configs.ProvisionerWhenDestroy,
					},
				},

				// If we have a provisioning error, then we just call
				// the post-apply hook now.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						return err != nil, nil
					},

					Then: &EvalApplyPost{
						Addr:  addr.Resource,
						State: &state,
						Error: &err,
					},
				},

				// Make sure we handle data sources properly.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						return addr.Resource.Resource.Mode == addrs.DataResourceMode, nil
					},

					Then: &EvalReadDataApply{
						Addr:           addr.Resource,
						Config:         n.Config,
						Change:         &changeApply,
						Provider:       &provider,
						ProviderAddr:   n.ResolvedProvider,
						ProviderSchema: &providerSchema,
						Output:         &state,
					},
					Else: &EvalApply{
						Addr:           addr.Resource,
						Config:         nil, // No configuration because we are destroying
						State:          &state,
						Change:         &changeApply,
						Provider:       &provider,
						ProviderAddr:   n.ResolvedProvider,
						ProviderSchema: &providerSchema,
						Output:         &state,
						Error:          &err,
					},
				},
				&EvalWriteState{
					Addr:           addr.Resource,
					ProviderAddr:   n.ResolvedProvider,
					ProviderSchema: &providerSchema,
					State:          &state,
				},
				&EvalApplyPost{
					Addr:  addr.Resource,
					State: &state,
					Error: &err,
				},
				&EvalUpdateStateHook{},
			},
		},
	}
}

// NodeDestroyResourceInstance represents a resource that is to be destroyed.
//
// Destroying a resource is a state-only operation: it is the individual
// instances being destroyed that affects remote objects. During graph
// construction, NodeDestroyResource should always depend on any other node
// related to the given resource, since it's just a final cleanup to avoid
// leaving skeleton resource objects in state after their instances have
// all been destroyed.
type NodeDestroyResource struct {
	*NodeAbstractResource
}

var (
	_ GraphNodeResource      = (*NodeDestroyResource)(nil)
	_ GraphNodeReferenceable = (*NodeDestroyResource)(nil)
	_ GraphNodeReferencer    = (*NodeDestroyResource)(nil)
	_ GraphNodeEvalable      = (*NodeDestroyResource)(nil)

	// FIXME: this is here to document that this node is both
	// GraphNodeProviderConsumer by virtue of the embedded
	// NodeAbstractResource, but that behavior is not desired and we skip it by
	// checking for GraphNodeNoProvider.
	_ GraphNodeProviderConsumer = (*NodeDestroyResource)(nil)
	_ GraphNodeNoProvider       = (*NodeDestroyResource)(nil)
)

func (n *NodeDestroyResource) Name() string {
	return n.ResourceAddr().String() + " (clean up state)"
}

// GraphNodeReferenceable, overriding NodeAbstractResource
func (n *NodeDestroyResource) ReferenceableAddrs() []addrs.Referenceable {
	// NodeDestroyResource doesn't participate in references: the graph
	// builder that created it should ensure directly that it already depends
	// on every other node related to its resource, without relying on
	// references.
	return nil
}

// GraphNodeReferencer, overriding NodeAbstractResource
func (n *NodeDestroyResource) References() []*addrs.Reference {
	// NodeDestroyResource doesn't participate in references: the graph
	// builder that created it should ensure directly that it already depends
	// on every other node related to its resource, without relying on
	// references.
	return nil
}

// GraphNodeEvalable
func (n *NodeDestroyResource) EvalTree() EvalNode {
	// This EvalNode will produce an error if the resource isn't already
	// empty by the time it is called, since it should just be pruning the
	// leftover husk of a resource in state after all of the child instances
	// and their objects were destroyed.
	return &EvalForgetResourceState{
		Addr: n.ResourceAddr().Resource,
	}
}

// GraphNodeResource
func (n *NodeDestroyResource) ResourceAddr() addrs.AbsResource {
	return n.NodeAbstractResource.ResourceAddr()
}

// GraphNodeSubpath
func (n *NodeDestroyResource) Path() addrs.ModuleInstance {
	return n.NodeAbstractResource.Path()
}

// GraphNodeNoProvider
// FIXME: this should be removed once the node can be separated from the
// Internal NodeAbstractResource behavior.
func (n *NodeDestroyResource) NoProvider() {
}

type GraphNodeNoProvider interface {
	NoProvider()
}
<commit_msg>use CreateBeforeDestroy from state<commit_after>package terraform

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/plans"
	"github.com/hashicorp/terraform/providers"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/states"
)

// NodeDestroyResourceInstance represents a resource instance that is to be
// destroyed.
type NodeDestroyResourceInstance struct {
	*NodeAbstractResourceInstance

	// If DeposedKey is set to anything other than states.NotDeposed then
	// this node destroys a deposed object of the associated instance
	// rather than its current object.
	DeposedKey states.DeposedKey

	CreateBeforeDestroyOverride *bool
}

var (
	_ GraphNodeResource            = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeResourceInstance    = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeDestroyer           = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeDestroyerCBD        = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeReferenceable       = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeReferencer          = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeEvalable            = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeProviderConsumer    = (*NodeDestroyResourceInstance)(nil)
	_ GraphNodeProvisionerConsumer = (*NodeDestroyResourceInstance)(nil)
)

func (n *NodeDestroyResourceInstance) Name() string {
	if n.DeposedKey != states.NotDeposed {
		return fmt.Sprintf("%s (destroy deposed %s)", n.ResourceInstanceAddr(), n.DeposedKey)
	}
	return n.ResourceInstanceAddr().String() + " (destroy)"
}

// GraphNodeDestroyer
func (n *NodeDestroyResourceInstance) DestroyAddr() *addrs.AbsResourceInstance {
	addr := n.ResourceInstanceAddr()
	return &addr
}

// GraphNodeDestroyerCBD
func (n *NodeDestroyResourceInstance) CreateBeforeDestroy() bool {
	if n.CreateBeforeDestroyOverride != nil {
		return *n.CreateBeforeDestroyOverride
	}

	// Config takes precedence
	if n.Config != nil && n.Config.Managed != nil {
		return n.Config.Managed.CreateBeforeDestroy
	}

	// Otherwise check the state for a stored destroy order
	if rs := n.ResourceState; rs != nil {
		if s := rs.Instance(n.InstanceKey); s != nil {
			if s.Current != nil {
				return s.Current.CreateBeforeDestroy
			}
		}
	}

	return false
}

// GraphNodeDestroyerCBD
func (n *NodeDestroyResourceInstance) ModifyCreateBeforeDestroy(v bool) error {
	n.CreateBeforeDestroyOverride = &v
	return nil
}

// GraphNodeReferenceable, overriding NodeAbstractResource
func (n *NodeDestroyResourceInstance) ReferenceableAddrs() []addrs.Referenceable {
	normalAddrs := n.NodeAbstractResourceInstance.ReferenceableAddrs()
	destroyAddrs := make([]addrs.Referenceable, len(normalAddrs))

	phaseType := addrs.ResourceInstancePhaseDestroy
	if n.CreateBeforeDestroy() {
		phaseType = addrs.ResourceInstancePhaseDestroyCBD
	}

	for i, normalAddr := range normalAddrs {
		switch ta := normalAddr.(type) {
		case addrs.Resource:
			destroyAddrs[i] = ta.Phase(phaseType)
		case addrs.ResourceInstance:
			destroyAddrs[i] = ta.Phase(phaseType)
		default:
			destroyAddrs[i] = normalAddr
		}
	}

	return destroyAddrs
}

// GraphNodeReferencer, overriding NodeAbstractResource
func (n *NodeDestroyResourceInstance) References() []*addrs.Reference {
	// If we have a config, then we need to include destroy-time dependencies
	if c := n.Config; c != nil && c.Managed != nil {
		var result []*addrs.Reference

		// We include conn info and config for destroy time provisioners
		// as dependencies that we have.
		for _, p := range c.Managed.Provisioners {
			schema := n.ProvisionerSchemas[p.Type]

			if p.When == configs.ProvisionerWhenDestroy {
				if p.Connection != nil {
					result = append(result, ReferencesFromConfig(p.Connection.Config, connectionBlockSupersetSchema)...)
				}
				result = append(result, ReferencesFromConfig(p.Config, schema)...)
			}
		}

		return result
	}

	return nil
}

// GraphNodeEvalable
func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
	addr := n.ResourceInstanceAddr()

	// Get our state
	rs := n.ResourceState
	var is *states.ResourceInstance
	if rs != nil {
		is = rs.Instance(n.InstanceKey)
	}
	if is == nil {
		log.Printf("[WARN] NodeDestroyResourceInstance for %s with no state", addr)
	}

	var changeApply *plans.ResourceInstanceChange
	var provider providers.Interface
	var providerSchema *ProviderSchema
	var state *states.ResourceInstanceObject
	var err error
	return &EvalOpFilter{
		Ops: []walkOperation{walkApply, walkDestroy},
		Node: &EvalSequence{
			Nodes: []EvalNode{
				&EvalGetProvider{
					Addr:   n.ResolvedProvider,
					Output: &provider,
					Schema: &providerSchema,
				},

				// Get the saved diff for apply
				&EvalReadDiff{
					Addr:           addr.Resource,
					ProviderSchema: &providerSchema,
					Change:         &changeApply,
				},

				&EvalReduceDiff{
					Addr:      addr.Resource,
					InChange:  &changeApply,
					Destroy:   true,
					OutChange: &changeApply,
				},

				// EvalReduceDiff may have simplified our planned change
				// into a NoOp if it does not require destroying.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						if changeApply == nil || changeApply.Action == plans.NoOp {
							return true, EvalEarlyExitError{}
						}
						return true, nil
					},
					Then: EvalNoop{},
				},

				&EvalReadState{
					Addr:           addr.Resource,
					Output:         &state,
					Provider:       &provider,
					ProviderSchema: &providerSchema,
				},
				&EvalRequireState{
					State: &state,
				},

				// Call pre-apply hook
				&EvalApplyPre{
					Addr:   addr.Resource,
					State:  &state,
					Change: &changeApply,
				},

				// Run destroy provisioners if not tainted
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						if state != nil && state.Status == states.ObjectTainted {
							return false, nil
						}

						return true, nil
					},

					Then: &EvalApplyProvisioners{
						Addr:           addr.Resource,
						State:          &state,
						ResourceConfig: n.Config,
						Error:          &err,
						When:           configs.ProvisionerWhenDestroy,
					},
				},

				// If we have a provisioning error, then we just call
				// the post-apply hook now.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						return err != nil, nil
					},

					Then: &EvalApplyPost{
						Addr:  addr.Resource,
						State: &state,
						Error: &err,
					},
				},

				// Make sure we handle data sources properly.
				&EvalIf{
					If: func(ctx EvalContext) (bool, error) {
						return addr.Resource.Resource.Mode == addrs.DataResourceMode, nil
					},

					Then: &EvalReadDataApply{
						Addr:           addr.Resource,
						Config:         n.Config,
						Change:         &changeApply,
						Provider:       &provider,
						ProviderAddr:   n.ResolvedProvider,
						ProviderSchema: &providerSchema,
						Output:         &state,
					},
					Else: &EvalApply{
						Addr:           addr.Resource,
						Config:         nil, // No configuration because we are destroying
						State:          &state,
						Change:         &changeApply,
						Provider:       &provider,
						ProviderAddr:   n.ResolvedProvider,
						ProviderSchema: &providerSchema,
						Output:         &state,
						Error:          &err,
					},
				},
				&EvalWriteState{
					Addr:           addr.Resource,
					ProviderAddr:   n.ResolvedProvider,
					ProviderSchema: &providerSchema,
					State:          &state,
				},
				&EvalApplyPost{
					Addr:  addr.Resource,
					State: &state,
					Error: &err,
				},
				&EvalUpdateStateHook{},
			},
		},
	}
}

// NodeDestroyResourceInstance represents a resource that is to be destroyed.
//
// Destroying a resource is a state-only operation: it is the individual
// instances being destroyed that affects remote objects. During graph
// construction, NodeDestroyResource should always depend on any other node
// related to the given resource, since it's just a final cleanup to avoid
// leaving skeleton resource objects in state after their instances have
// all been destroyed.
type NodeDestroyResource struct {
	*NodeAbstractResource
}

var (
	_ GraphNodeResource      = (*NodeDestroyResource)(nil)
	_ GraphNodeReferenceable = (*NodeDestroyResource)(nil)
	_ GraphNodeReferencer    = (*NodeDestroyResource)(nil)
	_ GraphNodeEvalable      = (*NodeDestroyResource)(nil)

	// FIXME: this is here to document that this node is both
	// GraphNodeProviderConsumer by virtue of the embedded
	// NodeAbstractResource, but that behavior is not desired and we skip it by
	// checking for GraphNodeNoProvider.
	_ GraphNodeProviderConsumer = (*NodeDestroyResource)(nil)
	_ GraphNodeNoProvider       = (*NodeDestroyResource)(nil)
)

func (n *NodeDestroyResource) Name() string {
	return n.ResourceAddr().String() + " (clean up state)"
}

// GraphNodeReferenceable, overriding NodeAbstractResource
func (n *NodeDestroyResource) ReferenceableAddrs() []addrs.Referenceable {
	// NodeDestroyResource doesn't participate in references: the graph
	// builder that created it should ensure directly that it already depends
	// on every other node related to its resource, without relying on
	// references.
	return nil
}

// GraphNodeReferencer, overriding NodeAbstractResource
func (n *NodeDestroyResource) References() []*addrs.Reference {
	// NodeDestroyResource doesn't participate in references: the graph
	// builder that created it should ensure directly that it already depends
	// on every other node related to its resource, without relying on
	// references.
	return nil
}

// GraphNodeEvalable
func (n *NodeDestroyResource) EvalTree() EvalNode {
	// This EvalNode will produce an error if the resource isn't already
	// empty by the time it is called, since it should just be pruning the
	// leftover husk of a resource in state after all of the child instances
	// and their objects were destroyed.
	return &EvalForgetResourceState{
		Addr: n.ResourceAddr().Resource,
	}
}

// GraphNodeResource
func (n *NodeDestroyResource) ResourceAddr() addrs.AbsResource {
	return n.NodeAbstractResource.ResourceAddr()
}

// GraphNodeSubpath
func (n *NodeDestroyResource) Path() addrs.ModuleInstance {
	return n.NodeAbstractResource.Path()
}

// GraphNodeNoProvider
// FIXME: this should be removed once the node can be separated from the
// Internal NodeAbstractResource behavior.
func (n *NodeDestroyResource) NoProvider() {
}

type GraphNodeNoProvider interface {
	NoProvider()
}
<|endoftext|>


<commit_before>package cors

import (
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/codegangsta/martini"
)

func Test_AllowAll(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins: true,
	}))

	r, _ := http.NewRequest("PUT", "foo", nil)
	m.ServeHTTP(recorder, r)

	if recorder.HeaderMap.Get(headerAllowOrigin) != "*" {
		t.Errorf("Allow-Origin header should be *")
	}
}

func Test_AllowRegexMatch(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowOrigins: []string{"https://aaa.com", "https://foo\\.*"},
	}))

	origin := "https://foo.com"
	r, _ := http.NewRequest("PUT", "foo", nil)
	r.Header.Add("Origin", origin)
	m.ServeHTTP(recorder, r)

	headerValue := recorder.HeaderMap.Get(headerAllowOrigin)
	if headerValue != origin {
		t.Errorf("Allow-Origin header should be %v, found %v", origin, headerValue)
	}
}

func Test_AllowRegexNoMatch(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowOrigins: []string{"https://foo\\.*"},
	}))

	origin := "https://bar.com"
	r, _ := http.NewRequest("PUT", "foo", nil)
	r.Header.Add("Origin", origin)
	m.ServeHTTP(recorder, r)

	headerValue := recorder.HeaderMap.Get(headerAllowOrigin)
	if headerValue != "" {
		t.Errorf("Allow-Origin header should not exist, found %v", headerValue)
	}
}

func Test_OtherHeaders(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins:  true,
		AllowCredentials: true,
		AllowMethods:     []string{"PATCH", "GET"},
		AllowHeaders:     []string{"Origin", "X-whatever"},
		ExposeHeaders:    []string{"Content-Length"},
		MaxAge:           5 * time.Minute,
	}))

	r, _ := http.NewRequest("PUT", "foo", nil)
	m.ServeHTTP(recorder, r)

	credentialsVal := recorder.HeaderMap.Get(headerAllowCredentials)
	methodsVal := recorder.HeaderMap.Get(headerAllowMethods)
	headersVal := recorder.HeaderMap.Get(headerAllowHeaders)
	exposedHeadersVal := recorder.HeaderMap.Get(headerExposeHeaders)
	maxAgeVal := recorder.HeaderMap.Get(headerMaxAge)

	if credentialsVal != "true" {
		t.Errorf("Allow-Credentials is expected to be true, found %v", credentialsVal)
	}

	if methodsVal != "PATCH,GET" {
		t.Errorf("Allow-Methods is expected to be PATCH,GET; found %v", methodsVal)
	}

	if headersVal != "Origin,X-whatever" {
		t.Errorf("Allow-Headers is expected to be Origin,X-whatever; found %v", headersVal)
	}

	if exposedHeadersVal != "Content-Length" {
		t.Errorf("Expose-Headers are expected to be Content-Length, found %v", exposedHeadersVal)
	}

	if maxAgeVal != "300" {
		t.Errorf("Max-Age is expected to be 300, found %v", maxAgeVal)
	}
}

func Test_Preflight(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins: true,
		AllowMethods:    []string{"PUT", "PATCH"},
		AllowHeaders:    []string{"Origin", "X-whatever"},
	}))

	r, _ := http.NewRequest("OPTIONS", "foo", nil)
	r.Header.Add(headerRequestMethod, "PUT")
	r.Header.Add(headerRequestHeaders, "X-whatever")
	m.ServeHTTP(recorder, r)

	methodsVal := recorder.HeaderMap.Get(headerAllowMethods)
	headersVal := recorder.HeaderMap.Get(headerAllowHeaders)

	if methodsVal != "PUT,PATCH" {
		t.Errorf("Allow-Methods is expected to be PUT,PATCH, found %v", methodsVal)
	}

	if headersVal != "X-whatever" {
		t.Errorf("Allow-Headers is expected to be X-whatever, found %v", headersVal)
	}
}

func Benchmark_WithoutCORS(b *testing.B) {
	recorder := httptest.NewRecorder()
	m := martini.New()

	b.ResetTimer()
	for i := 0; i < 100; i++ {
		r, _ := http.NewRequest("PUT", "foo", nil)
		m.ServeHTTP(recorder, r)
	}
}

func Benchmark_WithCORS(b *testing.B) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins:  true,
		AllowCredentials: true,
		AllowMethods:     []string{"PATCH", "GET"},
		AllowHeaders:     []string{"Origin", "X-whatever"},
		MaxAge:           5 * time.Minute,
	}))

	b.ResetTimer()
	for i := 0; i < 100; i++ {
		r, _ := http.NewRequest("PUT", "foo", nil)
		m.ServeHTTP(recorder, r)
	}
}
<commit_msg>Testing multiple expose headers.<commit_after>package cors

import (
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/codegangsta/martini"
)

func Test_AllowAll(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins: true,
	}))

	r, _ := http.NewRequest("PUT", "foo", nil)
	m.ServeHTTP(recorder, r)

	if recorder.HeaderMap.Get(headerAllowOrigin) != "*" {
		t.Errorf("Allow-Origin header should be *")
	}
}

func Test_AllowRegexMatch(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowOrigins: []string{"https://aaa.com", "https://foo\\.*"},
	}))

	origin := "https://foo.com"
	r, _ := http.NewRequest("PUT", "foo", nil)
	r.Header.Add("Origin", origin)
	m.ServeHTTP(recorder, r)

	headerValue := recorder.HeaderMap.Get(headerAllowOrigin)
	if headerValue != origin {
		t.Errorf("Allow-Origin header should be %v, found %v", origin, headerValue)
	}
}

func Test_AllowRegexNoMatch(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowOrigins: []string{"https://foo\\.*"},
	}))

	origin := "https://bar.com"
	r, _ := http.NewRequest("PUT", "foo", nil)
	r.Header.Add("Origin", origin)
	m.ServeHTTP(recorder, r)

	headerValue := recorder.HeaderMap.Get(headerAllowOrigin)
	if headerValue != "" {
		t.Errorf("Allow-Origin header should not exist, found %v", headerValue)
	}
}

func Test_OtherHeaders(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins:  true,
		AllowCredentials: true,
		AllowMethods:     []string{"PATCH", "GET"},
		AllowHeaders:     []string{"Origin", "X-whatever"},
		ExposeHeaders:    []string{"Content-Length", "Hello"},
		MaxAge:           5 * time.Minute,
	}))

	r, _ := http.NewRequest("PUT", "foo", nil)
	m.ServeHTTP(recorder, r)

	credentialsVal := recorder.HeaderMap.Get(headerAllowCredentials)
	methodsVal := recorder.HeaderMap.Get(headerAllowMethods)
	headersVal := recorder.HeaderMap.Get(headerAllowHeaders)
	exposedHeadersVal := recorder.HeaderMap.Get(headerExposeHeaders)
	maxAgeVal := recorder.HeaderMap.Get(headerMaxAge)

	if credentialsVal != "true" {
		t.Errorf("Allow-Credentials is expected to be true, found %v", credentialsVal)
	}

	if methodsVal != "PATCH,GET" {
		t.Errorf("Allow-Methods is expected to be PATCH,GET; found %v", methodsVal)
	}

	if headersVal != "Origin,X-whatever" {
		t.Errorf("Allow-Headers is expected to be Origin,X-whatever; found %v", headersVal)
	}

	if exposedHeadersVal != "Content-Length,Hello" {
		t.Errorf("Expose-Headers are expected to be Content-Length,Hello. Found %v", exposedHeadersVal)
	}

	if maxAgeVal != "300" {
		t.Errorf("Max-Age is expected to be 300, found %v", maxAgeVal)
	}
}

func Test_Preflight(t *testing.T) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins: true,
		AllowMethods:    []string{"PUT", "PATCH"},
		AllowHeaders:    []string{"Origin", "X-whatever"},
	}))

	r, _ := http.NewRequest("OPTIONS", "foo", nil)
	r.Header.Add(headerRequestMethod, "PUT")
	r.Header.Add(headerRequestHeaders, "X-whatever")
	m.ServeHTTP(recorder, r)

	methodsVal := recorder.HeaderMap.Get(headerAllowMethods)
	headersVal := recorder.HeaderMap.Get(headerAllowHeaders)

	if methodsVal != "PUT,PATCH" {
		t.Errorf("Allow-Methods is expected to be PUT,PATCH, found %v", methodsVal)
	}

	if headersVal != "X-whatever" {
		t.Errorf("Allow-Headers is expected to be X-whatever, found %v", headersVal)
	}
}

func Benchmark_WithoutCORS(b *testing.B) {
	recorder := httptest.NewRecorder()
	m := martini.New()

	b.ResetTimer()
	for i := 0; i < 100; i++ {
		r, _ := http.NewRequest("PUT", "foo", nil)
		m.ServeHTTP(recorder, r)
	}
}

func Benchmark_WithCORS(b *testing.B) {
	recorder := httptest.NewRecorder()
	m := martini.New()
	m.Use(Allow(&Options{
		AllowAllOrigins:  true,
		AllowCredentials: true,
		AllowMethods:     []string{"PATCH", "GET"},
		AllowHeaders:     []string{"Origin", "X-whatever"},
		MaxAge:           5 * time.Minute,
	}))

	b.ResetTimer()
	for i := 0; i < 100; i++ {
		r, _ := http.NewRequest("PUT", "foo", nil)
		m.ServeHTTP(recorder, r)
	}
}
<|endoftext|>


<commit_before>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 main

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/moov-io/ach"
)

func main() {
	// To create a file
	fh := ach.NewFileHeader()
	fh.ImmediateDestination = "231380104"
	fh.ImmediateOrigin = "121042882"
	fh.FileCreationDate = time.Now().Format("060102")
	fh.ImmediateDestinationName = "Federal Reserve Bank"
	fh.ImmediateOriginName = "My Bank Name"
	file := ach.NewFile()
	file.SetHeader(fh)

	// To create a batch.
	// Errors only if payment type is not supported.
	bh := ach.NewBatchHeader()
	bh.ServiceClassCode = ach.MixedDebitsAndCredits
	bh.CompanyName = "Your Company"
	bh.CompanyIdentification = file.Header.ImmediateOrigin
	bh.StandardEntryClassCode = ach.PPD
	bh.CompanyEntryDescription = "Trans. Description"
	bh.EffectiveEntryDate = time.Now().AddDate(0, 0, 1).Format("060102") // YYMMDD
	bh.ODFIIdentification = "121042882"

	batch, _ := ach.NewBatch(bh)

	// To create an entry
	entry := ach.NewEntryDetail()
	entry.TransactionCode = ach.CheckingCredit
	entry.SetRDFI("231380104")
	entry.DFIAccountNumber = "81967038518"
	entry.Amount = 1000000
	entry.IndividualName = "Wade Arnold"
	entry.SetTraceNumber("12345678", 1)
	entry.IdentificationNumber = "ABC##jvkdjfuiwn"
	entry.Category = ach.CategoryForward
	entry.AddendaRecordIndicator = 1

	// To add one or more optional addenda records for an entry

	addenda := ach.NewAddenda05()
	addenda.PaymentRelatedInformation = "bonus pay for amazing work on #OSS"
	entry.AddAddenda05(addenda)

	// Entries are added to batches like so:

	batch.AddEntry(entry)

	// When all of the Entries are added to the batch we must create it.

	if err := batch.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}

	// And batches are added to files much the same way:

	file.AddBatch(batch)

	// Now add a new batch for accepting payments on the web

	bh2 := ach.NewBatchHeader()
	bh2.ServiceClassCode = ach.CreditsOnly
	bh2.CompanyName = "Your Company"
	bh2.CompanyIdentification = file.Header.ImmediateOrigin
	bh2.StandardEntryClassCode = ach.WEB
	bh2.CompanyEntryDescription = "Subscribe"
	bh2.EffectiveEntryDate = time.Now().AddDate(0, 0, 1).Format("060102") // YYMMDD
	bh2.ODFIIdentification = "121042882"

	batch2, _ := ach.NewBatch(bh2)

	// Add an entry and define if it is a single or recurring payment
	// The following is a recurring payment for $7.99

	entry2 := ach.NewEntryDetail()
	entry2.TransactionCode = ach.CheckingCredit
	entry2.SetRDFI("231380104")
	entry2.DFIAccountNumber = "81967038518"
	entry2.Amount = 799
	entry2.IndividualName = "Wade Arnold"
	entry2.SetTraceNumber("87654321", 2)
	entry2.IdentificationNumber = "#123456"
	entry2.DiscretionaryData = "R"
	entry2.Category = ach.CategoryForward
	entry2.AddendaRecordIndicator = 1

	// To add one or more optional addenda records for an entry
	addenda2 := ach.NewAddenda05()
	addenda2.PaymentRelatedInformation = "Monthly Membership Subscription"
	entry2.AddAddenda05(addenda2)

	// add the entry to the batch
	batch2.AddEntry(entry2)

	// Create and add the second batch
	if err := batch2.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	file.AddBatch(batch2)

	// Once we added all our batches we must create the file

	if err := file.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	// Check if the trace number was kept
	batch1Entries := file.Batches[0].GetEntries()

	if batch1Entries[0].TraceNumber != "123456780000001" {
		log.Fatal("TraceNumber was not kept " + batch1Entries[0].TraceNumber )
	}

	batch2Entries := file.Batches[1].GetEntries()

	if batch2Entries[0].TraceNumber != "876543210000001" {
		log.Fatal("TraceNumber was not kept " + batch1Entries[0].TraceNumber )
	}

	// Finally we wnt to write the file to an io.Writer
	w := ach.NewWriter(os.Stdout)
	if err := w.Write(file); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	w.Flush()
}
<commit_msg>Fix in test<commit_after>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 main

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/moov-io/ach"
)

func main() {
	// To create a file
	fh := ach.NewFileHeader()
	fh.ImmediateDestination = "231380104"
	fh.ImmediateOrigin = "121042882"
	fh.FileCreationDate = time.Now().Format("060102")
	fh.ImmediateDestinationName = "Federal Reserve Bank"
	fh.ImmediateOriginName = "My Bank Name"
	file := ach.NewFile()
	file.SetHeader(fh)

	// To create a batch.
	// Errors only if payment type is not supported.
	bh := ach.NewBatchHeader()
	bh.ServiceClassCode = ach.MixedDebitsAndCredits
	bh.CompanyName = "Your Company"
	bh.CompanyIdentification = file.Header.ImmediateOrigin
	bh.StandardEntryClassCode = ach.PPD
	bh.CompanyEntryDescription = "Trans. Description"
	bh.EffectiveEntryDate = time.Now().AddDate(0, 0, 1).Format("060102") // YYMMDD
	bh.ODFIIdentification = "121042882"

	batch, _ := ach.NewBatch(bh)

	// To create an entry
	entry := ach.NewEntryDetail()
	entry.TransactionCode = ach.CheckingCredit
	entry.SetRDFI("231380104")
	entry.DFIAccountNumber = "81967038518"
	entry.Amount = 1000000
	entry.IndividualName = "Wade Arnold"
	entry.SetTraceNumber("12345678", 1)
	entry.IdentificationNumber = "ABC##jvkdjfuiwn"
	entry.Category = ach.CategoryForward
	entry.AddendaRecordIndicator = 1

	// To add one or more optional addenda records for an entry

	addenda := ach.NewAddenda05()
	addenda.PaymentRelatedInformation = "bonus pay for amazing work on #OSS"
	entry.AddAddenda05(addenda)

	// Entries are added to batches like so:

	batch.AddEntry(entry)

	// When all of the Entries are added to the batch we must create it.

	if err := batch.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}

	// And batches are added to files much the same way:

	file.AddBatch(batch)

	// Now add a new batch for accepting payments on the web

	bh2 := ach.NewBatchHeader()
	bh2.ServiceClassCode = ach.CreditsOnly
	bh2.CompanyName = "Your Company"
	bh2.CompanyIdentification = file.Header.ImmediateOrigin
	bh2.StandardEntryClassCode = ach.WEB
	bh2.CompanyEntryDescription = "Subscribe"
	bh2.EffectiveEntryDate = time.Now().AddDate(0, 0, 1).Format("060102") // YYMMDD
	bh2.ODFIIdentification = "121042882"

	batch2, _ := ach.NewBatch(bh2)

	// Add an entry and define if it is a single or recurring payment
	// The following is a recurring payment for $7.99

	entry2 := ach.NewEntryDetail()
	entry2.TransactionCode = ach.CheckingCredit
	entry2.SetRDFI("231380104")
	entry2.DFIAccountNumber = "81967038518"
	entry2.Amount = 799
	entry2.IndividualName = "Wade Arnold"
	entry2.SetTraceNumber("87654321", 2)
	entry2.IdentificationNumber = "#123456"
	entry2.DiscretionaryData = "R"
	entry2.Category = ach.CategoryForward
	entry2.AddendaRecordIndicator = 1

	// To add one or more optional addenda records for an entry
	addenda2 := ach.NewAddenda05()
	addenda2.PaymentRelatedInformation = "Monthly Membership Subscription"
	entry2.AddAddenda05(addenda2)

	// add the entry to the batch
	batch2.AddEntry(entry2)

	// Create and add the second batch
	if err := batch2.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	file.AddBatch(batch2)

	// Once we added all our batches we must create the file

	if err := file.Create(); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	// Check if the trace number was kept
	batch1Entries := file.Batches[0].GetEntries()

	if batch1Entries[0].TraceNumber != "123456780000001" {
		log.Fatal("TraceNumber was not kept " + batch1Entries[0].TraceNumber)
	}

	batch2Entries := file.Batches[1].GetEntries()

	if batch2Entries[0].TraceNumber != "876543210000002" {
		log.Fatal("TraceNumber was not kept " + batch2Entries[0].TraceNumber)
	}

	// Finally we wnt to write the file to an io.Writer
	w := ach.NewWriter(os.Stdout)
	if err := w.Write(file); err != nil {
		fmt.Printf("%T: %s", err, err)
	}
	w.Flush()
}
<|endoftext|>


<commit_before>package response

import (
	"testing"

	"github.com/miekg/coredns/middleware/test"

	"github.com/miekg/dns"
)

func TestTypifyNilMsg(t *testing.T) {
	var m *dns.Msg = nil

	ty, _ := Typify(m)
	if ty != OtherError {
		t.Errorf("message wrongly typified, expected OtherError, got %d", ty)
	}
}

func TestClassifyDelegation(t *testing.T) {
	m := delegationMsg()
	mt, _ := Typify(m)
	if mt != Delegation {
		t.Errorf("message is wrongly classified, expected delegation, got %d", mt)
	}
}

func delegationMsg() *dns.Msg {
	return &dns.Msg{
		Ns: []dns.RR{
			test.NS("miek.nl.	3600	IN	NS	linode.atoom.net."),
			test.NS("miek.nl.	3600	IN	NS	ns-ext.nlnetlabs.nl."),
			test.NS("miek.nl.	3600	IN	NS	omval.tednet.nl."),
		},
		Extra: []dns.RR{
			test.A("omval.tednet.nl.	3600	IN	A	185.49.141.42"),
			test.AAAA("omval.tednet.nl.	3600	IN	AAAA	2a04:b900:0:100::42"),
		},
	}
}
<commit_msg>Small golint cleanup. (#338)<commit_after>package response

import (
	"testing"

	"github.com/miekg/coredns/middleware/test"

	"github.com/miekg/dns"
)

func TestTypifyNilMsg(t *testing.T) {
	var m *dns.Msg

	ty, _ := Typify(m)
	if ty != OtherError {
		t.Errorf("message wrongly typified, expected OtherError, got %d", ty)
	}
}

func TestClassifyDelegation(t *testing.T) {
	m := delegationMsg()
	mt, _ := Typify(m)
	if mt != Delegation {
		t.Errorf("message is wrongly classified, expected delegation, got %d", mt)
	}
}

func delegationMsg() *dns.Msg {
	return &dns.Msg{
		Ns: []dns.RR{
			test.NS("miek.nl.	3600	IN	NS	linode.atoom.net."),
			test.NS("miek.nl.	3600	IN	NS	ns-ext.nlnetlabs.nl."),
			test.NS("miek.nl.	3600	IN	NS	omval.tednet.nl."),
		},
		Extra: []dns.RR{
			test.A("omval.tednet.nl.	3600	IN	A	185.49.141.42"),
			test.AAAA("omval.tednet.nl.	3600	IN	AAAA	2a04:b900:0:100::42"),
		},
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct{}

func getIP(servertype, servername string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		log.Printf("Does %v = %v and %v = %v?", s.Name, servertype, s.Identifier, servername)
		if s.Name == servertype && s.Identifier == servername {
			log.Printf("RETURNING: %v", s)
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	log.Printf("Assessing server %v", server)
	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		log.Printf("Err %v", err)
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		log.Printf("Err %v", err)
		return list, conf
	}

	return r, r2
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("RUNNING: %v on %v", job, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		conn, _ := grpc.Dial(ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		slave.Run(context.Background(), job)
		log.Printf("RUN COMMAND SENT %v", job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	log.Printf("DISCOVERED: %v", r)
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	for s.serving {
		time.Sleep(intentWait)

		log.Printf("Getting state")
		state := getConfig(&mainChecker{})
		log.Printf("Computing Diff")
		diff := configDiff(s.config, state)
		log.Printf("Determining jobs to run")
		joblist := runJobs(diff)
		log.Printf("MATCH FOUND %v from %v and %v", joblist, state, s.config)
		for _, job := range joblist {
			runJob(job, chooseServer(job, &mainChecker{}))
		}
		log.Printf("Completed Intent Run")
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.Serve()
	}
}
<commit_msg>Timeout on run requests<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct{}

func getIP(servertype, servername string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		log.Printf("Does %v = %v and %v = %v?", s.Name, servertype, s.Identifier, servername)
		if s.Name == servertype && s.Identifier == servername {
			log.Printf("RETURNING: %v", s)
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	log.Printf("Assessing server %v", server)
	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		log.Printf("Err %v", err)
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		log.Printf("Err %v", err)
		return list, conf
	}

	return r, r2
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("RUNNING: %v on %v", job, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		slave.Run(context.Background(), job)
		log.Printf("RUN COMMAND SENT %v", job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	log.Printf("DISCOVERED: %v", r)
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	for s.serving {
		time.Sleep(intentWait)

		log.Printf("Getting state")
		state := getConfig(&mainChecker{})
		log.Printf("Computing Diff")
		diff := configDiff(s.config, state)
		log.Printf("Determining jobs to run")
		joblist := runJobs(diff)
		log.Printf("MATCH FOUND %v from %v and %v", joblist, state, s.config)
		for _, job := range joblist {
			runJob(job, chooseServer(job, &mainChecker{}))
		}
		log.Printf("Completed Intent Run")
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.Serve()
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Serviced 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 btrfs

import (
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"reflect"
	"syscall"
	"testing"
)

var btrfsVolumes map[string]string = make(map[string]string)

// createBtrfsTmpVolume creates a btrfs volume of <size> bytes in a ramdisk,
// based on a loop device. Returns the path to the mounted filesystem.
func createBtrfsTmpVolume(t *testing.T, size int64) string {
	// Make a ramdisk
	ramdiskDir, err := ioutil.TempDir("", "btrfs-ramdisk-")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.MkdirAll(ramdiskDir, 0700); err != nil {
		t.Fatal(err)
	}
	if err := syscall.Mount("tmpfs", ramdiskDir, "tmpfs", syscall.MS_MGC_VAL, ""); err != nil {
		t.Fatal(err)
	}
	loopFile := filepath.Join(ramdiskDir, "loop")
	mountPath := filepath.Join(ramdiskDir, "mnt")
	if err := os.MkdirAll(mountPath, 0700); err != nil {
		t.Fatal(err)
	}
	// Create a sparse file of <size> bytes to back the loop device
	file, err := os.OpenFile(loopFile, os.O_RDWR|os.O_CREATE, 0600)
	if err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	defer file.Close()
	if err = file.Truncate(size); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	// Create a btrfs filesystem
	if err := exec.Command("mkfs.btrfs", loopFile).Run(); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	// Mount the loop device. System calls to get the next available loopback
	// device are nontrivial, so just shell out, like an animal
	cmd := exec.Command("mount", "-o", "loop", loopFile, mountPath)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	btrfsVolumes[mountPath] = ramdiskDir
	return mountPath
}

func cleanupBtrfsTmpVolume(t *testing.T, fsPath string) {
	var (
		ramdisk string
		ok      bool
	)
	if ramdisk, ok = btrfsVolumes[fsPath]; !ok {
		t.Fatal("Tried to clean up a btrfs volume we don't know about")
	}
	// First unmount the loop device
	if err := syscall.Unmount(fsPath, syscall.MNT_DETACH); err != nil {
		t.Error(err)
	}
	if err := syscall.Unmount(ramdisk, syscall.MNT_DETACH); err != nil {
		t.Fatal(err)
	}
}

func TestBtrfsVolume(t *testing.T) {

	if user, err := user.Current(); err != nil {
		panic(err)
	} else {
		if user.Uid != "0" {
			t.Skip("Skipping BTRFS tests because we are not running as root")
		}
	}

	if _, err := exec.LookPath("btrfs"); err != nil {
		t.Skip("Skipping BTRFS tests because btrfs-tools were not found in the path")
	}

	// Create a 64MB btrfs test volume
	btrfsTestVolumePath := createBtrfsTmpVolume(t, 256*1024*1024)
	defer cleanupBtrfsTmpVolume(t, btrfsTestVolumePath)

	t.Logf("Using '%s' as btrfs test volume", btrfsTestVolumePath)

	if err := os.MkdirAll(btrfsTestVolumePath, 0775); err != nil {
		t.Fatalf("Could not create test volume path: %s : %s", btrfsTestVolumePath, err)
	}

	btrfsd, err := New()
	if err != nil {
		t.Fatalf("Unable to create btrfs driver: %v", err)
	}

	if c, err := btrfsd.Mount("unittest", btrfsTestVolumePath); err != nil {
		t.Fatalf("Could not create volume object :%s", err)
	} else {
		testFile := filepath.Join(btrfsTestVolumePath, "unittest", "test.txt")
		testData := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
		testData2 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

		if err := ioutil.WriteFile(testFile, testData, 0664); err != nil {
			t.Fatalf("Could not write out test file: %s", err)
		}

		label := "unittest_foo"
		if err := c.Snapshot(label); err != nil {
			t.Fatalf("Could not snapshot: %s", err)
		}

		if err := ioutil.WriteFile(testFile, testData2, 0664); err != nil {
			t.Errorf("Could not write out test file 2: %s", err)
		}

		snapshots, _ := c.Snapshots()
		t.Logf("Found %v", snapshots)

		t.Logf("About to rollback %s", label)
		if err := c.Rollback(label); err != nil {
			t.Fatalf("Could not roll back: %s", err)
		}

		if output, err := ioutil.ReadFile(testFile); err != nil {
			t.Fatalf("Could not read back test file: %s", err)
		} else {
			if !reflect.DeepEqual(output, testData) {
				t.Logf("testdata: %v", testData)
				t.Logf("readdata: %v", output)
				t.FailNow()
			}
		}

		log.Printf("About to remove snapshot %s", label)
		if err := c.RemoveSnapshot(label); err != nil {
			t.Fatalf("Could not remove %s: %s", label, err)
		}

	}
}
<commit_msg>Remove some debug code<commit_after>// Copyright 2014 The Serviced 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 btrfs

import (
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"reflect"
	"syscall"
	"testing"
)

var btrfsVolumes map[string]string = make(map[string]string)

// createBtrfsTmpVolume creates a btrfs volume of <size> bytes in a ramdisk,
// based on a loop device. Returns the path to the mounted filesystem.
func createBtrfsTmpVolume(t *testing.T, size int64) string {
	// Make a ramdisk
	ramdiskDir, err := ioutil.TempDir("", "btrfs-ramdisk-")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.MkdirAll(ramdiskDir, 0700); err != nil {
		t.Fatal(err)
	}
	if err := syscall.Mount("tmpfs", ramdiskDir, "tmpfs", syscall.MS_MGC_VAL, ""); err != nil {
		t.Fatal(err)
	}
	loopFile := filepath.Join(ramdiskDir, "loop")
	mountPath := filepath.Join(ramdiskDir, "mnt")
	if err := os.MkdirAll(mountPath, 0700); err != nil {
		t.Fatal(err)
	}
	// Create a sparse file of <size> bytes to back the loop device
	file, err := os.OpenFile(loopFile, os.O_RDWR|os.O_CREATE, 0600)
	if err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	defer file.Close()
	if err = file.Truncate(size); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	// Create a btrfs filesystem
	if err := exec.Command("mkfs.btrfs", loopFile).Run(); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	// Mount the loop device. System calls to get the next available loopback
	// device are nontrivial, so just shell out, like an animal
	if err := exec.Command("mount", "-o", "loop", loopFile, mountPath).Run(); err != nil {
		defer syscall.Unmount(ramdiskDir, syscall.MNT_DETACH)
		t.Fatal(err)
	}
	btrfsVolumes[mountPath] = ramdiskDir
	return mountPath
}

func cleanupBtrfsTmpVolume(t *testing.T, fsPath string) {
	var (
		ramdisk string
		ok      bool
	)
	if ramdisk, ok = btrfsVolumes[fsPath]; !ok {
		t.Fatal("Tried to clean up a btrfs volume we don't know about")
	}
	// First unmount the loop device
	if err := syscall.Unmount(fsPath, syscall.MNT_DETACH); err != nil {
		t.Error(err)
	}
	if err := syscall.Unmount(ramdisk, syscall.MNT_DETACH); err != nil {
		t.Fatal(err)
	}
}

func TestBtrfsVolume(t *testing.T) {

	if user, err := user.Current(); err != nil {
		panic(err)
	} else {
		if user.Uid != "0" {
			t.Skip("Skipping BTRFS tests because we are not running as root")
		}
	}

	if _, err := exec.LookPath("btrfs"); err != nil {
		t.Skip("Skipping BTRFS tests because btrfs-tools were not found in the path")
	}

	// Create a 64MB btrfs test volume
	btrfsTestVolumePath := createBtrfsTmpVolume(t, 256*1024*1024)
	defer cleanupBtrfsTmpVolume(t, btrfsTestVolumePath)

	t.Logf("Using '%s' as btrfs test volume", btrfsTestVolumePath)

	if err := os.MkdirAll(btrfsTestVolumePath, 0775); err != nil {
		t.Fatalf("Could not create test volume path: %s : %s", btrfsTestVolumePath, err)
	}

	btrfsd, err := New()
	if err != nil {
		t.Fatalf("Unable to create btrfs driver: %v", err)
	}

	if c, err := btrfsd.Mount("unittest", btrfsTestVolumePath); err != nil {
		t.Fatalf("Could not create volume object :%s", err)
	} else {
		testFile := filepath.Join(btrfsTestVolumePath, "unittest", "test.txt")
		testData := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
		testData2 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

		if err := ioutil.WriteFile(testFile, testData, 0664); err != nil {
			t.Fatalf("Could not write out test file: %s", err)
		}

		label := "unittest_foo"
		if err := c.Snapshot(label); err != nil {
			t.Fatalf("Could not snapshot: %s", err)
		}

		if err := ioutil.WriteFile(testFile, testData2, 0664); err != nil {
			t.Errorf("Could not write out test file 2: %s", err)
		}

		snapshots, _ := c.Snapshots()
		t.Logf("Found %v", snapshots)

		t.Logf("About to rollback %s", label)
		if err := c.Rollback(label); err != nil {
			t.Fatalf("Could not roll back: %s", err)
		}

		if output, err := ioutil.ReadFile(testFile); err != nil {
			t.Fatalf("Could not read back test file: %s", err)
		} else {
			if !reflect.DeepEqual(output, testData) {
				t.Logf("testdata: %v", testData)
				t.Logf("readdata: %v", output)
				t.FailNow()
			}
		}

		log.Printf("About to remove snapshot %s", label)
		if err := c.RemoveSnapshot(label); err != nil {
			t.Fatalf("Could not remove %s: %s", label, err)
		}

	}
}
<|endoftext|>


<commit_before>package middlewares

import (
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/cozy/echo"
	"github.com/stretchr/testify/assert"
)

var ins *instance.Instance

type stupidRenderer struct{}

func (sr *stupidRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
	return nil
}
func TestUserAgent(t *testing.T) {
	// middleware instance
	e := echo.New()

	e.Renderer = &stupidRenderer{}

	req, _ := http.NewRequest(echo.GET, "http://cozy.local", nil)
	req.Header.Set(echo.HeaderAccept, "text/html")
	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0") // Firefox

	ins = &instance.Instance{Domain: "cozy.local", Locale: "en"}

	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	c.Set("instance", ins)

	h := CheckIE(echo.NotFoundHandler)
	err := h(c)
	assert.NotEqual(t, err, nil)

	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko") // IE 11
	h2 := CheckIE(echo.NotFoundHandler)
	err2 := h2(c)
	assert.Equal(t, err2, nil)
}
<commit_msg>Improve error checking<commit_after>package middlewares

import (
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/cozy/echo"
	"github.com/stretchr/testify/assert"
)

var ins *instance.Instance

type stupidRenderer struct{}

func (sr *stupidRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
	return nil
}
func TestUserAgent(t *testing.T) {
	// middleware instance
	e := echo.New()

	e.Renderer = &stupidRenderer{}

	req, _ := http.NewRequest(echo.GET, "http://cozy.local", nil)
	req.Header.Set(echo.HeaderAccept, "text/html")
	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0") // Firefox

	ins = &instance.Instance{Domain: "cozy.local", Locale: "en"}

	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	c.Set("instance", ins)

	h := CheckIE(echo.NotFoundHandler)
	err := h(c)
	assert.Error(t, err)

	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko") // IE 11
	h2 := CheckIE(echo.NotFoundHandler)
	err2 := h2(c)
	assert.NoError(t, err2, nil)
}
<|endoftext|>


<commit_before>package cce

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/drinktee/bce-sdk-go/bcc"
	"github.com/drinktee/bce-sdk-go/bce"
)

const (
	InstanceStatusRunning      string = "RUNNING"
	InstanceStatusCreating     string = "CREATING"
	InstanceStatusDeleting     string = "DELETING"
	InstanceStatusDeleted      string = "DELETED"
	InstanceStatusCreateFailed string = "CREATE_FAILED"
	InstanceStatusError        string = "ERROR"
)

// CceInstance define instance of cce
type CceInstance struct {
	InstanceId            string `json:"id"`
	InstanceName          string `json:"name"`
	Description           string `json:"desc"`
	Status                string `json:"status"`
	PaymentTiming         string `json:"paymentTiming"`
	CreationTime          string `json:"createTime"`
	ExpireTime            string `json:"expireTime"`
	PublicIP              string `json:"publicIp"`
	InternalIP            string `json:"internalIp"`
	CpuCount              int    `json:"cpu"`
	GpuCount              int    `json:"gpu"`
	MemoryCapacityInGB    int    `json:"memory"`
	localDiskSizeInGB     int    `json:"localDiskSizeInGB"`
	ImageId               string `json:"imageId"`
	NetworkCapacityInMbps int    `json:"networkCapacityInMbps"`
	PlacementPolicy       string `json:"placementPolicy"`
	ZoneName              string `json:"zoneName"`
	SubnetId              string `json:"subnetId"`
	VpcId                 string `json:"vpcId"`
}

// ListInstancesResponse define response of cce list
type ListInstancesResponse struct {
	Instances []CceInstance `json:"instances"`
}

// ListInstances gets all Instances of a cluster.
func (c *Client) ListInstances(clusterID string) ([]CceInstance, error) {
	if clusterID == "" {
		return nil, fmt.Errorf("clusterID should not be nil")
	}
	params := map[string]string{
		"clusterid": clusterID,
	}
	req, err := bce.NewRequest("GET", c.GetURL("/v1/instance", params), nil)

	if err != nil {
		return nil, err
	}

	resp, err := c.SendRequest(req, nil)

	if err != nil {
		return nil, err
	}

	bodyContent, err := resp.GetBodyContent()

	if err != nil {
		return nil, err
	}

	var insList ListInstancesResponse
	err = json.Unmarshal(bodyContent, &insList)

	if err != nil {
		return nil, err
	}

	return insList.Instances, nil
}

// ScaleUpClusterArgs define  args
type ScaleUpClusterArgs struct {
	ClusterID       string              `json:"clusterUuid"`
	CdsPreMountInfo bcc.CdsPreMountInfo `json:"cdsPreMountInfo"`
	OrderContent    OrderContent        `json:"orderContent"`
}

// ScaleUpClusterResponse define  args
type ScaleUpClusterResponse struct {
	ClusterID string   `json:"clusterUuid"`
	OrderID   []string `json:"orderId"`
}

// OrderContent define  bcc order content
type OrderContent struct {
	PaymentMethod []string    `json:"paymentMethod"`
	Items         []OrderItem `json:"items"`
}

// OrderItem define  bcc order content item
type OrderItem struct {
	Config        interface{} `json:"config"`
	PaymentMethod []string    `json:"paymentMethod"`
}

// BccOrderConfig define BCC order config
type BccOrderConfig struct {
	// 付费类型，一期只支持postpay
	ProductType string `json:"productType"`
	Region      string `json:"region"`
	LogicalZone string `json:"logicalZone"`
	// 普通BCC
	InstanceType string `json:"instanceType"`
	// 这些参数默认就行 容器产品用不到
	FpgaCard string `json:"fpgaCard"`
	GpuCard  int    `json:"gpuCard"`
	GpuCount int    `json:"gpuCount"`

	CPU    int `json:"cpu"`
	Memory int `json:"memory"`
	// 就一个镜像 ubuntu1604
	ImageType string `json:"imageType"`
	// 系统类型
	OsType string `json:"osType"`
	// 系统版本
	OsVersion string `json:"osVersion"`
	// 系统盘大小
	DiskSize int `json:"diskSize"`
	// 暂时为空
	EbsSize []int `json:"ebsSize"`
	// 是否需要购买EIP
	IfBuyEip int `json:"ifBuyEip,omitempty"`
	// eip名称
	EipName        string `json:"eipName"`
	SubProductType string `json:"subProductType"`
	// eip带宽
	BandwidthInMbps int `json:"bandwidthInMbps"`

	SubnetUuiD      string `json:"subnetUuid"`      // 子网uuid
	SecurityGroupID string `json:"securityGroupId"` // 安全组id

	AdminPass        string `json:"adminPass"`
	AdminPassConfirm string `json:"adminPassConfirm"`
	PurchaseLength   int    `json:"purchaseLength"`
	// 购买的虚机个数
	PurchaseNum int `json:"purchaseNum"`

	AutoRenewTimeUnit   string                `json:"autoRenewTimeUnit"`
	AutoRenewTime       int64                 `json:"autoRenewTime"`
	CreateEphemeralList []CreateEphemeralList `json:"createEphemeralList"`
	// 是否自动续费 默认即可 后付费不存在这个问题
	AutoRenew bool `json:"autoRenew"`
	// 镜像id 用默认即可 固定是ubuntu1604
	ImageID           string `json:"imageId"`
	OsName            string `json:"osName"`
	SecurityGroupName string `json:"securityGroupName"`
	// BCC
	ServiceType string `json:"serviceType"`
}

// CreateEphemeralList define storage
type CreateEphemeralList struct {
	// 磁盘存储类型 从页面创建虚机时 看到请求 默认是ssd
	StorageType string `json:"storageType"`
	// 磁盘大小
	SizeInGB int `json:"sizeInGB"`
}

// CdsOrderConfig define CDS order config
type CdsOrderConfig struct {
	// 付费类型，一期只支持postpay
	productType string `json:"productType"`
	// "zoneA"
	logicalZone    string `json:"logicalZone"`
	region         string `json:"sizeInGB"` // "bj"
	purchaseNum    int    `json:"sizeInGB"` // 1
	purchaseLength int    `json:"sizeInGB"` // 1
	autoRenewTime  int    `json:"sizeInGB"` // 0
	// "month"
	autoRenewTimeUnit string               `json:"sizeInGB"`
	cdsDiskSize       []bcc.DiskSizeConfig `json:"sizeInGB"`
	// "CDS"
	serviceType string `json:"sizeInGB"`
}

// EipOrderConfig define CDS order config
type EipOrderConfig struct {
	// 付费类型，一期只支持postpay
	ProductType     string `json:"productType"`
	BandwidthInMbps int    `json:"bandwidthInMbps"` // 1000
	Region          string `json:"region"`          // "bj"
	SubProductType  string `json:"subProductType"`  // "netraffic",
	// EIP购买数量应该是购买BCC数量的总和
	PurchaseNum       int    `json:"purchaseNum"`
	PurchaseLength    int    `json:"purchaseLength"`    // 1
	AutoRenewTime     int    `json:"autoRenewTime"`     // 0
	AutoRenewTimeUnit string `json:"autoRenewTimeUnit"` // "month",
	Name              string `json:"name"`              // "kkk"
	ServiceType       string `json:"serviceType"`       // "EIP"
}

// ScaleDownClusterArgs define  args
type ScaleDownClusterArgs struct {
	ClusterID string     `json:"clusterUuid"`
	AuthCode  string     `json:"authCode"`
	NodeInfos []NodeInfo `json:"nodeInfo"`
}

// NodeInfo define instanceid
type NodeInfo struct {
	InstanceID string `json:"instanceId"`
}

// ScaleDownClusterResponse define  args
type ScaleDownClusterResponse struct {
	ClusterID string   `json:"clusterUuid"`
	OrderID   []string `json:"orderId"`
}

// ScaleUpCluster scaleup a  cluster
func (c *Client) ScaleUpCluster(args *ScaleUpClusterArgs) (*ScaleUpClusterResponse, error) {
	var params map[string]string
	if args != nil {
		params = map[string]string{
			"clientToken": c.GenerateClientToken(),
			"scalingUp":   "",
		}
	}
	postContent, err := json.Marshal(args)
	if err != nil {
		return nil, err
	}
	req, err := bce.NewRequest("POST", c.GetURL("v1/cluster", params), bytes.NewBuffer(postContent))
	if err != nil {
		return nil, err
	}
	resp, err := c.SendRequest(req, nil)
	if err != nil {
		return nil, err
	}
	bodyContent, err := resp.GetBodyContent()
	if err != nil {
		return nil, err
	}
	var scResp *ScaleUpClusterResponse
	err = json.Unmarshal(bodyContent, &scResp)

	if err != nil {
		return nil, err
	}
	return scResp, nil
}

// ScaleDownCluster scale down a  cluster
func (c *Client) ScaleDownCluster(args *ScaleDownClusterArgs) error {
	var params map[string]string
	if args != nil {
		params = map[string]string{
			"clientToken": c.GenerateClientToken(),
			"scalingDown": "",
		}
	}
	postContent, err := json.Marshal(args)
	if err != nil {
		return err
	}
	req, err := bce.NewRequest("POST", c.GetURL("v1/cluster", params), bytes.NewBuffer(postContent))
	if err != nil {
		return err
	}
	_, err = c.SendRequest(req, nil)
	return err
}
<commit_msg>字段默认都为omitempty<commit_after>package cce

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/drinktee/bce-sdk-go/bcc"
	"github.com/drinktee/bce-sdk-go/bce"
)

const (
	InstanceStatusRunning      string = "RUNNING"
	InstanceStatusCreating     string = "CREATING"
	InstanceStatusDeleting     string = "DELETING"
	InstanceStatusDeleted      string = "DELETED"
	InstanceStatusCreateFailed string = "CREATE_FAILED"
	InstanceStatusError        string = "ERROR"
)

// CceInstance define instance of cce
type CceInstance struct {
	InstanceId            string `json:"id"`
	InstanceName          string `json:"name"`
	Description           string `json:"desc"`
	Status                string `json:"status"`
	PaymentTiming         string `json:"paymentTiming"`
	CreationTime          string `json:"createTime"`
	ExpireTime            string `json:"expireTime"`
	PublicIP              string `json:"publicIp"`
	InternalIP            string `json:"internalIp"`
	CpuCount              int    `json:"cpu"`
	GpuCount              int    `json:"gpu"`
	MemoryCapacityInGB    int    `json:"memory"`
	localDiskSizeInGB     int    `json:"localDiskSizeInGB"`
	ImageId               string `json:"imageId"`
	NetworkCapacityInMbps int    `json:"networkCapacityInMbps"`
	PlacementPolicy       string `json:"placementPolicy"`
	ZoneName              string `json:"zoneName"`
	SubnetId              string `json:"subnetId"`
	VpcId                 string `json:"vpcId"`
}

// ListInstancesResponse define response of cce list
type ListInstancesResponse struct {
	Instances []CceInstance `json:"instances"`
}

// ListInstances gets all Instances of a cluster.
func (c *Client) ListInstances(clusterID string) ([]CceInstance, error) {
	if clusterID == "" {
		return nil, fmt.Errorf("clusterID should not be nil")
	}
	params := map[string]string{
		"clusterid": clusterID,
	}
	req, err := bce.NewRequest("GET", c.GetURL("/v1/instance", params), nil)

	if err != nil {
		return nil, err
	}

	resp, err := c.SendRequest(req, nil)

	if err != nil {
		return nil, err
	}

	bodyContent, err := resp.GetBodyContent()

	if err != nil {
		return nil, err
	}

	var insList ListInstancesResponse
	err = json.Unmarshal(bodyContent, &insList)

	if err != nil {
		return nil, err
	}

	return insList.Instances, nil
}

// ScaleUpClusterArgs define  args
type ScaleUpClusterArgs struct {
	ClusterID       string              `json:"clusterUuid,omitempty"`
	CdsPreMountInfo bcc.CdsPreMountInfo `json:"cdsPreMountInfo,omitempty"`
	OrderContent    OrderContent        `json:"orderContent,omitempty"`
}

// ScaleUpClusterResponse define  args
type ScaleUpClusterResponse struct {
	ClusterID string   `json:"clusterUuid"`
	OrderID   []string `json:"orderId"`
}

// OrderContent define  bcc order content
type OrderContent struct {
	PaymentMethod []string    `json:"paymentMethod,omitempty"`
	Items         []OrderItem `json:"items,omitempty"`
}

// OrderItem define  bcc order content item
type OrderItem struct {
	Config        interface{} `json:"config,omitempty"`
	PaymentMethod []string    `json:"paymentMethod,omitempty"`
}

// BccOrderConfig define BCC order config
type BccOrderConfig struct {
	// 付费类型，一期只支持postpay
	ProductType string `json:"productType,omitempty"`
	Region      string `json:"region,omitempty"`
	LogicalZone string `json:"logicalZone,omitempty"`
	// 普通BCC
	InstanceType string `json:"instanceType,omitempty"`
	// 这些参数默认就行 容器产品用不到
	FpgaCard string `json:"fpgaCard,omitempty"`
	GpuCard  int    `json:"gpuCard,omitempty"`
	GpuCount int    `json:"gpuCount,omitempty"`

	CPU    int `json:"cpu,omitempty"`
	Memory int `json:"memory,omitempty"`
	// 就一个镜像 ubuntu1604
	ImageType string `json:"imageType,omitempty"`
	// 系统类型
	OsType string `json:"osType,omitempty"`
	// 系统版本
	OsVersion string `json:"osVersion,omitempty"`
	// 系统盘大小
	DiskSize int `json:"diskSize,omitempty"`
	// 暂时为空
	EbsSize []int `json:"ebsSize,omitempty"`
	// 是否需要购买EIP
	IfBuyEip int `json:"ifBuyEip,omitempty"`
	// eip名称
	EipName        string `json:"eipName,omitempty"`
	SubProductType string `json:"subProductType,omitempty"`
	// eip带宽
	BandwidthInMbps int `json:"bandwidthInMbps,omitempty"`

	SubnetUuiD      string `json:"subnetUuid,omitempty"`      // 子网uuid
	SecurityGroupID string `json:"securityGroupId,omitempty"` // 安全组id

	AdminPass        string `json:"adminPass,omitempty"`
	AdminPassConfirm string `json:"adminPassConfirm,omitempty"`
	PurchaseLength   int    `json:"purchaseLength,omitempty"`
	// 购买的虚机个数
	PurchaseNum int `json:"purchaseNum,omitempty"`

	AutoRenewTimeUnit   string                `json:"autoRenewTimeUnit,omitempty"`
	AutoRenewTime       int64                 `json:"autoRenewTime,omitempty"`
	CreateEphemeralList []CreateEphemeralList `json:"createEphemeralList,omitempty"`
	// 是否自动续费 默认即可 后付费不存在这个问题
	AutoRenew bool `json:"autoRenew,omitempty"`
	// 镜像id 用默认即可 固定是ubuntu1604
	ImageID           string `json:"imageId,omitempty"`
	OsName            string `json:"osName,omitempty"`
	SecurityGroupName string `json:"securityGroupName,omitempty"`
	// BCC
	ServiceType string `json:"serviceType,omitempty"`
}

// CreateEphemeralList define storage
type CreateEphemeralList struct {
	// 磁盘存储类型 从页面创建虚机时 看到请求 默认是ssd
	StorageType string `json:"storageType,omitempty"`
	// 磁盘大小
	SizeInGB int `json:"sizeInGB,omitempty"`
}

// CdsOrderConfig define CDS order config
type CdsOrderConfig struct {
	// 付费类型，一期只支持postpay
	productType string `json:"productType,omitempty"`
	// "zoneA"
	logicalZone    string `json:"logicalZone,omitempty"`
	region         string `json:"region,omitempty"`         // "bj"
	purchaseNum    int    `json:"purchaseNum,omitempty"`    // 1
	purchaseLength int    `json:"purchaseLength,omitempty"` // 1
	autoRenewTime  int    `json:"autoRenewTime,omitempty"`  // 0
	// "month"
	autoRenewTimeUnit string               `json:"autoRenewTimeUnit,omitempty"`
	cdsDiskSize       []bcc.DiskSizeConfig `json:"cdsDiskSize,omitempty"`
	// "CDS"
	serviceType string `json:"serviceType,omitempty"`
}

// EipOrderConfig define CDS order config
type EipOrderConfig struct {
	// 付费类型，一期只支持postpay
	ProductType     string `json:"productType,omitempty"`
	BandwidthInMbps int    `json:"bandwidthInMbps,omitempty"` // 1000
	Region          string `json:"region,omitempty"`          // "bj"
	SubProductType  string `json:"subProductType,omitempty"`  // "netraffic",
	// EIP购买数量应该是购买BCC数量的总和
	PurchaseNum       int    `json:"purchaseNum,omitempty"`
	PurchaseLength    int    `json:"purchaseLength,omitempty"`    // 1
	AutoRenewTime     int    `json:"autoRenewTime,omitempty"`     // 0
	AutoRenewTimeUnit string `json:"autoRenewTimeUnit,omitempty"` // "month",
	Name              string `json:"name,omitempty"`              // "kkk"
	ServiceType       string `json:"serviceType,omitempty"`       // "EIP"
}

// ScaleDownClusterArgs define  args
type ScaleDownClusterArgs struct {
	ClusterID string     `json:"clusterUuid"`
	AuthCode  string     `json:"authCode"`
	NodeInfos []NodeInfo `json:"nodeInfo"`
}

// NodeInfo define instanceid
type NodeInfo struct {
	InstanceID string `json:"instanceId"`
}

// ScaleDownClusterResponse define  args
type ScaleDownClusterResponse struct {
	ClusterID string   `json:"clusterUuid"`
	OrderID   []string `json:"orderId"`
}

// ScaleUpCluster scaleup a  cluster
func (c *Client) ScaleUpCluster(args *ScaleUpClusterArgs) (*ScaleUpClusterResponse, error) {
	var params map[string]string
	if args != nil {
		params = map[string]string{
			"clientToken": c.GenerateClientToken(),
			"scalingUp":   "",
		}
	}
	postContent, err := json.Marshal(args)
	if err != nil {
		return nil, err
	}
	req, err := bce.NewRequest("POST", c.GetURL("v1/cluster", params), bytes.NewBuffer(postContent))
	if err != nil {
		return nil, err
	}
	resp, err := c.SendRequest(req, nil)
	if err != nil {
		return nil, err
	}
	bodyContent, err := resp.GetBodyContent()
	if err != nil {
		return nil, err
	}
	var scResp *ScaleUpClusterResponse
	err = json.Unmarshal(bodyContent, &scResp)

	if err != nil {
		return nil, err
	}
	return scResp, nil
}

// ScaleDownCluster scale down a  cluster
func (c *Client) ScaleDownCluster(args *ScaleDownClusterArgs) error {
	var params map[string]string
	if args != nil {
		params = map[string]string{
			"clientToken": c.GenerateClientToken(),
			"scalingDown": "",
		}
	}
	postContent, err := json.Marshal(args)
	if err != nil {
		return err
	}
	req, err := bce.NewRequest("POST", c.GetURL("v1/cluster", params), bytes.NewBuffer(postContent))
	if err != nil {
		return err
	}
	_, err = c.SendRequest(req, nil)
	return err
}
<|endoftext|>


<commit_before>package pki

import (
  "crypto/rand"
  "crypto/x509"
  "crypto/x509/pkix"
  "encoding/pem"
  "fmt"
  "math/big"
  "net"
  "time"
)

const (
  PemLabelCertificateRequest = "CERTIFICATE REQUEST"
  PemLabelCertificate        = "CERTIFICATE"
)

type (
  CertificateData struct {
    Subject  pkix.Name

    DNSNames       []string
    EmailAddresses []string
    IPAddresses    []net.IP
  }

  Certificate x509.Certificate
  CertificateRequest x509.CertificateRequest

  CertificateOptions struct {
    SerialNumber        *big.Int
    NotBefore           time.Time
    NotAfter            time.Time // Validity bounds.
    IsCA                bool
    // how many sub ca are allowed between this ca and the end/final certificate
    // if it is -1, then no limit will be set
    CALength            int
    KeyUsage            x509.KeyUsage
  }
)

func NewCertificateData() *CertificateData {
  return &CertificateData{Subject: pkix.Name{}}
}

// Create a certificate sign request from the input data and the private key of
// the request creator.
func (c *CertificateData) ToCertificateRequest(private_key PrivateKey) (*CertificateRequest, error) {
  csr := &x509.CertificateRequest{}

  csr.Subject        = c.Subject
  csr.DNSNames       = c.DNSNames
  csr.IPAddresses    = c.IPAddresses
  csr.EmailAddresses = c.EmailAddresses

  csr_asn1, err := x509.CreateCertificateRequest(rand.Reader, csr, private_key.PrivateKey())
  if err != nil { return nil, err }
  return LoadCertificateSignRequest(csr_asn1)
}

// Load a certificate sign request from its asn1 representation.
func LoadCertificateSignRequest(raw []byte) (*CertificateRequest, error) {
  csr, err := x509.ParseCertificateRequest(raw)
  if err != nil { return nil, err }
  return (*CertificateRequest)(csr), nil
}

// Return the certificate sign request as a pem block.
func (c *CertificateRequest) MarshalPem() (marshalledPemBlock, error) {
  block := &pem.Block{Type: PemLabelCertificateRequest, Bytes: c.Raw}
  return pem.EncodeToMemory(block), nil
}

// Convert the certificate sign request to a certificate using the private key
// of the signer and the certificate of the signer.
// If the certificate is null, the sign request will be used to sign itself.
// Please also see the certificate options struct for information on mandatory fields.
// For more information, please read http://golang.org/pkg/crypto/x509/#CreateCertificate
func (c *CertificateRequest) ToCertificate(private_key PrivateKey,
        cert_opts CertificateOptions, ca *Certificate) (*Certificate, error) {

  if err := cert_opts.Valid(); err != nil { return nil, err }

  template := &x509.Certificate{}
  template.Subject        = c.Subject
  template.DNSNames       = c.DNSNames
  template.IPAddresses    = c.IPAddresses
  template.EmailAddresses = c.EmailAddresses

  // if no ca is given, we have to set IsCA to self sign
  if ca == nil {
    template.IsCA = true
  }

  template.NotBefore    = cert_opts.NotBefore
  template.NotAfter     = cert_opts.NotAfter
  template.KeyUsage     = cert_opts.KeyUsage
  template.IsCA         = cert_opts.IsCA
  if cert_opts.IsCA {
    template.BasicConstraintsValid = true
  }
  if cert_opts.CALength >= 0 {
    template.MaxPathLen   = cert_opts.CALength
    template.MaxPathLenZero = true
    template.BasicConstraintsValid = true
  }
  template.SerialNumber = cert_opts.SerialNumber

  var cert_asn1 []byte
  var err  error
  // if we have no ca which can sign the cert, a self signed cert is wanted
  // (or isn't it? Maybe we should split creation of the template? But that would be ugly)
  if ca == nil {
    cert_asn1, err = x509.CreateCertificate(rand.Reader, template, template, c.PublicKey, private_key.PrivateKey())
  } else {
    cert_asn1, err = x509.CreateCertificate(rand.Reader, template, (*x509.Certificate)(ca), c.PublicKey, private_key.PrivateKey())
  }
  if err != nil { return nil, err }
  return LoadCertificate(cert_asn1)
}

// Load a certificate from its asn1 representation.
func LoadCertificate(raw []byte) (*Certificate, error) {
  cert, err := x509.ParseCertificate(raw)
  if err != nil { return nil, err }
  return (*Certificate)(cert), nil
}

// marshal the certificate to a pem block
func (c *Certificate) MarshalPem() (marshalledPemBlock, error) {
  block := &pem.Block{Type: PemLabelCertificate, Bytes: c.Raw}
  return pem.EncodeToMemory(block), nil
}

func (co *CertificateOptions) Valid() error {
  if co.SerialNumber == nil { return fmt.Errorf("No serial number set!") }
  return nil
}
<commit_msg>provide more documentation for certificate types<commit_after>package pki

import (
  "crypto/rand"
  "crypto/x509"
  "crypto/x509/pkix"
  "encoding/pem"
  "fmt"
  "math/big"
  "net"
  "time"
)

// labels used in the pem file format to mark certificate sign requests and certificates
const (
  PemLabelCertificateRequest = "CERTIFICATE REQUEST"
  PemLabelCertificate        = "CERTIFICATE"
)

type (
  // Use CertificateData to fill in the minimum data you need to create a certificate
  // sign request.
  CertificateData struct {
    Subject  pkix.Name

    DNSNames       []string
    EmailAddresses []string
    IPAddresses    []net.IP
  }

  // Certificate is an alias on the x509.Certificate to add some methods.
  Certificate x509.Certificate
  // CertificateRequest is an alias on the x509.CertificateRequest to add some methods.
  CertificateRequest x509.CertificateRequest

  // CertificateOptions is used to provide the necessary information to create
  // a certificate from a certificate sign request.
  CertificateOptions struct {
    SerialNumber        *big.Int
    NotBefore           time.Time
    NotAfter            time.Time // Validity bounds.
    IsCA                bool
    // how many sub ca are allowed between this ca and the end/final certificate
    // if it is -1, then no limit will be set
    CALength            int
    KeyUsage            x509.KeyUsage
  }
)

// Create a new set of certificate data.
func NewCertificateData() *CertificateData {
  return &CertificateData{Subject: pkix.Name{}}
}

// Create a certificate sign request from the input data and the private key of
// the request creator.
func (c *CertificateData) ToCertificateRequest(private_key PrivateKey) (*CertificateRequest, error) {
  csr := &x509.CertificateRequest{}

  csr.Subject        = c.Subject
  csr.DNSNames       = c.DNSNames
  csr.IPAddresses    = c.IPAddresses
  csr.EmailAddresses = c.EmailAddresses

  csr_asn1, err := x509.CreateCertificateRequest(rand.Reader, csr, private_key.PrivateKey())
  if err != nil { return nil, err }
  return LoadCertificateSignRequest(csr_asn1)
}

// Load a certificate sign request from its asn1 representation.
func LoadCertificateSignRequest(raw []byte) (*CertificateRequest, error) {
  csr, err := x509.ParseCertificateRequest(raw)
  if err != nil { return nil, err }
  return (*CertificateRequest)(csr), nil
}

// Return the certificate sign request as a pem block.
func (c *CertificateRequest) MarshalPem() (marshalledPemBlock, error) {
  block := &pem.Block{Type: PemLabelCertificateRequest, Bytes: c.Raw}
  return pem.EncodeToMemory(block), nil
}

// Convert the certificate sign request to a certificate using the private key
// of the signer and the certificate of the signer.
// If the certificate is null, the sign request will be used to sign itself.
// Please also see the certificate options struct for information on mandatory fields.
// For more information, please read http://golang.org/pkg/crypto/x509/#CreateCertificate
func (c *CertificateRequest) ToCertificate(private_key PrivateKey,
        cert_opts CertificateOptions, ca *Certificate) (*Certificate, error) {

  if err := cert_opts.Valid(); err != nil { return nil, err }

  template := &x509.Certificate{}
  template.Subject        = c.Subject
  template.DNSNames       = c.DNSNames
  template.IPAddresses    = c.IPAddresses
  template.EmailAddresses = c.EmailAddresses

  // if no ca is given, we have to set IsCA to self sign
  if ca == nil {
    template.IsCA = true
  }

  template.NotBefore    = cert_opts.NotBefore
  template.NotAfter     = cert_opts.NotAfter
  template.KeyUsage     = cert_opts.KeyUsage
  template.IsCA         = cert_opts.IsCA
  if cert_opts.IsCA {
    template.BasicConstraintsValid = true
  }
  if cert_opts.CALength >= 0 {
    template.MaxPathLen   = cert_opts.CALength
    template.MaxPathLenZero = true
    template.BasicConstraintsValid = true
  }
  template.SerialNumber = cert_opts.SerialNumber

  var cert_asn1 []byte
  var err  error
  // if we have no ca which can sign the cert, a self signed cert is wanted
  // (or isn't it? Maybe we should split creation of the template? But that would be ugly)
  if ca == nil {
    cert_asn1, err = x509.CreateCertificate(rand.Reader, template, template, c.PublicKey, private_key.PrivateKey())
  } else {
    cert_asn1, err = x509.CreateCertificate(rand.Reader, template, (*x509.Certificate)(ca), c.PublicKey, private_key.PrivateKey())
  }
  if err != nil { return nil, err }
  return LoadCertificate(cert_asn1)
}

// Load a certificate from its asn1 representation.
func LoadCertificate(raw []byte) (*Certificate, error) {
  cert, err := x509.ParseCertificate(raw)
  if err != nil { return nil, err }
  return (*Certificate)(cert), nil
}

// marshal the certificate to a pem block
func (c *Certificate) MarshalPem() (marshalledPemBlock, error) {
  block := &pem.Block{Type: PemLabelCertificate, Bytes: c.Raw}
  return pem.EncodeToMemory(block), nil
}

// Check if the certificate options have the required fields set.
func (co *CertificateOptions) Valid() error {
  if co.SerialNumber == nil { return fmt.Errorf("No serial number set!") }
  return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/lightningnetwork/lnd/keychain"
	litecoinCfg "github.com/ltcsuite/ltcd/chaincfg"
	"github.com/roasbeef/btcd/chaincfg"
	bitcoinCfg "github.com/roasbeef/btcd/chaincfg"
	"github.com/roasbeef/btcd/chaincfg/chainhash"
	"github.com/roasbeef/btcd/wire"
)

// activeNetParams is a pointer to the parameters specific to the currently
// active bitcoin network.
var activeNetParams = bitcoinTestNetParams

// bitcoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network.
type bitcoinNetParams struct {
	*bitcoinCfg.Params
	rpcPort  string
	CoinType uint32
}

// litecoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network.
type litecoinNetParams struct {
	*litecoinCfg.Params
	rpcPort  string
	CoinType uint32
}

// bitcoinTestNetParams contains parameters specific to the 3rd version of the
// test network.
var bitcoinTestNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.TestNet3Params,
	rpcPort:  "18334",
	CoinType: keychain.CoinTypeTestnet,
}

// bitcoinMainNetParams contains parameters specific to the current Bitcoin
// mainnet.
var bitcoinMainNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.MainNetParams,
	rpcPort:  "8334",
	CoinType: keychain.CoinTypeBitcoin,
}

// bitcoinSimNetParams contains parameters specific to the simulation test
// network.
var bitcoinSimNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.SimNetParams,
	rpcPort:  "18556",
	CoinType: keychain.CoinTypeTestnet,
}

// litecoinTestNetParams contains parameters specific to the 4th version of the
// test network.
var litecoinTestNetParams = litecoinNetParams{
	Params:   &litecoinCfg.TestNet4Params,
	rpcPort:  "19334",
	CoinType: keychain.CoinTypeTestnet,
}

// litecoinMainNetParams contains the parameters specific to the current
// Litecoin mainnet.
var litecoinMainNetParams = litecoinNetParams{
	Params:   &litecoinCfg.MainNetParams,
	rpcPort:  "9334",
	CoinType: keychain.CoinTypeLitecoin,
}

// regTestNetParams contains parameters specific to a local regtest network.
var regTestNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.RegressionNetParams,
	rpcPort:  "18334",
	CoinType: keychain.CoinTypeTestnet,
}

// applyLitecoinParams applies the relevant chain configuration parameters that
// differ for litecoin to the chain parameters typed for btcsuite derivation.
// This function is used in place of using something like interface{} to
// abstract over _which_ chain (or fork) the parameters are for.
func applyLitecoinParams(params *bitcoinNetParams, litecoinParams *litecoinNetParams) {
	params.Name = litecoinParams.Name
	params.Net = wire.BitcoinNet(litecoinParams.Net)
	params.DefaultPort = litecoinParams.DefaultPort
	params.CoinbaseMaturity = litecoinParams.CoinbaseMaturity

	copy(params.GenesisHash[:], litecoinParams.GenesisHash[:])

	// Address encoding magics
	params.PubKeyHashAddrID = litecoinParams.PubKeyHashAddrID
	params.ScriptHashAddrID = litecoinParams.ScriptHashAddrID
	params.PrivateKeyID = litecoinParams.PrivateKeyID
	params.WitnessPubKeyHashAddrID = litecoinParams.WitnessPubKeyHashAddrID
	params.WitnessScriptHashAddrID = litecoinParams.WitnessScriptHashAddrID
	params.Bech32HRPSegwit = litecoinParams.Bech32HRPSegwit

	copy(params.HDPrivateKeyID[:], litecoinParams.HDPrivateKeyID[:])
	copy(params.HDPublicKeyID[:], litecoinParams.HDPublicKeyID[:])

	params.HDCoinType = litecoinParams.HDCoinType

	checkPoints := make([]chaincfg.Checkpoint, len(litecoinParams.Checkpoints))
	for i := 0; i < len(litecoinParams.Checkpoints); i++ {
		var chainHash chainhash.Hash
		copy(chainHash[:], litecoinParams.Checkpoints[i].Hash[:])

		checkPoints[i] = chaincfg.Checkpoint{
			Height: litecoinParams.Checkpoints[i].Height,
			Hash:   &chainHash,
		}
	}
	params.Checkpoints = checkPoints

	params.rpcPort = litecoinParams.rpcPort
	params.CoinType = litecoinParams.CoinType
}
<commit_msg>chainparams: create isTestnet function<commit_after>package main

import (
	"github.com/lightningnetwork/lnd/keychain"
	litecoinCfg "github.com/ltcsuite/ltcd/chaincfg"
	litecoinWire "github.com/ltcsuite/ltcd/wire"
	"github.com/roasbeef/btcd/chaincfg"
	bitcoinCfg "github.com/roasbeef/btcd/chaincfg"
	"github.com/roasbeef/btcd/chaincfg/chainhash"
	bitcoinWire "github.com/roasbeef/btcd/wire"
)

// activeNetParams is a pointer to the parameters specific to the currently
// active bitcoin network.
var activeNetParams = bitcoinTestNetParams

// bitcoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network.
type bitcoinNetParams struct {
	*bitcoinCfg.Params
	rpcPort  string
	CoinType uint32
}

// litecoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network.
type litecoinNetParams struct {
	*litecoinCfg.Params
	rpcPort  string
	CoinType uint32
}

// bitcoinTestNetParams contains parameters specific to the 3rd version of the
// test network.
var bitcoinTestNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.TestNet3Params,
	rpcPort:  "18334",
	CoinType: keychain.CoinTypeTestnet,
}

// bitcoinMainNetParams contains parameters specific to the current Bitcoin
// mainnet.
var bitcoinMainNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.MainNetParams,
	rpcPort:  "8334",
	CoinType: keychain.CoinTypeBitcoin,
}

// bitcoinSimNetParams contains parameters specific to the simulation test
// network.
var bitcoinSimNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.SimNetParams,
	rpcPort:  "18556",
	CoinType: keychain.CoinTypeTestnet,
}

// litecoinTestNetParams contains parameters specific to the 4th version of the
// test network.
var litecoinTestNetParams = litecoinNetParams{
	Params:   &litecoinCfg.TestNet4Params,
	rpcPort:  "19334",
	CoinType: keychain.CoinTypeTestnet,
}

// litecoinMainNetParams contains the parameters specific to the current
// Litecoin mainnet.
var litecoinMainNetParams = litecoinNetParams{
	Params:   &litecoinCfg.MainNetParams,
	rpcPort:  "9334",
	CoinType: keychain.CoinTypeLitecoin,
}

// regTestNetParams contains parameters specific to a local regtest network.
var regTestNetParams = bitcoinNetParams{
	Params:   &bitcoinCfg.RegressionNetParams,
	rpcPort:  "18334",
	CoinType: keychain.CoinTypeTestnet,
}

// applyLitecoinParams applies the relevant chain configuration parameters that
// differ for litecoin to the chain parameters typed for btcsuite derivation.
// This function is used in place of using something like interface{} to
// abstract over _which_ chain (or fork) the parameters are for.
func applyLitecoinParams(params *bitcoinNetParams, litecoinParams *litecoinNetParams) {
	params.Name = litecoinParams.Name
	params.Net = bitcoinWire.BitcoinNet(litecoinParams.Net)
	params.DefaultPort = litecoinParams.DefaultPort
	params.CoinbaseMaturity = litecoinParams.CoinbaseMaturity

	copy(params.GenesisHash[:], litecoinParams.GenesisHash[:])

	// Address encoding magics
	params.PubKeyHashAddrID = litecoinParams.PubKeyHashAddrID
	params.ScriptHashAddrID = litecoinParams.ScriptHashAddrID
	params.PrivateKeyID = litecoinParams.PrivateKeyID
	params.WitnessPubKeyHashAddrID = litecoinParams.WitnessPubKeyHashAddrID
	params.WitnessScriptHashAddrID = litecoinParams.WitnessScriptHashAddrID
	params.Bech32HRPSegwit = litecoinParams.Bech32HRPSegwit

	copy(params.HDPrivateKeyID[:], litecoinParams.HDPrivateKeyID[:])
	copy(params.HDPublicKeyID[:], litecoinParams.HDPublicKeyID[:])

	params.HDCoinType = litecoinParams.HDCoinType

	checkPoints := make([]chaincfg.Checkpoint, len(litecoinParams.Checkpoints))
	for i := 0; i < len(litecoinParams.Checkpoints); i++ {
		var chainHash chainhash.Hash
		copy(chainHash[:], litecoinParams.Checkpoints[i].Hash[:])

		checkPoints[i] = chaincfg.Checkpoint{
			Height: litecoinParams.Checkpoints[i].Height,
			Hash:   &chainHash,
		}
	}
	params.Checkpoints = checkPoints

	params.rpcPort = litecoinParams.rpcPort
	params.CoinType = litecoinParams.CoinType
}

// isTestnet tests if the given params correspond to a testnet
// parameter configuration.
func isTestnet(params *bitcoinNetParams) bool {
	switch params.Params.Net {
	case bitcoinWire.TestNet3, bitcoinWire.BitcoinNet(litecoinWire.TestNet4):
		return true
	default:
		return false
	}
}
<|endoftext|>