<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package annotations_test

import (
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/annotations"
	basetesting "github.com/juju/juju/api/base/testing"
	"github.com/juju/juju/apiserver/params"
	jujutesting "github.com/juju/juju/juju/testing"
	coretesting "github.com/juju/juju/testing"
	"github.com/juju/juju/testing/factory"
)

type annotationsMockSuite struct {
	coretesting.BaseSuite
	annotationsClient *annotations.Client
}

var _ = gc.Suite(&annotationsMockSuite{})

func (s *annotationsMockSuite) TestSetEntitiesAnnotation(c *gc.C) {
	var called bool
	annts := map[string]string{"annotation1": "test"}
	annts2 := map[string]string{"annotation2": "test"}
	setParams := map[string]map[string]string{
		"charmA":   annts,
		"serviceB": annts2,
	}
	apiCaller := basetesting.APICallerFunc(
		func(objType string,
			version int,
			id, request string,
			a, result interface{}) error {

			called = true
			c.Check(objType, gc.Equals, "Annotations")
			c.Check(id, gc.Equals, "")
			c.Check(request, gc.Equals, "Set")

			args, ok := a.(params.AnnotationsSet)
			c.Assert(ok, jc.IsTrue)

			for _, aParam := range args.Annotations {
				// Since sometimes arrays returned on some
				// architectures vary the order within params.AnnotationsSet,
				// simply assert that each entity has its own annotations.
				// Bug 1409141
				c.Assert(aParam.Annotations, gc.DeepEquals, setParams[aParam.Entity.Tag])
			}
			return nil
		})
	annotationsClient := annotations.NewClient(apiCaller)
	err := annotationsClient.Set(setParams)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(called, jc.IsTrue)
}

func (s *annotationsMockSuite) TestGetEntitiesAnnotations(c *gc.C) {
	var called bool
	apiCaller := basetesting.APICallerFunc(
		func(
			objType string,
			version int,
			id, request string,
			a, response interface{}) error {
			called = true
			c.Check(objType, gc.Equals, "Annotations")
			c.Check(id, gc.Equals, "")
			c.Check(request, gc.Equals, "Get")
			args, ok := a.(params.Entities)
			c.Assert(ok, jc.IsTrue)
			c.Assert(args.Entities, gc.HasLen, 1)
			c.Assert(args.Entities[0], gc.DeepEquals, params.Entity{"charm"})

			result := response.(*params.AnnotationsGetResults)
			facadeAnnts := map[string]string{
				"annotations": "test",
			}
			entitiesAnnts := params.AnnotationsGetResult{
				Entity:      params.Entity{"charm"},
				Annotations: facadeAnnts,
			}
			result.Results = []params.AnnotationsGetResult{entitiesAnnts}
			return nil
		})
	annotationsClient := annotations.NewClient(apiCaller)
	found, err := annotationsClient.Get([]string{"charm"})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(called, jc.IsTrue)
	c.Assert(found, gc.HasLen, 1)
}

type annotationsSuite struct {
	jujutesting.JujuConnSuite
	annotationsClient *annotations.Client
}

var _ = gc.Suite(&annotationsSuite{})

func (s *annotationsSuite) SetUpTest(c *gc.C) {
	s.JujuConnSuite.SetUpTest(c)
	s.annotationsClient = annotations.NewClient(s.APIState)
	c.Assert(s.annotationsClient, gc.NotNil)
}

func (s *annotationsSuite) TearDownTest(c *gc.C) {
	s.annotationsClient.ClientFacade.Close()
	s.JujuConnSuite.TearDownTest(c)
}

func (s *annotationsSuite) TestAnnotationFacadeCall(c *gc.C) {
	charm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "wordpress"})

	annts := map[string]string{"annotation": "test"}
	err := s.annotationsClient.Set(
		map[string]map[string]string{
			charm.Tag().String(): annts,
		})
	c.Assert(err, jc.ErrorIsNil)

	found, err := s.annotationsClient.Get([]string{charm.Tag().String()})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(found, gc.HasLen, 1)
}
<commit_msg>Formatting<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package annotations_test

import (
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/annotations"
	basetesting "github.com/juju/juju/api/base/testing"
	"github.com/juju/juju/apiserver/params"
	jujutesting "github.com/juju/juju/juju/testing"
	coretesting "github.com/juju/juju/testing"
	"github.com/juju/juju/testing/factory"
)

type annotationsMockSuite struct {
	coretesting.BaseSuite
	annotationsClient *annotations.Client
}

var _ = gc.Suite(&annotationsMockSuite{})

func (s *annotationsMockSuite) TestSetEntitiesAnnotation(c *gc.C) {
	var called bool
	annts := map[string]string{"annotation1": "test"}
	annts2 := map[string]string{"annotation2": "test"}
	setParams := map[string]map[string]string{
		"charmA":   annts,
		"serviceB": annts2,
	}
	apiCaller := basetesting.APICallerFunc(
		func(objType string,
			version int,
			id, request string,
			a, result interface{},
		) error {
			called = true
			c.Check(objType, gc.Equals, "Annotations")
			c.Check(id, gc.Equals, "")
			c.Check(request, gc.Equals, "Set")

			args, ok := a.(params.AnnotationsSet)
			c.Assert(ok, jc.IsTrue)

			for _, aParam := range args.Annotations {
				// Since sometimes arrays returned on some
				// architectures vary the order within params.AnnotationsSet,
				// simply assert that each entity has its own annotations.
				// Bug 1409141
				c.Assert(aParam.Annotations, gc.DeepEquals, setParams[aParam.Entity.Tag])
			}
			return nil
		})
	annotationsClient := annotations.NewClient(apiCaller)
	err := annotationsClient.Set(setParams)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(called, jc.IsTrue)
}

func (s *annotationsMockSuite) TestGetEntitiesAnnotations(c *gc.C) {
	var called bool
	apiCaller := basetesting.APICallerFunc(
		func(
			objType string,
			version int,
			id, request string,
			a, response interface{}) error {
			called = true
			c.Check(objType, gc.Equals, "Annotations")
			c.Check(id, gc.Equals, "")
			c.Check(request, gc.Equals, "Get")
			args, ok := a.(params.Entities)
			c.Assert(ok, jc.IsTrue)
			c.Assert(args.Entities, gc.HasLen, 1)
			c.Assert(args.Entities[0], gc.DeepEquals, params.Entity{"charm"})

			result := response.(*params.AnnotationsGetResults)
			facadeAnnts := map[string]string{
				"annotations": "test",
			}
			entitiesAnnts := params.AnnotationsGetResult{
				Entity:      params.Entity{"charm"},
				Annotations: facadeAnnts,
			}
			result.Results = []params.AnnotationsGetResult{entitiesAnnts}
			return nil
		})
	annotationsClient := annotations.NewClient(apiCaller)
	found, err := annotationsClient.Get([]string{"charm"})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(called, jc.IsTrue)
	c.Assert(found, gc.HasLen, 1)
}

type annotationsSuite struct {
	jujutesting.JujuConnSuite
	annotationsClient *annotations.Client
}

var _ = gc.Suite(&annotationsSuite{})

func (s *annotationsSuite) SetUpTest(c *gc.C) {
	s.JujuConnSuite.SetUpTest(c)
	s.annotationsClient = annotations.NewClient(s.APIState)
	c.Assert(s.annotationsClient, gc.NotNil)
}

func (s *annotationsSuite) TearDownTest(c *gc.C) {
	s.annotationsClient.ClientFacade.Close()
	s.JujuConnSuite.TearDownTest(c)
}

func (s *annotationsSuite) TestAnnotationFacadeCall(c *gc.C) {
	charm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "wordpress"})

	annts := map[string]string{"annotation": "test"}
	err := s.annotationsClient.Set(
		map[string]map[string]string{
			charm.Tag().String(): annts,
		})
	c.Assert(err, jc.ErrorIsNil)

	found, err := s.annotationsClient.Get([]string{charm.Tag().String()})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(found, gc.HasLen, 1)
}
<|endoftext|>


<commit_before>// 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 parts

import (
	"bytes"
	html "html/template"
	"log"
	"net/http"
	"regexp"
	"sort"
	"strconv"
	"text/template"
)

const (
	filterTemplateSrc = `for x := range {{.Input}} {
    {{range .Paths}}{{if and .Pred .Output}}
    if {{.Pred}} {
        {{.Output}} <- x
    }{{end}}{{end}}
}
{{- range .Paths}}
close({{.Output}})
{{- end}}`

	filterEditorTemplateSrc = `

		Input
		<select name="FilterInput">
			{{range .Graph.Channels -}}
			<option value="{{.Name}}" {{if eq .Name $.Node.Part.Input}}selected{{end}}>{{.Name}}</option>
			{{- end}}
		</select>

	<fieldset id="pathtemplate">

			Output
			<select name="FilterOutput">
				{{range $.Graph.Channels -}}
				<option value="{{.Name}}">{{.Name}}</option>
				{{- end}}
			</select>

			Predicate
			<input type="text" name="FilterPredicate">

		Remove this output
	</fieldset>
	{{range $index, $path := .Node.Part.Paths}}
	<fieldset>

			Output
			<select name="FilterOutput{{$index}}">
				{{range $.Graph.Channels -}}
				<option value="{{.Name}}" {{if eq .Name $path.Output}}selected{{end}}>{{.Name}}</option>
				{{- end}}
			</select>

			Predicate
			<input type="text" name="FilterPredicate{{$index}}" required value="{{$path.Pred}}">

		Remove this output
	</fieldset>
	{{- end }}
	Add output`
)

var (
	filterTemplate = template.Must(template.New("filter").Parse(filterTemplateSrc))

	pathOutputNameRE = regexp.MustCompile(`^FilterOutput(\d+)$`)
	pathPredNameRE   = regexp.MustCompile(`^FilterPredicate(\d+)$`)
)

type pathway struct {
	Pred   string `json:"pred"`
	Output string `json:"output"`
}

// Filter tests values from the input and passes it on to one or more
// outputs based on predicates.
type Filter struct {
	Input string    `json:"input"`
	Paths []pathway `json:"paths"`
}

// AssociateEditor adds a "part_view" template to the given template.
func (f *Filter) AssociateEditor(tmpl *html.Template) error {
	_, err := tmpl.New("part_view").Parse(filterEditorTemplateSrc)
	return err
}

// Channels returns the names of all channels used by this goroutine.
func (f *Filter) Channels() (read, written []string) {
	o := make([]string, 0, len(f.Paths))
	for _, p := range f.Paths {
		o = append(o, p.Output)
	}
	return []string{f.Input}, o
}

// Impl returns the content of a goroutine implementation.
func (f *Filter) Impl() string {
	b := new(bytes.Buffer)
	filterTemplate.Execute(b, f)
	return b.String()
}

// Update sets fields based on the given Request.
func (f *Filter) Update(r *http.Request) error {
	if r == nil {
		// No secret cached information to refresh.
		return nil
	}
	if err := r.ParseForm(); err != nil {
		return err
	}
	p := make(map[int]pathway)
	var ks []int
	for k := range r.Form {
		if s := pathOutputNameRE.FindStringSubmatch(k); s != nil {
			o, err := strconv.Atoi(s[1])
			if err != nil {
				return err
			}
			ks = append(ks, o)
			p[o] = pathway{Pred: p[o].Pred, Output: r.FormValue(k)}
			continue
		}
		if s := pathPredNameRE.FindStringSubmatch(k); s != nil {
			o, err := strconv.Atoi(s[1])
			if err != nil {
				return err
			}
			p[o] = pathway{Pred: r.FormValue(k), Output: p[o].Output}
		}
	}
	// Ensure the inputs stay in relative order.
	sort.Ints(ks)

	log.Print(p)
	log.Print(ks)

	f.Input = r.FormValue("FilterInput")
	f.Paths = nil
	for _, k := range ks {
		v := p[k]
		if v.Output == "" || v.Pred == "" {
			continue
		}
		f.Paths = append(f.Paths, v)
	}
	return nil
}

// TypeKey returns "Filter".
func (*Filter) TypeKey() string { return "Filter" }
<commit_msg>Remove some log<commit_after>// 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 parts

import (
	"bytes"
	html "html/template"
	"net/http"
	"regexp"
	"sort"
	"strconv"
	"text/template"
)

const (
	filterTemplateSrc = `for x := range {{.Input}} {
    {{range .Paths}}{{if and .Pred .Output}}
    if {{.Pred}} {
        {{.Output}} <- x
    }{{end}}{{end}}
}
{{- range .Paths}}
close({{.Output}})
{{- end}}`

	filterEditorTemplateSrc = `

		Input
		<select name="FilterInput">
			{{range .Graph.Channels -}}
			<option value="{{.Name}}" {{if eq .Name $.Node.Part.Input}}selected{{end}}>{{.Name}}</option>
			{{- end}}
		</select>

	<fieldset id="pathtemplate">

			Output
			<select name="FilterOutput">
				{{range $.Graph.Channels -}}
				<option value="{{.Name}}">{{.Name}}</option>
				{{- end}}
			</select>

			Predicate
			<input type="text" name="FilterPredicate">

		Remove this output
	</fieldset>
	{{range $index, $path := .Node.Part.Paths}}
	<fieldset>

			Output
			<select name="FilterOutput{{$index}}">
				{{range $.Graph.Channels -}}
				<option value="{{.Name}}" {{if eq .Name $path.Output}}selected{{end}}>{{.Name}}</option>
				{{- end}}
			</select>

			Predicate
			<input type="text" name="FilterPredicate{{$index}}" required value="{{$path.Pred}}">

		Remove this output
	</fieldset>
	{{- end }}
	Add output`
)

var (
	filterTemplate = template.Must(template.New("filter").Parse(filterTemplateSrc))

	pathOutputNameRE = regexp.MustCompile(`^FilterOutput(\d+)$`)
	pathPredNameRE   = regexp.MustCompile(`^FilterPredicate(\d+)$`)
)

type pathway struct {
	Pred   string `json:"pred"`
	Output string `json:"output"`
}

// Filter tests values from the input and passes it on to one or more
// outputs based on predicates.
type Filter struct {
	Input string    `json:"input"`
	Paths []pathway `json:"paths"`
}

// AssociateEditor adds a "part_view" template to the given template.
func (f *Filter) AssociateEditor(tmpl *html.Template) error {
	_, err := tmpl.New("part_view").Parse(filterEditorTemplateSrc)
	return err
}

// Channels returns the names of all channels used by this goroutine.
func (f *Filter) Channels() (read, written []string) {
	o := make([]string, 0, len(f.Paths))
	for _, p := range f.Paths {
		o = append(o, p.Output)
	}
	return []string{f.Input}, o
}

// Impl returns the content of a goroutine implementation.
func (f *Filter) Impl() string {
	b := new(bytes.Buffer)
	filterTemplate.Execute(b, f)
	return b.String()
}

// Update sets fields based on the given Request.
func (f *Filter) Update(r *http.Request) error {
	if r == nil {
		// No secret cached information to refresh.
		return nil
	}
	if err := r.ParseForm(); err != nil {
		return err
	}
	p := make(map[int]pathway)
	var ks []int
	for k := range r.Form {
		if s := pathOutputNameRE.FindStringSubmatch(k); s != nil {
			o, err := strconv.Atoi(s[1])
			if err != nil {
				return err
			}
			ks = append(ks, o)
			p[o] = pathway{Pred: p[o].Pred, Output: r.FormValue(k)}
			continue
		}
		if s := pathPredNameRE.FindStringSubmatch(k); s != nil {
			o, err := strconv.Atoi(s[1])
			if err != nil {
				return err
			}
			p[o] = pathway{Pred: r.FormValue(k), Output: p[o].Output}
		}
	}
	// Ensure the inputs stay in relative order.
	sort.Ints(ks)

	f.Input = r.FormValue("FilterInput")
	f.Paths = nil
	for _, k := range ks {
		v := p[k]
		if v.Output == "" || v.Pred == "" {
			continue
		}
		f.Paths = append(f.Paths, v)
	}
	return nil
}

// TypeKey returns "Filter".
func (*Filter) TypeKey() string { return "Filter" }
<|endoftext|>


<commit_before>package node

import (
	"testing"
)

type testPaymentConnection struct {
	in  chan Payment
	out chan Payment
}

func (c testPaymentConnection) SendPayment(p Payment) error {
	c.out <- p
	return nil
}
func (c testPaymentConnection) Payments() <-chan Payment {
	return c.in
}

func makePairedPaymentConnections() (PaymentConnection, PaymentConnection) {
	one := make(chan Payment)
	two := make(chan Payment)
	return testPaymentConnection{one, two}, testPaymentConnection{two, one}
}

type testPayment struct {
	src NodeAddress
	dst NodeAddress
	amt int64
}

func (t testPayment) Source() NodeAddress      { return t.src }
func (t testPayment) Destination() NodeAddress { return t.dst }
func (t testPayment) Verify() error            { return nil }
func (t testPayment) Amount() int64            { return t.amt }

func TestPaymentHandler(t *testing.T) {
	h1, h2 := make(chan PacketHash), make(chan PacketHash)
	c1, c2 := makePairedPaymentConnections()
	a1 := NodeAddress("1")
	a2 := NodeAddress("2")
	p1 := newPaymentImpl(a1, h1)
	p2 := newPaymentImpl(a2, h2)
	p1.AddConnection(a2, c1)
	p2.AddConnection(a1, c2)

	t1 := testPacket(a2)
	p1.AddSentPacket(t1, a1, a2)
	if p1.IncomingDebt(a1) != 0 {
		t.Fatalf("Expected a1 incomingdebt %d got %d", 0, p1.IncomingDebt(a1))
	}
	if p1.OutgoingDebt(a2) != 0 {
		t.Fatalf("Expected a2 outgoingdebt %d got %d", 0, p1.OutgoingDebt(a2))
	}
	h1 <- t1.Hash()
	if p1.IncomingDebt(a1) != 1 {
		t.Fatalf("Expected a1 incomingdebt %d got %d", 1, p1.IncomingDebt(a1))
	}
	if p1.OutgoingDebt(a2) != 1 {
		t.Fatalf("Expected a2 outgoingdebt %d got %d", 1, p1.OutgoingDebt(a2))
	}

	p2.AddSentPacket(t1, a1, a2)
	h2 <- t1.Hash()
	if p2.IncomingDebt(a1) != 1 {
		t.Fatalf("Expected a1 incomingdebt %d got %d", 1, p2.IncomingDebt(a1))
	}

	payment := testPayment{a1, a2, 1}
	p1.SendPayment(payment)
	if p2.IncomingDebt(a1) != 0 {
		t.Fatalf("Expected a1 incomingdebt %d got %d", 0, p2.IncomingDebt(a1))
	}
	if p1.OutgoingDebt(a2) != 0 {
		t.Fatalf("Expected a2 outgoingdebt %d got %d", 0, p1.OutgoingDebt(a2))
	}
}
<commit_msg>Fix payment test<commit_after>package node

import (
	"testing"
	"time"
)

type testPaymentConnection struct {
	in  chan Payment
	out chan Payment
}

func (c testPaymentConnection) SendPayment(p Payment) error {
	c.out <- p
	return nil
}
func (c testPaymentConnection) Payments() <-chan Payment {
	return c.in
}

func makePairedPaymentConnections() (PaymentConnection, PaymentConnection) {
	one := make(chan Payment)
	two := make(chan Payment)
	return testPaymentConnection{one, two}, testPaymentConnection{two, one}
}

type testPayment struct {
	src NodeAddress
	dst NodeAddress
	amt int64
}

func (t testPayment) Source() NodeAddress      { return t.src }
func (t testPayment) Destination() NodeAddress { return t.dst }
func (t testPayment) Verify() error            { return nil }
func (t testPayment) Amount() int64            { return t.amt }

func WaitForIncomingDebt(t *testing.T, p PaymentHandler, a NodeAddress, m int64) {
	timeout := time.After(time.Second)
	tick := time.Tick(time.Millisecond * 5)
	for {
		select {
		case _ = <-timeout:
			t.Fatalf("Timeout witing for IncomingDebt(%v) from %v in %v", m, a, p)
			return
		case _ = <-tick:
			if p.IncomingDebt(a) == m {
				return
			}
		}
	}
}

func WaitForOutgoingDebt(t *testing.T, p PaymentHandler, a NodeAddress, m int64) {
	timeout := time.After(time.Second)
	tick := time.Tick(time.Millisecond * 5)
	for {
		select {
		case _ = <-timeout:
			t.Fatalf("Timeout witing for OutgoingDebt(%v) from %v in %v", m, a, p)
			return
		case _ = <-tick:
			if p.OutgoingDebt(a) == m {
				return
			}
		}
	}
}

func TestPaymentHandler(t *testing.T) {
	h1, h2 := make(chan PacketHash), make(chan PacketHash)
	c1, c2 := makePairedPaymentConnections()
	a1 := NodeAddress("1")
	a2 := NodeAddress("2")
	p1 := newPaymentImpl(a1, h1)
	p2 := newPaymentImpl(a2, h2)
	p1.AddConnection(a2, c1)
	p2.AddConnection(a1, c2)

	t1 := testPacket(a2)
	p1.AddSentPacket(t1, a1, a2)
	WaitForIncomingDebt(t, p1, a1, 0)
	WaitForOutgoingDebt(t, p1, a2, 0)
	h1 <- t1.Hash()
	WaitForIncomingDebt(t, p1, a1, 1)
	WaitForOutgoingDebt(t, p1, a2, 1)

	p2.AddSentPacket(t1, a1, a2)
	h2 <- t1.Hash()
	WaitForIncomingDebt(t, p2, a1, 1)

	payment := testPayment{a1, a2, 1}
	p1.SendPayment(payment)
	WaitForIncomingDebt(t, p2, a1, 0)
	WaitForOutgoingDebt(t, p1, a2, 0)
}
<|endoftext|>


<commit_before>package plugin

import (
	"io"
	"math/rand"
	"net/http"
	"net/http/httputil"
	"net/url"
	"sync/atomic"
	"time"

	"golang.org/x/net/websocket"

	"github.com/labstack/echo"
)

type (
	Proxy struct {
		Base     `json:",squash"`
		Balance  string    `json:"balance"`
		Targets  []*Target `json:"targets"`
		balancer Balancer
	}

	Target struct {
		Name string `json:"name,omitempty"`
		URL  string `json:"url"`
		url  *url.URL
	}

	Random struct {
		targets []*Target
		random  *rand.Rand
	}

	RoundRobin struct {
		targets []*Target
		i       uint32
	}

	Balancer interface {
		Next(int) *Target
		Length() int
	}
)

func (p *Proxy) Init() (err error) {
	for _, t := range p.Targets {
		t.url, err = url.Parse(t.URL)
		if err != nil {
			return
		}
	}

	// Balancer
	switch p.Balance {
	case "round-robin":
		p.balancer = &RoundRobin{targets: p.Targets}
	default: // Random
		p.balancer = &Random{
			targets: p.Targets,
			random:  rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
		}
	}

	return
}

func (*Proxy) Priority() int {
	return 1
}

func (p *Proxy) Process(echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) (err error) {
		req := c.Request()
		res := c.Response()
		i := -1
		t := p.balancer.Next(i).url

		// Next:
		// 	*outReq.URL = *p.balancer.Next(i).url // Shallow copy
		// 	path := c.P(0)
		// 	if path != "" {
		// 		if path[0] != '/' { // Prepend '/' if necessary
		// 			path = "/" + path
		// 		}
		// 		outReq.URL.Path = path
		// 		outReq.URL.RawQuery = c.QueryString()
		// 	}
		// 	outReq.Header = req.Header
		// 	p.Logger.Infof("proxy: out request, url=%v", outReq.URL)

		if req.Header.Get(echo.HeaderUpgrade) == "websocket" {
			p.wsProxy(t).ServeHTTP(res, req)
		} else {
			p.httpProxy(t).ServeHTTP(res, req)
		}

		// 	// Out request
		// 	outReq := &http.Request{
		// 		Method:        req.Method,
		// 		Close:         false, // Persistent connection
		// 		URL:           new(url.URL),
		// 		Body:          req.Body,
		// 		ContentLength: int64(req.ContentLength),
		// 	}
		// Next:
		// 	*outReq.URL = *p.balancer.Next(i).url // Shallow copy
		// 	path := c.P(0)
		// 	if path != "" {
		// 		if path[0] != '/' { // Prepend '/' if necessary
		// 			path = "/" + path
		// 		}
		// 		outReq.URL.Path = path
		// 		outReq.URL.RawQuery = c.QueryString()
		// 	}
		// 	outReq.Header = req.Header
		// 	p.Logger.Infof("proxy: out request, url=%v", outReq.URL)
		//
		// 	// Out response
		// 	outRes, err := p.transport.RoundTrip(outReq)
		// 	if err != nil {
		// 		p.Logger.Errorf("proxy: error=%s", err)
		// 		i++
		// 		if i == p.balancer.Length() {
		// 			return echo.NewHTTPError(http.StatusBadGateway)
		// 		}
		// 		p.Logger.Warnf("proxy: trying target=%s", outReq.URL)
		// 		goto Next
		// 	}
		// 	p.Logger.Infof("proxy: out response, status=%d", outRes.StatusCode)
		// 	defer outRes.Body.Close()
		// 	for k := range outRes.Header { // Copy headers
		// 		res.Header().Add(k, outRes.Header.Get(k))
		// 	}
		// 	res.WriteHeader(outRes.StatusCode)
		// 	_, err = io.Copy(res, outRes.Body)
		return
	}
}

func (r *Random) Next(i int) *Target {
	if i == -1 {
		return r.targets[r.random.Intn(len(r.targets))]
	}
	return r.targets[i]
}

func (r *Random) Length() int {
	return len(r.targets)
}

func (r *RoundRobin) Next(i int) *Target {
	if i == -1 {
		if r.i == uint32(len(r.targets)) {
			r.i = 0
		}
		atomic.AddUint32(&r.i, 1)
		return r.targets[r.i]
	}
	return r.targets[i]
}

func (r *RoundRobin) Length() int {
	return len(r.targets)
}

func (p *Proxy) httpProxy(u *url.URL) http.Handler {
	return httputil.NewSingleHostReverseProxy(u)
}

func (p *Proxy) wsProxy(u *url.URL) http.Handler {
	return websocket.Handler(func(in *websocket.Conn) {
		defer in.Close()

		r := in.Request()
		t := "ws://" + u.Host + r.RequestURI
		out, err := websocket.Dial(t, "", r.Header.Get("Origin"))
		if err != nil {
			p.Logger.Errorf("ws proxy error, target=%s, err=%v", t, err)
			return
		}
		defer out.Close()

		errc := make(chan error, 2)
		cp := func(w io.Writer, r io.Reader) {
			_, err := io.Copy(w, r)
			errc <- err
		}

		go cp(in, out)
		go cp(out, in)
		err = <-errc
		if err != nil && err != io.EOF {
			p.Logger.Errorf("ws proxy error, url=%s, err=%v", r.URL, err)
		}
	})
}
<commit_msg>fix(proxy): set forwarded-proto header<commit_after>package plugin

import (
	"io"
	"math/rand"
	"net/http"
	"net/http/httputil"
	"net/url"
	"sync/atomic"
	"time"

	"golang.org/x/net/websocket"

	"github.com/labstack/echo"
)

type (
	Proxy struct {
		Base     `json:",squash"`
		Balance  string    `json:"balance"`
		Targets  []*Target `json:"targets"`
		balancer Balancer
	}

	Target struct {
		Name string `json:"name,omitempty"`
		URL  string `json:"url"`
		url  *url.URL
	}

	Random struct {
		targets []*Target
		random  *rand.Rand
	}

	RoundRobin struct {
		targets []*Target
		i       uint32
	}

	Balancer interface {
		Next(int) *Target
		Length() int
	}
)

func (p *Proxy) Init() (err error) {
	for _, t := range p.Targets {
		t.url, err = url.Parse(t.URL)
		if err != nil {
			return
		}
	}

	// Balancer
	switch p.Balance {
	case "round-robin":
		p.balancer = &RoundRobin{targets: p.Targets}
	default: // Random
		p.balancer = &Random{
			targets: p.Targets,
			random:  rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
		}
	}

	return
}

func (*Proxy) Priority() int {
	return 1
}

func (p *Proxy) Process(echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) (err error) {
		req := c.Request()
		res := c.Response()
		i := -1
		t := p.balancer.Next(i).url

		// Next:
		// 	*outReq.URL = *p.balancer.Next(i).url // Shallow copy
		// 	path := c.P(0)
		// 	if path != "" {
		// 		if path[0] != '/' { // Prepend '/' if necessary
		// 			path = "/" + path
		// 		}
		// 		outReq.URL.Path = path
		// 		outReq.URL.RawQuery = c.QueryString()
		// 	}
		// 	outReq.Header = req.Header
		// 	p.Logger.Infof("proxy: out request, url=%v", outReq.URL)

		// Tell upstream that the incoming request is https
		if c.IsTLS() {
			req.Header.Set(echo.HeaderXForwardedProto, "https")
		}

		if req.Header.Get(echo.HeaderUpgrade) == "websocket" {
			p.wsProxy(t).ServeHTTP(res, req)
		} else {
			p.httpProxy(t).ServeHTTP(res, req)
		}

		// 	// Out request
		// 	outReq := &http.Request{
		// 		Method:        req.Method,
		// 		Close:         false, // Persistent connection
		// 		URL:           new(url.URL),
		// 		Body:          req.Body,
		// 		ContentLength: int64(req.ContentLength),
		// 	}
		// Next:
		// 	*outReq.URL = *p.balancer.Next(i).url // Shallow copy
		// 	path := c.P(0)
		// 	if path != "" {
		// 		if path[0] != '/' { // Prepend '/' if necessary
		// 			path = "/" + path
		// 		}
		// 		outReq.URL.Path = path
		// 		outReq.URL.RawQuery = c.QueryString()
		// 	}
		// 	outReq.Header = req.Header
		// 	p.Logger.Infof("proxy: out request, url=%v", outReq.URL)
		//
		// 	// Out response
		// 	outRes, err := p.transport.RoundTrip(outReq)
		// 	if err != nil {
		// 		p.Logger.Errorf("proxy: error=%s", err)
		// 		i++
		// 		if i == p.balancer.Length() {
		// 			return echo.NewHTTPError(http.StatusBadGateway)
		// 		}
		// 		p.Logger.Warnf("proxy: trying target=%s", outReq.URL)
		// 		goto Next
		// 	}
		// 	p.Logger.Infof("proxy: out response, status=%d", outRes.StatusCode)
		// 	defer outRes.Body.Close()
		// 	for k := range outRes.Header { // Copy headers
		// 		res.Header().Add(k, outRes.Header.Get(k))
		// 	}
		// 	res.WriteHeader(outRes.StatusCode)
		// 	_, err = io.Copy(res, outRes.Body)
		return
	}
}

func (r *Random) Next(i int) *Target {
	if i == -1 {
		return r.targets[r.random.Intn(len(r.targets))]
	}
	return r.targets[i]
}

func (r *Random) Length() int {
	return len(r.targets)
}

func (r *RoundRobin) Next(i int) *Target {
	if i == -1 {
		if r.i == uint32(len(r.targets)) {
			r.i = 0
		}
		atomic.AddUint32(&r.i, 1)
		return r.targets[r.i]
	}
	return r.targets[i]
}

func (r *RoundRobin) Length() int {
	return len(r.targets)
}

func (p *Proxy) httpProxy(u *url.URL) http.Handler {
	return httputil.NewSingleHostReverseProxy(u)
}

func (p *Proxy) wsProxy(u *url.URL) http.Handler {
	return websocket.Handler(func(in *websocket.Conn) {
		defer in.Close()

		r := in.Request()
		t := "ws://" + u.Host + r.RequestURI
		out, err := websocket.Dial(t, "", r.Header.Get("Origin"))
		if err != nil {
			p.Logger.Errorf("ws proxy error, target=%s, err=%v", t, err)
			return
		}
		defer out.Close()

		errc := make(chan error, 2)
		cp := func(w io.Writer, r io.Reader) {
			_, err := io.Copy(w, r)
			errc <- err
		}

		go cp(in, out)
		go cp(out, in)
		err = <-errc
		if err != nil && err != io.EOF {
			p.Logger.Errorf("ws proxy error, url=%s, err=%v", r.URL, err)
		}
	})
}
<|endoftext|>


<commit_before>package world

import (
	"fmt"
)

type ObjectLike interface {
	// NotifyPosition is called when an object is added to, removed from,
	// or moved between tiles. The argument is the new tile, or nil for
	// removal. This function must return the previous value given to it.
	NotifyPosition(*Tile) *Tile

	// Think is called every tick (200ms) for objects that are in a zone.
	Think()

	// Save returns a version number and data describing the object.
	// Data may only contain primitives, []interface{}, and
	// map[string]interface{}, recursively.
	Save() (uint, interface{})

	// Load is given a version number and data from a previous call to Save.
	// Panicing on errors is suggested. From a zero value of a type, after
	// a call to Load, the NotifyPosition method's next call should return
	// nil.
	Load(uint, interface{})
}

type Object struct {
	tile *Tile
}

func init() {
	Register("object", (*Object)(nil))
}

func (o *Object) NotifyPosition(t *Tile) *Tile {
	old := o.tile
	o.tile = t
	return old
}

func (o *Object) Think() {
	// do nothing
}

func (o *Object) Save() (uint, interface{}) {
	return 0, 0
}

func (o *Object) Load(version uint, data interface{}) {
	switch version {
	case 0:
		// no fields in version 0
	default:
		panic(fmt.Sprintf("version %d unknown", version))
	}
}
<commit_msg>add Position method to Object<commit_after>package world

import (
	"fmt"
	"sync/atomic"
	"unsafe"
)

type ObjectLike interface {
	// NotifyPosition is called when an object is added to, removed from,
	// or moved between tiles. The argument is the new tile, or nil for
	// removal. This function must return the previous value given to it.
	NotifyPosition(*Tile) *Tile

	// This function is not called, but is provided in the default
	// implementation for convenience.
	Position() *Tile

	// Think is called every tick (200ms) for objects that are in a zone.
	Think()

	// Save returns a version number and data describing the object.
	// Data may only contain primitives, []interface{}, and
	// map[string]interface{}, recursively.
	Save() (uint, interface{})

	// Load is given a version number and data from a previous call to Save.
	// Panicing on errors is suggested. From a zero value of a type, after
	// a call to Load, the NotifyPosition method's next call should return
	// nil.
	Load(uint, interface{})
}

type Object struct {
	tile unsafe.Pointer // *Tile
}

func init() {
	Register("object", (*Object)(nil))
}

func (o *Object) NotifyPosition(t *Tile) *Tile {
	for {
		old := atomic.LoadPointer(&o.tile)
		if atomic.CompareAndSwapPointer(&o.tile, old, unsafe.Pointer(t)) {
			return (*Tile)(old)
		}
	}
}

func (o *Object) Position() *Tile {
	return (*Tile)(atomic.LoadPointer(&o.tile))
}

func (o *Object) Think() {
	// do nothing
}

func (o *Object) Save() (uint, interface{}) {
	return 0, 0
}

func (o *Object) Load(version uint, data interface{}) {
	switch version {
	case 0:
		// no fields in version 0
	default:
		panic(fmt.Sprintf("version %d unknown", version))
	}
}
<|endoftext|>


<commit_before>package ws

import (
	"babelweb2/parser"
	"log"
	"net/http"
	"sync"

	"github.com/gorilla/websocket"
)

const (
	delete = iota
	update = iota
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

var Db dataBase

//Message messages to send to the client via websocket
type Message map[string]interface{}

type dataBase struct {
	sync.Mutex
	Bd parser.BabelDesc
}

//MCUpdates multicast updates sent by the routine comminicating with the routers
func MCUpdates(updates chan parser.BabelUpdate, g *Listenergroupe,
	wg *sync.WaitGroup) {
	wg.Add(1)
	for {
		update, quit := <-updates
		if !quit {
			log.Println("closing all channels")
			g.Iter(func(l *Listener) {
				close(l.conduct)
			})
			wg.Done()
			return
		}
		if !(Db.Bd.CheckUpdate(update)) {
			continue
		}
		Db.Lock()
		err := Db.Bd.Update(update)
		if err != nil {
			log.Println(err)
		}
		Db.Unlock()
		t := update.ToS()
		g.Iter(func(l *Listener) {
			l.conduct <- t
		})
		//TODO unlock()
	}
}

//GetMess gets messages sent by the client and redirect them to the mess chanel
func GetMess(conn *websocket.Conn, mess chan []byte) {
	_, message, err := conn.ReadMessage()
	if err != nil {
		close(mess)
		log.Println(err)
		return
	}
	mess <- message

}

//HandleMessage handle messages receved from the client
func HandleMessage(mess []byte) {
	//TODO gere les message du client
	return
}

//Handler manage the websockets
func Handler(l *Listenergroupe) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Println("Could not create the socket.", err)
			return
		}

		Db.Lock()
		Db.Bd.Iter(func(bu parser.BabelUpdate) error {
			sbu := bu.ToS()
			err := conn.WriteJSON(sbu)
			if err != nil {
				log.Println(err)
			}
			return err
		})
		Db.Unlock()

		log.Println("New connection to a websocket")
		updates := NewListener()
		l.Push(updates)
		defer l.Flush(updates)
		mess := make(chan []byte, ChanelSize)
		go GetMess(conn, mess)
		for {
			//we wait for a new message from the client or from our channel
			select {
			case lastUp := <-updates.conduct: //we got a new update on the channel

				log.Println("sending:\n", lastUp)

				err := conn.WriteJSON(lastUp)
				if err != nil {
					log.Println(err)
				}

			case clientMessage, q := <-mess: //we got a message from the client
				if q == false {
					return
				}

				log.Println(clientMessage)

				HandleMessage(clientMessage)

			}
		}
	}
	return http.HandlerFunc(fn)
}
<commit_msg>Change the place where we unlock the database in order to not miss any updates<commit_after>package ws

import (
	"babelweb2/parser"
	"log"
	"net/http"
	"sync"

	"github.com/gorilla/websocket"
)

const (
	delete = iota
	update = iota
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

var Db dataBase

//Message messages to send to the client via websocket
type Message map[string]interface{}

type dataBase struct {
	sync.Mutex
	Bd parser.BabelDesc
}

//MCUpdates multicast updates sent by the routine comminicating with the routers
func MCUpdates(updates chan parser.BabelUpdate, g *Listenergroupe,
	wg *sync.WaitGroup) {
	wg.Add(1)
	for {
		update, quit := <-updates
		if !quit {
			log.Println("closing all channels")
			g.Iter(func(l *Listener) {
				close(l.conduct)
			})
			wg.Done()
			return
		}
		if !(Db.Bd.CheckUpdate(update)) {
			continue
		}
		Db.Lock()
		err := Db.Bd.Update(update)
		if err != nil {
			log.Println(err)
		}
		Db.Unlock()
		t := update.ToS()
		g.Iter(func(l *Listener) {
			l.conduct <- t
		})
		//TODO unlock()
	}
}

//GetMess gets messages sent by the client and redirect them to the mess chanel
func GetMess(conn *websocket.Conn, mess chan []byte) {
	_, message, err := conn.ReadMessage()
	if err != nil {
		close(mess)
		log.Println(err)
		return
	}
	mess <- message

}

//HandleMessage handle messages receved from the client
func HandleMessage(mess []byte) {
	//TODO gere les message du client
	return
}

//Handler manage the websockets
func Handler(l *Listenergroupe) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Println("Could not create the socket.", err)
			return
		}

		Db.Lock()
		Db.Bd.Iter(func(bu parser.BabelUpdate) error {
			sbu := bu.ToS()
			err := conn.WriteJSON(sbu)
			if err != nil {
				log.Println(err)
			}
			return err
		})

		log.Println("New connection to a websocket")
		updates := NewListener()
		l.Push(updates)
		Db.Unlock()
		defer l.Flush(updates)
		mess := make(chan []byte, ChanelSize)
		go GetMess(conn, mess)
		for {
			//we wait for a new message from the client or from our channel
			select {
			case lastUp := <-updates.conduct: //we got a new update on the channel

				log.Println("sending:\n", lastUp)

				err := conn.WriteJSON(lastUp)
				if err != nil {
					log.Println(err)
				}

			case clientMessage, q := <-mess: //we got a message from the client
				if q == false {
					return
				}

				log.Println(clientMessage)

				HandleMessage(clientMessage)

			}
		}
	}
	return http.HandlerFunc(fn)
}
<|endoftext|>


<commit_before>package departure

import (
	"time"
	"fmt"
)

func Watch(duration, throttle, bufferTime int, apiKey, origin, destination, transitMode, lineName string) {
	ticker := time.NewTicker(time.Second * time.Duration(throttle))
	go func() {
		for range ticker.C {
			desiredDepTime := time.Now().Add(time.Duration(bufferTime) * time.Second)
			depTime, err := GetDepartureTime(origin, destination, apiKey, transitMode, lineName, desiredDepTime)
			if err != nil {
				fmt.Printf("ERROR %s\n", err)
			} else {
				until := time.Until(depTime)
				untilSeconds := int(until.Seconds())

				if untilSeconds < bufferTime {
					fmt.Printf("GO %d\n", untilSeconds)
				} else {
					fmt.Printf("WAIT %d\n", untilSeconds)
				}
			}
		}
	}()
	time.Sleep(time.Second * time.Duration(duration))
	ticker.Stop()
	fmt.Println("DONE")
}
<commit_msg>Subtract buffer time from wait time<commit_after>package departure

import (
	"time"
	"fmt"
)

func Watch(duration, throttle, bufferTime int, apiKey, origin, destination, transitMode, lineName string) {
	ticker := time.NewTicker(time.Second * time.Duration(throttle))
	go func() {
		for range ticker.C {
			desiredDepTime := time.Now().Add(time.Duration(bufferTime) * time.Second)
			depTime, err := GetDepartureTime(origin, destination, apiKey, transitMode, lineName, desiredDepTime)
			if err != nil {
				fmt.Printf("ERROR %s\n", err)
			} else {
				until := time.Until(depTime)
				untilSeconds := int(until.Seconds()) - bufferTime

				if untilSeconds < bufferTime {
					fmt.Printf("GO %d\n", untilSeconds)
				} else {
					fmt.Printf("WAIT %d\n", untilSeconds)
				}
			}
		}
	}()
	time.Sleep(time.Second * time.Duration(duration))
	ticker.Stop()
	fmt.Println("DONE")
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 mock

import (
	"bytes"
	"errors"
	"github.com/Matir/gobuster/client"
	"io/ioutil"
	"net/http"
	"net/url"
)

type MockClientFactory struct {
	ForeverClient *MockClient
	NextClient    *MockClient
}
type MockClient struct {
	NextResponse *http.Response
	Requests     []*url.URL
}

func (f *MockClientFactory) Get() client.Client {
	if f.NextClient != nil {
		c := f.NextClient
		f.NextClient = nil
		return c
	}
	if f.ForeverClient != nil {
		return f.ForeverClient
	}
	return &MockClient{}
}

func (c *MockClient) RequestURL(u *url.URL) (*http.Response, error) {
	c.Requests = append(c.Requests, u)
	if c.NextResponse == nil {
		return nil, errors.New("No NextResponse for MockClient.")
	}
	r := c.NextResponse
	c.NextResponse = nil
	return r, nil
}

func (_ *MockClient) SetCheckRedirect(_ func(*http.Request, []*http.Request) error) {}

func ResponseFromString(s string) *http.Response {
	cb := ioutil.NopCloser(bytes.NewBufferString(s))
	return &http.Response{
		Body: cb,
	}
}

func MockRobotsResponse() *http.Response {
	s := `User-agent: *
Disallow: /a`
	return ResponseFromString(s)
}
<commit_msg>Commit mock changes.<commit_after>// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 mock

import (
	"bytes"
	"errors"
	"github.com/Matir/gobuster/client"
	"io/ioutil"
	"net/http"
	"net/url"
)

type MockClientFactory struct {
	ForeverClient *MockClient
	NextClient    *MockClient
}
type MockClient struct {
	ForeverResponse *http.Response
	NextResponse    *http.Response
	Requests        []*url.URL
	Redir           *url.URL
	CheckRedirect   func(*http.Request, []*http.Request) error
}

func (f *MockClientFactory) Get() client.Client {
	if f.NextClient != nil {
		c := f.NextClient
		f.NextClient = nil
		return c
	}
	if f.ForeverClient != nil {
		return f.ForeverClient
	}
	return &MockClient{}
}

func (c *MockClient) RequestURL(u *url.URL) (*http.Response, error) {
	c.Requests = append(c.Requests, u)
	if c.Redir != nil && c.CheckRedirect != nil {
		req := &http.Request{URL: c.Redir}
		if err := c.CheckRedirect(req, []*http.Request{}); err != nil {
			return nil, err
		}
	}
	if c.ForeverResponse != nil {
		return c.ForeverResponse, nil
	}
	if c.NextResponse == nil {
		return nil, errors.New("No NextResponse for MockClient.")
	}
	r := c.NextResponse
	c.NextResponse = nil
	return r, nil
}

func (c *MockClient) SetCheckRedirect(f func(*http.Request, []*http.Request) error) {
	c.CheckRedirect = f
}

func ResponseFromString(s string) *http.Response {
	cb := ioutil.NopCloser(bytes.NewBufferString(s))
	return &http.Response{
		Body: cb,
	}
}

func MockRobotsResponse() *http.Response {
	s := `User-agent: *
Disallow: /a`
	return ResponseFromString(s)
}
<|endoftext|>


<commit_before>package filepathutil

// $ go get github.com/grokify/gotilla/git/apps/gitremoteaddupstream

import (
	"os"
	"os/user"
	"strings"
)

func CurLeafDir() (string, error) {
	dir, err := os.Getwd()
	if err != nil {
		return "", err
	}
	dirParts := strings.Split(dir, string(os.PathSeparator))
	if len(dirParts) > 0 {
		return dirParts[len(dirParts)-1], nil
	}
	return "", nil
}

// UserToAbsolute converts ~ directories to absolute directories
// in filepaths. This is useful because ~ cannot be resolved by
// ioutil.ReadFile().
func UserToAbsolute(file string) (string, error) {
	file = strings.TrimSpace(file)
	parts := strings.Split(file, string(os.PathSeparator))
	if len(parts) == 0 {
		return file, nil
	} else if parts[0] != "~" {
		return file, nil
	}
	usr, err := user.Current()
	if err != nil {
		return file, err
	}
	if len(parts) == 1 {
		return usr.HomeDir, nil
	}

	return strings.Join(
		append([]string{usr.HomeDir}, parts[1:]...),
		string(os.PathSeparator)), nil
}
<commit_msg>add comment<commit_after>package filepathutil

// $ go get github.com/grokify/gotilla/git/apps/gitremoteaddupstream

import (
	"os"
	"os/user"
	"strings"
)

// CurLeafDir returns the leaf dir of a nested directory.
func CurLeafDir() (string, error) {
	dir, err := os.Getwd()
	if err != nil {
		return "", err
	}
	dirParts := strings.Split(dir, string(os.PathSeparator))
	if len(dirParts) > 0 {
		return dirParts[len(dirParts)-1], nil
	}
	return "", nil
}

// UserToAbsolute converts ~ directories to absolute directories
// in filepaths. This is useful because ~ cannot be resolved by
// ioutil.ReadFile().
func UserToAbsolute(file string) (string, error) {
	file = strings.TrimSpace(file)
	parts := strings.Split(file, string(os.PathSeparator))
	if len(parts) == 0 {
		return file, nil
	} else if parts[0] != "~" {
		return file, nil
	}
	usr, err := user.Current()
	if err != nil {
		return file, err
	}
	if len(parts) == 1 {
		return usr.HomeDir, nil
	}

	return strings.Join(
		append([]string{usr.HomeDir}, parts[1:]...),
		string(os.PathSeparator)), nil
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 v1alpha1

import (
	"path"
	"strings"

	"github.com/google/kf/v2/pkg/kf/algorithms"
	corev1 "k8s.io/api/core/v1"
)

// TODO(poy): This file SHOULD be generated, but it has been written by hand.

// SpaceDomains implements the necessary interfaces for the algorithms
// package.
type SpaceDomains []SpaceDomain

// Set implements Interface.
func (d SpaceDomains) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(SpaceDomains)[i] = b.(SpaceDomains)[j]
}

// Append implements Interface.
func (d SpaceDomains) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(SpaceDomains)...)
}

// Clone implements Interface.
func (d SpaceDomains) Clone() algorithms.Interface {
	return append(SpaceDomains{}, d...)
}

// Slice implements Interface.
func (d SpaceDomains) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d SpaceDomains) Len() int {
	return len(d)
}

// Less implements Interface.
func (d SpaceDomains) Less(i int, j int) bool {
	return d[i].Domain < d[j].Domain
}

// Swap implements Interface.
func (d SpaceDomains) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// RouteSpecFieldsSlice implements the necessary interfaces for the algorithms
// package.
type RouteSpecFieldsSlice []RouteSpecFields

// Set implements Interface.
func (d RouteSpecFieldsSlice) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(RouteSpecFieldsSlice)[i] = b.(RouteSpecFieldsSlice)[j]
}

// Append implements Interface.
func (d RouteSpecFieldsSlice) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(RouteSpecFieldsSlice)...)
}

// Clone implements Interface.
func (d RouteSpecFieldsSlice) Clone() algorithms.Interface {
	return append(RouteSpecFieldsSlice{}, d...)
}

// Slice implements Interface.
func (d RouteSpecFieldsSlice) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d RouteSpecFieldsSlice) Len() int {
	return len(d)
}

// Less implements Interface.
// This is used to sort RouteSpecFields in an order that makes sense for generating VirtualService rules.
// RouteSpecFields are sorted alphabetically by hostname and domain (though the domain should be the same for all RSFs being compared).
// RSFs with the "*" host are listed last, since they are the most general.
// Within RSFs with the same hostname + domain, the ones with longer paths come first, since they are more specific and
// should be evaluated first in the VS.
func (d RouteSpecFieldsSlice) Less(i int, j int) bool {
	// TODO(https://github.com/knative/pkg/issues/542):
	// We can't garuntee that the path will have the '/' or not
	// because webhooks can't yet modify slices.
	d[i].Path = path.Join("/", d[i].Path)
	d[j].Path = path.Join("/", d[j].Path)

	if d[i].Hostname != d[j].Hostname {
		if strings.HasPrefix(d[i].Hostname, "*") {
			return false
		}
		if strings.HasPrefix(d[j].Hostname, "*") {
			return true
		}
		return d[i].Hostname < d[j].Hostname
	}

	// RouteSpecFields sort is only used by the VirtualService reconciler currently,
	// which uses a list of RSFs with the same domain, so this case shouldn't happen.
	if d[i].Domain != d[j].Domain {
		return d[i].Domain < d[j].Domain
	}

	return len(d[i].Path) > len(d[j].Path)
}

// Swap implements Interface.
func (d RouteSpecFieldsSlice) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// ObjectReferences implements the necessary interfaces for the algorithms
// package.
type ObjectReferences []corev1.ObjectReference

// Set implements Interface.
func (d ObjectReferences) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(ObjectReferences)[i] = b.(ObjectReferences)[j]
}

// Append implements Interface.
func (d ObjectReferences) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(ObjectReferences)...)
}

// Clone implements Interface.
func (d ObjectReferences) Clone() algorithms.Interface {
	return append(ObjectReferences{}, d...)
}

// Slice implements Interface.
func (d ObjectReferences) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d ObjectReferences) Len() int {
	return len(d)
}

// Less implements Interface.
func (d ObjectReferences) Less(i int, j int) bool {
	return d[i].Name < d[j].Name
}

// Swap implements Interface.
func (d ObjectReferences) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// LocalObjectReferences implements the necessary interfaces for the algorithms
// package.
type LocalObjectReferences []corev1.LocalObjectReference

// Set implements Interface.
func (d LocalObjectReferences) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(LocalObjectReferences)[i] = b.(LocalObjectReferences)[j]
}

// Append implements Interface.
func (d LocalObjectReferences) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(LocalObjectReferences)...)
}

// Clone implements Interface.
func (d LocalObjectReferences) Clone() algorithms.Interface {
	return append(LocalObjectReferences{}, d...)
}

// Slice implements Interface.
func (d LocalObjectReferences) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d LocalObjectReferences) Len() int {
	return len(d)
}

// Less implements Interface.
func (d LocalObjectReferences) Less(i int, j int) bool {
	return d[i].Name < d[j].Name
}

// Swap implements Interface.
func (d LocalObjectReferences) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}
<commit_msg>Fix routespec ordering<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 v1alpha1

import (
	"path"
	"strings"

	"github.com/google/kf/v2/pkg/kf/algorithms"
	corev1 "k8s.io/api/core/v1"
)

// TODO(poy): This file SHOULD be generated, but it has been written by hand.

// SpaceDomains implements the necessary interfaces for the algorithms
// package.
type SpaceDomains []SpaceDomain

// Set implements Interface.
func (d SpaceDomains) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(SpaceDomains)[i] = b.(SpaceDomains)[j]
}

// Append implements Interface.
func (d SpaceDomains) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(SpaceDomains)...)
}

// Clone implements Interface.
func (d SpaceDomains) Clone() algorithms.Interface {
	return append(SpaceDomains{}, d...)
}

// Slice implements Interface.
func (d SpaceDomains) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d SpaceDomains) Len() int {
	return len(d)
}

// Less implements Interface.
func (d SpaceDomains) Less(i int, j int) bool {
	return d[i].Domain < d[j].Domain
}

// Swap implements Interface.
func (d SpaceDomains) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// RouteSpecFieldsSlice implements the necessary interfaces for the algorithms
// package.
type RouteSpecFieldsSlice []RouteSpecFields

// Set implements Interface.
func (d RouteSpecFieldsSlice) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(RouteSpecFieldsSlice)[i] = b.(RouteSpecFieldsSlice)[j]
}

// Append implements Interface.
func (d RouteSpecFieldsSlice) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(RouteSpecFieldsSlice)...)
}

// Clone implements Interface.
func (d RouteSpecFieldsSlice) Clone() algorithms.Interface {
	return append(RouteSpecFieldsSlice{}, d...)
}

// Slice implements Interface.
func (d RouteSpecFieldsSlice) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d RouteSpecFieldsSlice) Len() int {
	return len(d)
}

// Less implements Interface.
// This is used to sort RouteSpecFields in an order that makes sense for generating VirtualService rules.
// RouteSpecFields are sorted alphabetically by hostname and domain (though the domain should be the same for all RSFs being compared).
// RSFs with the "*" host are listed last, since they are the most general.
// Within RSFs with the same hostname + domain, the ones with longer paths come first, since they are more specific and
// should be evaluated first in the VS.
func (d RouteSpecFieldsSlice) Less(i int, j int) bool {
	// TODO(https://github.com/knative/pkg/issues/542):
	// We can't garuntee that the path will have the '/' or not
	// because webhooks can't yet modify slices.
	d[i].Path = path.Join("/", d[i].Path)
	d[j].Path = path.Join("/", d[j].Path)

	if d[i].Hostname != d[j].Hostname {
		if strings.HasPrefix(d[i].Hostname, "*") {
			return false
		}
		if strings.HasPrefix(d[j].Hostname, "*") {
			return true
		}
		return d[i].Hostname < d[j].Hostname
	}

	// RouteSpecFields sort is only used by the VirtualService reconciler currently,
	// which uses a list of RSFs with the same domain, so this case shouldn't happen.
	if d[i].Domain != d[j].Domain {
		return d[i].Domain < d[j].Domain
	}

	if len(d[i].Path) != len(d[j].Path) {
		return len(d[i].Path) > len(d[j].Path)
	}

	return d[i].Path < d[j].Path
}

// Swap implements Interface.
func (d RouteSpecFieldsSlice) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// ObjectReferences implements the necessary interfaces for the algorithms
// package.
type ObjectReferences []corev1.ObjectReference

// Set implements Interface.
func (d ObjectReferences) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(ObjectReferences)[i] = b.(ObjectReferences)[j]
}

// Append implements Interface.
func (d ObjectReferences) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(ObjectReferences)...)
}

// Clone implements Interface.
func (d ObjectReferences) Clone() algorithms.Interface {
	return append(ObjectReferences{}, d...)
}

// Slice implements Interface.
func (d ObjectReferences) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d ObjectReferences) Len() int {
	return len(d)
}

// Less implements Interface.
func (d ObjectReferences) Less(i int, j int) bool {
	return d[i].Name < d[j].Name
}

// Swap implements Interface.
func (d ObjectReferences) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}

// LocalObjectReferences implements the necessary interfaces for the algorithms
// package.
type LocalObjectReferences []corev1.LocalObjectReference

// Set implements Interface.
func (d LocalObjectReferences) Set(i int, a algorithms.Interface, j int, b algorithms.Interface) {
	a.(LocalObjectReferences)[i] = b.(LocalObjectReferences)[j]
}

// Append implements Interface.
func (d LocalObjectReferences) Append(a algorithms.Interface) algorithms.Interface {
	return append(d, a.(LocalObjectReferences)...)
}

// Clone implements Interface.
func (d LocalObjectReferences) Clone() algorithms.Interface {
	return append(LocalObjectReferences{}, d...)
}

// Slice implements Interface.
func (d LocalObjectReferences) Slice(i int, j int) algorithms.Interface {
	return d[i:j]
}

// Len implements Interface.
func (d LocalObjectReferences) Len() int {
	return len(d)
}

// Less implements Interface.
func (d LocalObjectReferences) Less(i int, j int) bool {
	return d[i].Name < d[j].Name
}

// Swap implements Interface.
func (d LocalObjectReferences) Swap(i int, j int) {
	d[i], d[j] = d[j], d[i]
}
<|endoftext|>


<commit_before>package cli

import (
	"context"
	"fmt"
	"time"

	"github.com/golang/protobuf/ptypes/empty"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"google.golang.org/grpc"

	"github.com/datawire/telepresence2/pkg/client"
	"github.com/datawire/telepresence2/pkg/rpc/connector"
	"github.com/datawire/telepresence2/pkg/rpc/daemon"
)

type connectorState struct {
	cmd    *cobra.Command
	cr     *connector.ConnectRequest
	conn   *grpc.ClientConn
	daemon daemon.DaemonClient
	grpc   connector.ConnectorClient
	info   *connector.ConnectInfo
}

// Connect asks the daemon to connect to a cluster
func (cs *connectorState) EnsureState() (bool, error) {
	if cs.isConnected() {
		return false, cs.setConnectInfo()
	}

	for attempt := 0; ; attempt++ {
		dr, err := cs.daemon.Status(cs.cmd.Context(), &empty.Empty{})
		if err != nil {
			return false, err
		}
		switch dr.Error {
		case daemon.DaemonStatus_UNSPECIFIED:
		case daemon.DaemonStatus_NOT_STARTED:
			return false, errDaemonIsNotRunning
		case daemon.DaemonStatus_NO_NETWORK:
			if attempt >= 40 {
				return false, errors.New("Unable to connect: Network overrides are not established")
			}
			time.Sleep(250 * time.Millisecond)
			continue
		case daemon.DaemonStatus_PAUSED:
			return false, errors.New("Unable to connect: Network overrides are paused (use 'telepresence resume')")
		}
		break
	}

	cs.cr.InstallId = client.NewScout("unused").Reporter.InstallID()

	err := start(client.GetExe(), []string{"connector-foreground"}, false, nil, nil, nil)
	if err != nil {
		return false, errors.Wrap(err, "failed to launch the connector service")
	}
	fmt.Fprintln(cs.cmd.OutOrStdout(), "Connecting to traffic manager...")

	if err = client.WaitUntilSocketAppears("connector", client.ConnectorSocketName, 10*time.Second); err != nil {
		return false, fmt.Errorf("connector service did not start (see %s for more info)", client.Logfile)
	}
	err = cs.connect()
	if err != nil {
		return false, err
	}
	return false, cs.setConnectInfo()
}

func (cs *connectorState) setConnectInfo() error {
	r, err := cs.grpc.Connect(cs.cmd.Context(), cs.cr)
	if err != nil {
		return err
	}
	cs.info = r

	var msg string
	switch r.Error {
	case connector.ConnectInfo_UNSPECIFIED:
		fmt.Fprintf(cs.cmd.OutOrStdout(), "Connected to context %s (%s)\n", r.ClusterContext, r.ClusterServer)
		return nil
	case connector.ConnectInfo_ALREADY_CONNECTED:
		fmt.Fprintln(cs.cmd.OutOrStdout(), "Already connected")
		return nil
	case connector.ConnectInfo_DISCONNECTING:
		msg = "Unable to connect while disconnecting"
	case connector.ConnectInfo_TRAFFIC_MANAGER_FAILED, connector.ConnectInfo_CLUSTER_FAILED, connector.ConnectInfo_BRIDGE_FAILED:
		msg = r.ErrorText
	}
	return errors.New(msg) // Return true to ensure disconnect
}

func (cs *connectorState) DeactivateState() error {
	if !cs.isConnected() {
		return nil
	}
	out := cs.cmd.OutOrStdout()
	fmt.Fprint(out, "Disconnecting...")
	var err error
	if client.SocketExists(client.ConnectorSocketName) {
		// using context.Background() here since it's likely that the
		// command context has been cancelled.
		_, err = cs.grpc.Quit(context.Background(), &empty.Empty{})
	}
	cs.disconnect()
	if err == nil {
		err = client.WaitUntilSocketVanishes("connector", client.ConnectorSocketName, 5*time.Second)
	}
	if err == nil {
		fmt.Fprintln(out, "done")
	} else {
		fmt.Fprintln(out, "failed")
	}
	return err
}

func newConnectorState(daemon daemon.DaemonClient, cr *connector.ConnectRequest, cmd *cobra.Command) (*connectorState, error) {
	cs := &connectorState{daemon: daemon, cmd: cmd, cr: cr}
	err := assertConnectorStarted()
	if err == nil {
		err = cs.connect()
	}
	return cs, err
}

func assertConnectorStarted() error {
	if client.SocketExists(client.ConnectorSocketName) {
		return nil
	}
	return errConnectorIsNotRunning
}

// withDaemon establishes a connection, calls the function with the gRPC client, and ensures
// that the connection is closed.
func withConnector(cmd *cobra.Command, f func(state *connectorState) error) error {
	ds, err := newDaemonState(cmd, "", "")
	if err != nil {
		return err
	}
	defer ds.disconnect()
	cs, err := newConnectorState(ds.grpc, nil, cmd)
	if err != nil {
		return err
	}
	defer cs.disconnect()
	return f(cs)
}

// isConnected returns true if a connection has been established to the daemon
func (cs *connectorState) isConnected() bool {
	return cs.conn != nil
}

// connect opens the client connection to the daemon.
func (cs *connectorState) connect() (err error) {
	if cs.conn, err = client.DialSocket(client.ConnectorSocketName); err == nil {
		cs.grpc = connector.NewConnectorClient(cs.conn)
	}
	return
}

// disconnect closes the client connection to the daemon.
func (cs *connectorState) disconnect() {
	conn := cs.conn
	cs.conn = nil
	cs.grpc = nil
	if conn != nil {
		conn.Close()
	}
}
<commit_msg>Ensure connector is closed when acquired.<commit_after>package cli

import (
	"context"
	"fmt"
	"time"

	"github.com/golang/protobuf/ptypes/empty"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"google.golang.org/grpc"

	"github.com/datawire/telepresence2/pkg/client"
	"github.com/datawire/telepresence2/pkg/rpc/connector"
	"github.com/datawire/telepresence2/pkg/rpc/daemon"
)

type connectorState struct {
	cmd    *cobra.Command
	cr     *connector.ConnectRequest
	conn   *grpc.ClientConn
	daemon daemon.DaemonClient
	grpc   connector.ConnectorClient
	info   *connector.ConnectInfo
}

// Connect asks the daemon to connect to a cluster
func (cs *connectorState) EnsureState() (bool, error) {
	if cs.isConnected() {
		return false, cs.setConnectInfo()
	}

	for attempt := 0; ; attempt++ {
		dr, err := cs.daemon.Status(cs.cmd.Context(), &empty.Empty{})
		if err != nil {
			return false, err
		}
		switch dr.Error {
		case daemon.DaemonStatus_UNSPECIFIED:
		case daemon.DaemonStatus_NOT_STARTED:
			return false, errDaemonIsNotRunning
		case daemon.DaemonStatus_NO_NETWORK:
			if attempt >= 40 {
				return false, errors.New("Unable to connect: Network overrides are not established")
			}
			time.Sleep(250 * time.Millisecond)
			continue
		case daemon.DaemonStatus_PAUSED:
			return false, errors.New("Unable to connect: Network overrides are paused (use 'telepresence resume')")
		}
		break
	}

	cs.cr.InstallId = client.NewScout("unused").Reporter.InstallID()

	err := start(client.GetExe(), []string{"connector-foreground"}, false, nil, nil, nil)
	if err != nil {
		return false, errors.Wrap(err, "failed to launch the connector service")
	}
	fmt.Fprintln(cs.cmd.OutOrStdout(), "Connecting to traffic manager...")

	if err = client.WaitUntilSocketAppears("connector", client.ConnectorSocketName, 10*time.Second); err != nil {
		return false, fmt.Errorf("connector service did not start (see %s for more info)", client.Logfile)
	}
	err = cs.connect()
	if err != nil {
		return true, err
	}
	return true, cs.setConnectInfo()
}

func (cs *connectorState) setConnectInfo() error {
	r, err := cs.grpc.Connect(cs.cmd.Context(), cs.cr)
	if err != nil {
		return err
	}
	cs.info = r

	var msg string
	switch r.Error {
	case connector.ConnectInfo_UNSPECIFIED:
		fmt.Fprintf(cs.cmd.OutOrStdout(), "Connected to context %s (%s)\n", r.ClusterContext, r.ClusterServer)
		return nil
	case connector.ConnectInfo_ALREADY_CONNECTED:
		fmt.Fprintln(cs.cmd.OutOrStdout(), "Already connected")
		return nil
	case connector.ConnectInfo_DISCONNECTING:
		msg = "Unable to connect while disconnecting"
	case connector.ConnectInfo_TRAFFIC_MANAGER_FAILED, connector.ConnectInfo_CLUSTER_FAILED, connector.ConnectInfo_BRIDGE_FAILED:
		msg = r.ErrorText
	}
	return errors.New(msg) // Return true to ensure disconnect
}

func (cs *connectorState) DeactivateState() error {
	if !cs.isConnected() {
		return nil
	}
	out := cs.cmd.OutOrStdout()
	fmt.Fprint(out, "Disconnecting...")
	var err error
	if client.SocketExists(client.ConnectorSocketName) {
		// using context.Background() here since it's likely that the
		// command context has been cancelled.
		_, err = cs.grpc.Quit(context.Background(), &empty.Empty{})
	}
	cs.disconnect()
	if err == nil {
		err = client.WaitUntilSocketVanishes("connector", client.ConnectorSocketName, 5*time.Second)
	}
	if err == nil {
		fmt.Fprintln(out, "done")
	} else {
		fmt.Fprintln(out, "failed")
	}
	return err
}

func newConnectorState(daemon daemon.DaemonClient, cr *connector.ConnectRequest, cmd *cobra.Command) (*connectorState, error) {
	cs := &connectorState{daemon: daemon, cmd: cmd, cr: cr}
	err := assertConnectorStarted()
	if err == nil {
		err = cs.connect()
	}
	return cs, err
}

func assertConnectorStarted() error {
	if client.SocketExists(client.ConnectorSocketName) {
		return nil
	}
	return errConnectorIsNotRunning
}

// withDaemon establishes a connection, calls the function with the gRPC client, and ensures
// that the connection is closed.
func withConnector(cmd *cobra.Command, f func(state *connectorState) error) error {
	ds, err := newDaemonState(cmd, "", "")
	if err != nil {
		return err
	}
	defer ds.disconnect()
	cs, err := newConnectorState(ds.grpc, nil, cmd)
	if err != nil {
		return err
	}
	defer cs.disconnect()
	return f(cs)
}

// isConnected returns true if a connection has been established to the daemon
func (cs *connectorState) isConnected() bool {
	return cs.conn != nil
}

// connect opens the client connection to the daemon.
func (cs *connectorState) connect() (err error) {
	if cs.conn, err = client.DialSocket(client.ConnectorSocketName); err == nil {
		cs.grpc = connector.NewConnectorClient(cs.conn)
	}
	return
}

// disconnect closes the client connection to the daemon.
func (cs *connectorState) disconnect() {
	conn := cs.conn
	cs.conn = nil
	cs.grpc = nil
	if conn != nil {
		conn.Close()
	}
}
<|endoftext|>


<commit_before>package signapi

import (
	"io/ioutil"
	"net/http"
	"time"

	"github.com/aakso/ssh-inscribe/pkg/auth/authz/authzfilter"

	"github.com/aakso/ssh-inscribe/pkg/auth"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"github.com/pkg/errors"
	"golang.org/x/crypto/ssh"
)

func (sa *SignApi) HandleSign(c echo.Context) error {
	var actx *auth.AuthContext
	if token, _ := c.Get("user").(*jwt.Token); token != nil {
		if claims, _ := token.Claims.(*SignClaim); claims != nil {
			actx = claims.AuthContext
		}
	}
	if actx == nil {
		return errors.New("no auth context")
	}
	log := Log.WithField("audit_id", actx.GetAuthMeta()[auth.MetaAuditID])

	if !actx.IsValid() {
		return echo.NewHTTPError(http.StatusBadRequest, "auth context is not valid")
	}

	body, err := ioutil.ReadAll(c.Request().Body)
	if err != nil {
		err = errors.Wrap(err, "cannot read public key")
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(body)
	if err != nil {
		err = errors.Wrap(err, "cannot parse public key")
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	// User requests to filter principals
	principalsInclude := c.QueryParam("include_principals")
	principalsExclude := c.QueryParam("exclude_principals")
	if principalsInclude != "" || principalsExclude != "" {
		// Special use case for authzfilter
		var authz auth.Authorizer
		authz, err := authzfilter.NewPrincipalFilter(authzfilter.PrincipalFilterConfig{
			FilterIncludePrincipalsGlob: principalsInclude,
			FilterExcludePrincipalsGlob: principalsExclude,
		})
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, errors.Wrap(err, "cannot parse principal filter"))
		}
		if ctx, ok := authz.Authorize(actx); !ok {
			log.Error("user requested principal filter failed, this should not happen")
			return echo.ErrUnauthorized
		} else {
			actx = ctx
		}
	}

	cert := auth.MakeCertificate(pubKey, actx)
	cert.ValidBefore = uint64(time.Now().Add(sa.defaultCertLife).Unix())
	// Validity
	if exp := c.QueryParam("expires"); exp != "" {
		ts, err := time.Parse(time.RFC3339, exp)
		if err != nil {
			err = errors.Wrap(err, "invalid expires")
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		if time.Until(ts) > sa.maxCertLife {
			return echo.NewHTTPError(http.StatusBadRequest, errors.Errorf("maxmimum lifetime is %s", sa.maxCertLife).Error())
		}
		cert.ValidBefore = uint64(ts.Unix())
	}

	if err := sa.signer.SignCertificate(cert); err != nil {
		err = errors.Wrap(err, "cannot sign")
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}
	log.
		WithField("key_id", cert.KeyId).
		WithField("expires", time.Unix(int64(cert.ValidBefore), 0)).
		Info("issued certificate")
	return c.Blob(http.StatusOK, "text/plain", ssh.MarshalAuthorizedKey(cert))
}
<commit_msg>improve certificate issue logging<commit_after>package signapi

import (
	"io/ioutil"
	"net/http"
	"time"

	"github.com/aakso/ssh-inscribe/pkg/auth/authz/authzfilter"

	"github.com/aakso/ssh-inscribe/pkg/auth"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"github.com/pkg/errors"
	"golang.org/x/crypto/ssh"
)

func (sa *SignApi) HandleSign(c echo.Context) error {
	var actx *auth.AuthContext
	if token, _ := c.Get("user").(*jwt.Token); token != nil {
		if claims, _ := token.Claims.(*SignClaim); claims != nil {
			actx = claims.AuthContext
		}
	}
	if actx == nil {
		return errors.New("no auth context")
	}
	log := Log.WithField("audit_id", actx.GetAuthMeta()[auth.MetaAuditID])

	if !actx.IsValid() {
		return echo.NewHTTPError(http.StatusBadRequest, "auth context is not valid")
	}

	// User requests to filter principals
	principalsInclude := c.QueryParam("include_principals")
	principalsExclude := c.QueryParam("exclude_principals")
	if principalsInclude != "" || principalsExclude != "" {
		// Special use case for authzfilter
		var authz auth.Authorizer
		authz, err := authzfilter.NewPrincipalFilter(authzfilter.PrincipalFilterConfig{
			FilterIncludePrincipalsGlob: principalsInclude,
			FilterExcludePrincipalsGlob: principalsExclude,
		})
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, errors.Wrap(err, "cannot parse principal filter"))
		}
		if ctx, ok := authz.Authorize(actx); !ok {
			log.Error("user requested principal filter failed, this should not happen")
			return echo.ErrUnauthorized
		} else {
			actx = ctx
		}
	}

	body, err := ioutil.ReadAll(c.Request().Body)
	if err != nil {
		err = errors.Wrap(err, "cannot read public key")
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(body)
	if err != nil {
		err = errors.Wrap(err, "cannot parse public key")
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	cert := auth.MakeCertificate(pubKey, actx)
	cert.ValidBefore = uint64(time.Now().Add(sa.defaultCertLife).Unix())
	// Validity
	if exp := c.QueryParam("expires"); exp != "" {
		ts, err := time.Parse(time.RFC3339, exp)
		if err != nil {
			err = errors.Wrap(err, "invalid expires")
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		if time.Until(ts) > sa.maxCertLife {
			return echo.NewHTTPError(http.StatusBadRequest, errors.Errorf("maxmimum lifetime is %s", sa.maxCertLife).Error())
		}
		cert.ValidBefore = uint64(ts.Unix())
	}

	if err := sa.signer.SignCertificate(cert); err != nil {
		err = errors.Wrap(err, "cannot sign")
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}
	log.
		WithField("key_id", cert.KeyId).
		WithField("principals", cert.ValidPrincipals).
		WithField("critical_options", cert.CriticalOptions).
		WithField("extensions", cert.Extensions).
		WithField("not_before", time.Unix(int64(cert.ValidAfter), 0)).
		WithField("expires", time.Unix(int64(cert.ValidBefore), 0)).
		WithField("pubkey_fp", ssh.FingerprintSHA256(pubKey)).
		WithField("pubkey_fp_md5", ssh.FingerprintLegacyMD5(pubKey)).
		Info("issued certificate")
	return c.Blob(http.StatusOK, "text/plain", ssh.MarshalAuthorizedKey(cert))
}
<|endoftext|>


<commit_before>package prometheus

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"time"

	"gopkg.in/guregu/null.v3"

	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/prometheus/client_golang/api/prometheus"
	pmodel "github.com/prometheus/common/model"
)

type PrometheusExecutor struct {
	*tsdb.DataSourceInfo
}

func NewPrometheusExecutor(dsInfo *tsdb.DataSourceInfo) tsdb.Executor {
	return &PrometheusExecutor{dsInfo}
}

var (
	plog log.Logger
)

func init() {
	plog = log.New("tsdb.prometheus")
	tsdb.RegisterExecutor("prometheus", NewPrometheusExecutor)
}

func (e *PrometheusExecutor) getClient() (prometheus.QueryAPI, error) {
	cfg := prometheus.Config{
		Address: e.DataSourceInfo.Url,
	}

	client, err := prometheus.New(cfg)
	if err != nil {
		return nil, err
	}

	return prometheus.NewQueryAPI(client), nil
}

func (e *PrometheusExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice, queryContext *tsdb.QueryContext) *tsdb.BatchResult {
	result := &tsdb.BatchResult{}

	client, err := e.getClient()
	if err != nil {
		return result.WithError(err)
	}

	query, err := parseQuery(queries, queryContext)
	if err != nil {
		return result.WithError(err)
	}

	timeRange := prometheus.Range{
		Start: query.Start,
		End:   query.End,
		Step:  query.Step,
	}

	value, err := client.QueryRange(ctx, query.Expr, timeRange)

	if err != nil {
		return result.WithError(err)
	}

	queryResult, err := parseResponse(value, query)
	if err != nil {
		return result.WithError(err)
	}
	result.QueryResults = queryResult
	return result
}

func formatLegend(metric pmodel.Metric, query *PrometheusQuery) string {
	reg, _ := regexp.Compile(`\{\{\s*(.+?)\s*\}\}`)

	result := reg.ReplaceAllFunc([]byte(query.LegendFormat), func(in []byte) []byte {
		labelName := strings.Replace(string(in), "{{", "", 1)
		labelName = strings.Replace(labelName, "}}", "", 1)
		labelName = strings.TrimSpace(labelName)
		if val, exists := metric[pmodel.LabelName(labelName)]; exists {
			return []byte(val)
		}

		return in
	})

	return string(result)
}

func parseQuery(queries tsdb.QuerySlice, queryContext *tsdb.QueryContext) (*PrometheusQuery, error) {
	queryModel := queries[0]

	expr, err := queryModel.Model.Get("expr").String()
	if err != nil {
		return nil, err
	}

	step, err := queryModel.Model.Get("step").Int64()
	if err != nil {
		return nil, err
	}

	format, err := queryModel.Model.Get("legendFormat").String()
	if err != nil {
		return nil, err
	}

	start, err := queryContext.TimeRange.ParseFrom()
	if err != nil {
		return nil, err
	}

	end, err := queryContext.TimeRange.ParseTo()
	if err != nil {
		return nil, err
	}

	return &PrometheusQuery{
		Expr:         expr,
		Step:         time.Second * time.Duration(step),
		LegendFormat: format,
		Start:        start,
		End:          end,
	}, nil
}

func parseResponse(value pmodel.Value, query *PrometheusQuery) (map[string]*tsdb.QueryResult, error) {
	queryResults := make(map[string]*tsdb.QueryResult)
	queryRes := tsdb.NewQueryResult()

	data, ok := value.(pmodel.Matrix)
	if !ok {
		return queryResults, fmt.Errorf("Unsupported result format: %s", value.Type().String())
	}

	for _, v := range data {
		series := tsdb.TimeSeries{
			Name: formatLegend(v.Metric, query),
		}

		for _, k := range v.Values {
			series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(float64(k.Value)), float64(k.Timestamp.Unix()*1000)))
		}

		queryRes.Series = append(queryRes.Series, &series)
	}

	queryResults["A"] = queryRes
	return queryResults, nil
}

/*
func resultWithError(result *tsdb.BatchResult, err error) *tsdb.BatchResult {
	result.Error = err
	return result
}*/
<commit_msg>chore(tsdb): remove commented code<commit_after>package prometheus

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"time"

	"gopkg.in/guregu/null.v3"

	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/prometheus/client_golang/api/prometheus"
	pmodel "github.com/prometheus/common/model"
)

type PrometheusExecutor struct {
	*tsdb.DataSourceInfo
}

func NewPrometheusExecutor(dsInfo *tsdb.DataSourceInfo) tsdb.Executor {
	return &PrometheusExecutor{dsInfo}
}

var (
	plog log.Logger
)

func init() {
	plog = log.New("tsdb.prometheus")
	tsdb.RegisterExecutor("prometheus", NewPrometheusExecutor)
}

func (e *PrometheusExecutor) getClient() (prometheus.QueryAPI, error) {
	cfg := prometheus.Config{
		Address: e.DataSourceInfo.Url,
	}

	client, err := prometheus.New(cfg)
	if err != nil {
		return nil, err
	}

	return prometheus.NewQueryAPI(client), nil
}

func (e *PrometheusExecutor) Execute(ctx context.Context, queries tsdb.QuerySlice, queryContext *tsdb.QueryContext) *tsdb.BatchResult {
	result := &tsdb.BatchResult{}

	client, err := e.getClient()
	if err != nil {
		return result.WithError(err)
	}

	query, err := parseQuery(queries, queryContext)
	if err != nil {
		return result.WithError(err)
	}

	timeRange := prometheus.Range{
		Start: query.Start,
		End:   query.End,
		Step:  query.Step,
	}

	value, err := client.QueryRange(ctx, query.Expr, timeRange)

	if err != nil {
		return result.WithError(err)
	}

	queryResult, err := parseResponse(value, query)
	if err != nil {
		return result.WithError(err)
	}
	result.QueryResults = queryResult
	return result
}

func formatLegend(metric pmodel.Metric, query *PrometheusQuery) string {
	reg, _ := regexp.Compile(`\{\{\s*(.+?)\s*\}\}`)

	result := reg.ReplaceAllFunc([]byte(query.LegendFormat), func(in []byte) []byte {
		labelName := strings.Replace(string(in), "{{", "", 1)
		labelName = strings.Replace(labelName, "}}", "", 1)
		labelName = strings.TrimSpace(labelName)
		if val, exists := metric[pmodel.LabelName(labelName)]; exists {
			return []byte(val)
		}

		return in
	})

	return string(result)
}

func parseQuery(queries tsdb.QuerySlice, queryContext *tsdb.QueryContext) (*PrometheusQuery, error) {
	queryModel := queries[0]

	expr, err := queryModel.Model.Get("expr").String()
	if err != nil {
		return nil, err
	}

	step, err := queryModel.Model.Get("step").Int64()
	if err != nil {
		return nil, err
	}

	format, err := queryModel.Model.Get("legendFormat").String()
	if err != nil {
		return nil, err
	}

	start, err := queryContext.TimeRange.ParseFrom()
	if err != nil {
		return nil, err
	}

	end, err := queryContext.TimeRange.ParseTo()
	if err != nil {
		return nil, err
	}

	return &PrometheusQuery{
		Expr:         expr,
		Step:         time.Second * time.Duration(step),
		LegendFormat: format,
		Start:        start,
		End:          end,
	}, nil
}

func parseResponse(value pmodel.Value, query *PrometheusQuery) (map[string]*tsdb.QueryResult, error) {
	queryResults := make(map[string]*tsdb.QueryResult)
	queryRes := tsdb.NewQueryResult()

	data, ok := value.(pmodel.Matrix)
	if !ok {
		return queryResults, fmt.Errorf("Unsupported result format: %s", value.Type().String())
	}

	for _, v := range data {
		series := tsdb.TimeSeries{
			Name: formatLegend(v.Metric, query),
		}

		for _, k := range v.Values {
			series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(float64(k.Value)), float64(k.Timestamp.Unix()*1000)))
		}

		queryRes.Series = append(queryRes.Series, &series)
	}

	queryResults["A"] = queryRes
	return queryResults, nil
}
<|endoftext|>


<commit_before>package client

import (
    "time"
    "net/http"
    "io"
    "net/http/cookiejar"
)

type Requester interface {
    NewRequest(method, endpoint string, body io.Reader) (*http.Request)
    Do(req *http.Request) (*http.Response, error)
    Request(method, endpoint string, body io.Reader, jar http.CookieJar) (*http.Response, error)
    SimpleRequest(method, endpoint string, body io.Reader, jar http.CookieJar) (code int, response *ResponseBody, err Error)
}

type requester struct {
    target string
    client *http.Client
}

func newRequester(target string, cookies  []*http.Cookie) (Requester, Error) {
    var jar, err = cookiejar.New(nil)
    if err != nil {
        return nil, newFatal(err)
    }

    if cookies != nil {
        jar.SetCookies(target, cookies)
    }

    return &requester{
        target:target,
        client: &http.Client{
            Transport: &http.Transport{
                TLSHandshakeTimeout:15 * time.Second,
                ResponseHeaderTimeout:30 * time.Second,
                MaxIdleConnsPerHost: 1000,
                MaxIdleConns: 4096,
                MaxResponseHeaderBytes: 1024,
                IdleConnTimeout: 2 * time.Minute,
                ExpectContinueTimeout: 30 * time.Second,
            },
            Timeout: 100 * time.Second,
            Jar: jar,
        },
    }, nil
}

func (r *requester) NewRequest(method, endpoint string, body io.Reader) (*http.Request, Error) {
    path := r.target + endpoint
    if req, err := http.NewRequest(method, path, body); err != nil {
        return newFatal(err)
    } else {
        if body != nil {
            req.Header.Set("Content-Type", "application/json")
        }
        return req
    }
}

func (r *requester) Do(req *http.Request) (*http.Response, Error) {
    resp, err := r.client.Do(req);
    return resp, newError(err)
}

func (r *requester) Request(method, endpoint string, body io.Reader) (*http.Response, Error) {
    if req, err := r.NewRequest(method, endpoint, body); err != nil {
        return nil, err
    } else {
        return r.Do(req)
    }
}

func (r *requester) SimpleRequest(method, endpoint string, body io.Reader) (int, *ResponseBody, Error) {
    if req, err := r.NewRequest(method, endpoint, body); err != nil {
        return nil, err
    } else if resp, err := r.Do(req); err != nil {
        return 0, nil, err
    } else if body, err := ReadResponseBody(resp.Body); err != nil {
        return 0, nil, err
    } else {
        return resp.StatusCode, body, nil
    }
}
<commit_msg>Additional Requester interface correction<commit_after>package client

import (
    "time"
    "net/http"
    "io"
    "net/http/cookiejar"
)

type Requester interface {
    NewRequest(method, endpoint string, body io.Reader) (*http.Request)
    Do(req *http.Request) (*http.Response, error)
    Request(method, endpoint string, body io.Reader) (*http.Response, error)
    SimpleRequest(method, endpoint string, body io.Reader) (code int, response *ResponseBody, err Error)
}

type requester struct {
    target string
    client *http.Client
}

func newRequester(target string, cookies  []*http.Cookie) (Requester, Error) {
    var jar, err = cookiejar.New(nil)
    if err != nil {
        return nil, newFatal(err)
    }

    if cookies != nil {
        jar.SetCookies(target, cookies)
    }

    return &requester{
        target:target,
        client: &http.Client{
            Transport: &http.Transport{
                TLSHandshakeTimeout:15 * time.Second,
                ResponseHeaderTimeout:30 * time.Second,
                MaxIdleConnsPerHost: 1000,
                MaxIdleConns: 4096,
                MaxResponseHeaderBytes: 1024,
                IdleConnTimeout: 2 * time.Minute,
                ExpectContinueTimeout: 30 * time.Second,
            },
            Timeout: 100 * time.Second,
            Jar: jar,
        },
    }, nil
}

func (r *requester) NewRequest(method, endpoint string, body io.Reader) (*http.Request, Error) {
    path := r.target + endpoint
    if req, err := http.NewRequest(method, path, body); err != nil {
        return newFatal(err)
    } else {
        if body != nil {
            req.Header.Set("Content-Type", "application/json")
        }
        return req
    }
}

func (r *requester) Do(req *http.Request) (*http.Response, Error) {
    resp, err := r.client.Do(req);
    return resp, newError(err)
}

func (r *requester) Request(method, endpoint string, body io.Reader) (*http.Response, Error) {
    if req, err := r.NewRequest(method, endpoint, body); err != nil {
        return nil, err
    } else {
        return r.Do(req)
    }
}

func (r *requester) SimpleRequest(method, endpoint string, body io.Reader) (int, *ResponseBody, Error) {
    if req, err := r.NewRequest(method, endpoint, body); err != nil {
        return nil, err
    } else if resp, err := r.Do(req); err != nil {
        return 0, nil, err
    } else if body, err := ReadResponseBody(resp.Body); err != nil {
        return 0, nil, err
    } else {
        return resp.StatusCode, body, nil
    }
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/peteretelej/saf"
)

func main() {
	b, err := saf.GetBundles()
	if err != nil {
		fmt.Printf("Failed to get bundles: %v\n", err)
		return
	}
	b.PrettyPrint()

}
<commit_msg>Add exit status to error exit<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/peteretelej/saf"
)

func main() {
	b, err := saf.GetBundles()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to get bundles: %v\n", err)
		os.Exit(1)
	}
	b.PrettyPrint()

}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
	log "github.com/sirupsen/logrus"
	utilclock "k8s.io/apimachinery/pkg/util/clock"
	k8sscheme "k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/tools/clientcmd"

	"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalogtemplate"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/server"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/metrics"
	olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version"
)

const (
	catalogNamespaceEnvVarName  = "GLOBAL_CATALOG_NAMESPACE"
	defaultWakeupInterval       = 15 * time.Minute
	defaultCatalogNamespace     = "openshift-operator-lifecycle-manager"
	defaultConfigMapServerImage = "quay.io/operator-framework/configmap-operator-registry:latest"
	defaultOPMImage             = "quay.io/operator-framework/upstream-opm-builder:latest"
	defaultUtilImage            = "quay.io/operator-framework/olm:latest"
	defaultOperatorName         = ""
)

// config flags defined globally so that they appear on the test binary as well
var (
	kubeConfigPath = flag.String(
		"kubeconfig", "", "absolute path to the kubeconfig file")

	wakeupInterval = flag.Duration(
		"interval", defaultWakeupInterval, "wakeup interval")

	catalogNamespace = flag.String(
		"namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources")

	configmapServerImage = flag.String(
		"configmapServerImage", defaultConfigMapServerImage, "the image to use for serving the operator registry api for a configmap")

	opmImage = flag.String(
		"opmImage", defaultOPMImage, "the image to use for unpacking bundle content with opm")

	utilImage = flag.String(
		"util-image", defaultUtilImage, "an image containing custom olm utilities")

	writeStatusName = flag.String(
		"writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.")

	debug = flag.Bool(
		"debug", false, "use debug log level")

	version = flag.Bool("version", false, "displays olm version")

	tlsKeyPath = flag.String(
		"tls-key", "", "Path to use for private key (requires tls-cert)")

	tlsCertPath = flag.String(
		"tls-cert", "", "Path to use for certificate key (requires tls-key)")

	profiling = flag.Bool("profiling", false, "deprecated")

	clientCAPath = flag.String("client-ca", "", "path to watch for client ca bundle")

	installPlanTimeout  = flag.Duration("install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
	bundleUnpackTimeout = flag.Duration("bundle-unpack-timeout", 10*time.Minute, "The time limit for bundle unpacking, after which InstallPlan execution is considered to have failed. 0 is considered as having no timeout.")
)

func init() {
	metrics.RegisterCatalog()
}

func main() {
	// Get exit signal context
	ctx, cancel := context.WithCancel(signals.Context())
	defer cancel()

	// Parse the command-line flags.
	flag.Parse()

	// Check if version flag was set
	if *version {
		fmt.Print(olmversion.String())

		// Exit early
		os.Exit(0)
	}

	logger := log.New()
	if *debug {
		logger.SetLevel(log.DebugLevel)
	}
	logger.Infof("log level %s", logger.Level)

	// If the catalogNamespaceEnvVarName environment variable is set, then  update the value of catalogNamespace.
	if catalogNamespaceEnvVarValue := os.Getenv(catalogNamespaceEnvVarName); catalogNamespaceEnvVarValue != "" {
		logger.Infof("%s environment variable is set. Updating Global Catalog Namespace to %s", catalogNamespaceEnvVarName, catalogNamespaceEnvVarValue)
		*catalogNamespace = catalogNamespaceEnvVarValue
	}

	listenAndServe, err := server.GetListenAndServeFunc(logger, tlsCertPath, tlsKeyPath, clientCAPath)
	if err != nil {
		logger.Fatal("Error setting up health/metric/pprof service: %v", err)
	}

	go func() {
		if err := listenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.Error(err)
		}
	}()

	// create a config client for operator status
	config, err := clientcmd.BuildConfigFromFlags("", *kubeConfigPath)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}
	configClient, err := configv1client.NewForConfig(config)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}
	opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger)
	crClient, err := client.NewClient(*kubeConfigPath)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}

	// Create a new instance of the operator.
	op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *opmImage, *utilImage, *catalogNamespace, k8sscheme.Scheme, *installPlanTimeout, *bundleUnpackTimeout)
	if err != nil {
		log.Panicf("error configuring catalog operator: %s", err.Error())
	}

	opCatalogTemplate, err := catalogtemplate.NewOperator(ctx, *kubeConfigPath, logger, *wakeupInterval, *catalogNamespace)
	if err != nil {
		log.Panicf("error configuring catalog template operator: %s", err.Error())
	}

	op.Run(ctx)
	<-op.Ready()

	opCatalogTemplate.Run(ctx)
	<-opCatalogTemplate.Ready()

	if *writeStatusName != "" {
		operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), op.Done(), opClient, configClient, crClient)
	}

	<-op.Done()
}
<commit_msg>Update default catalog namespace (#2371)<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
	log "github.com/sirupsen/logrus"
	utilclock "k8s.io/apimachinery/pkg/util/clock"
	k8sscheme "k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/tools/clientcmd"

	"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalogtemplate"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/server"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals"
	"github.com/operator-framework/operator-lifecycle-manager/pkg/metrics"
	olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version"
)

const (
	catalogNamespaceEnvVarName  = "GLOBAL_CATALOG_NAMESPACE"
	defaultWakeupInterval       = 15 * time.Minute
	defaultCatalogNamespace     = "olm"
	defaultConfigMapServerImage = "quay.io/operator-framework/configmap-operator-registry:latest"
	defaultOPMImage             = "quay.io/operator-framework/upstream-opm-builder:latest"
	defaultUtilImage            = "quay.io/operator-framework/olm:latest"
	defaultOperatorName         = ""
)

// config flags defined globally so that they appear on the test binary as well
var (
	kubeConfigPath = flag.String(
		"kubeconfig", "", "absolute path to the kubeconfig file")

	wakeupInterval = flag.Duration(
		"interval", defaultWakeupInterval, "wakeup interval")

	catalogNamespace = flag.String(
		"namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources")

	configmapServerImage = flag.String(
		"configmapServerImage", defaultConfigMapServerImage, "the image to use for serving the operator registry api for a configmap")

	opmImage = flag.String(
		"opmImage", defaultOPMImage, "the image to use for unpacking bundle content with opm")

	utilImage = flag.String(
		"util-image", defaultUtilImage, "an image containing custom olm utilities")

	writeStatusName = flag.String(
		"writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.")

	debug = flag.Bool(
		"debug", false, "use debug log level")

	version = flag.Bool("version", false, "displays olm version")

	tlsKeyPath = flag.String(
		"tls-key", "", "Path to use for private key (requires tls-cert)")

	tlsCertPath = flag.String(
		"tls-cert", "", "Path to use for certificate key (requires tls-key)")

	profiling = flag.Bool("profiling", false, "deprecated")

	clientCAPath = flag.String("client-ca", "", "path to watch for client ca bundle")

	installPlanTimeout  = flag.Duration("install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
	bundleUnpackTimeout = flag.Duration("bundle-unpack-timeout", 10*time.Minute, "The time limit for bundle unpacking, after which InstallPlan execution is considered to have failed. 0 is considered as having no timeout.")
)

func init() {
	metrics.RegisterCatalog()
}

func main() {
	// Get exit signal context
	ctx, cancel := context.WithCancel(signals.Context())
	defer cancel()

	// Parse the command-line flags.
	flag.Parse()

	// Check if version flag was set
	if *version {
		fmt.Print(olmversion.String())

		// Exit early
		os.Exit(0)
	}

	logger := log.New()
	if *debug {
		logger.SetLevel(log.DebugLevel)
	}
	logger.Infof("log level %s", logger.Level)

	// If the catalogNamespaceEnvVarName environment variable is set, then  update the value of catalogNamespace.
	if catalogNamespaceEnvVarValue := os.Getenv(catalogNamespaceEnvVarName); catalogNamespaceEnvVarValue != "" {
		logger.Infof("%s environment variable is set. Updating Global Catalog Namespace to %s", catalogNamespaceEnvVarName, catalogNamespaceEnvVarValue)
		*catalogNamespace = catalogNamespaceEnvVarValue
	}

	listenAndServe, err := server.GetListenAndServeFunc(logger, tlsCertPath, tlsKeyPath, clientCAPath)
	if err != nil {
		logger.Fatal("Error setting up health/metric/pprof service: %v", err)
	}

	go func() {
		if err := listenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.Error(err)
		}
	}()

	// create a config client for operator status
	config, err := clientcmd.BuildConfigFromFlags("", *kubeConfigPath)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}
	configClient, err := configv1client.NewForConfig(config)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}
	opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger)
	crClient, err := client.NewClient(*kubeConfigPath)
	if err != nil {
		log.Fatalf("error configuring client: %s", err.Error())
	}

	// Create a new instance of the operator.
	op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *opmImage, *utilImage, *catalogNamespace, k8sscheme.Scheme, *installPlanTimeout, *bundleUnpackTimeout)
	if err != nil {
		log.Panicf("error configuring catalog operator: %s", err.Error())
	}

	opCatalogTemplate, err := catalogtemplate.NewOperator(ctx, *kubeConfigPath, logger, *wakeupInterval, *catalogNamespace)
	if err != nil {
		log.Panicf("error configuring catalog template operator: %s", err.Error())
	}

	op.Run(ctx)
	<-op.Ready()

	opCatalogTemplate.Run(ctx)
	<-opCatalogTemplate.Ready()

	if *writeStatusName != "" {
		operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), op.Done(), opClient, configClient, crClient)
	}

	<-op.Done()
}
<|endoftext|>