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

package network

import (
	"sort"
	"strconv"

	"github.com/juju/utils/set"
)

// PortSet is a set-like container of Port values.
type PortSet struct {
	values map[string]set.Ints
}

// NewPortSet creates a map of protocols to sets of stringified port numbers.
func NewPortSet(portRanges ...PortRange) PortSet {
	var result PortSet
	result.values = make(map[string]set.Ints)
	result.AddRanges(portRanges...)
	return result
}

// Size returns the number of ports in the set.
func (ps PortSet) Size() int {
	size := 0
	for _, ports := range ps.values {
		size += len(ports)
	}
	return size
}

// IsEmpty returns true if the PortSet is empty.
func (ps PortSet) IsEmpty() bool {
	return len(ps.values) == 0
}

// Values returns a list of all the ports in the set.
func (ps PortSet) Values() []Port {
	return ps.Ports()
}

// Protocols returns a list of protocols known to the PortSet.
func (ps PortSet) Protocols() []string {
	var result []string
	for key := range ps.values {
		result = append(result, key)
	}
	return result
}

// PortRanges returns a list of all the port ranges in the set for the
// given protocols. If no protocols are provided all known protocols in
// the set are used.
func (ps PortSet) PortRanges(protocols ...string) []PortRange {
	if len(protocols) == 0 {
		protocols = ps.Protocols()
	}

	var result []PortRange
	for _, protocol := range protocols {
		ranges := collapsePorts(protocol, ps.PortNumbers(protocol)...)
		result = append(result, ranges...)
	}
	return result
}

func collapsePorts(protocol string, ports ...int) (result []PortRange) {
	if len(ports) == 0 {
		return nil
	}

	sort.Ints(ports)

	fromPort := 0
	toPort := 0
	for _, port := range ports {
		if fromPort == 0 {
			// new port range
			fromPort = port
			toPort = port
		} else if port == toPort+1 {
			// continuing port range
			toPort = port
		} else {
			// break in port range
			result = append(result,
				PortRange{
					Protocol: protocol,
					FromPort: fromPort,
					ToPort:   toPort,
				})
			fromPort = port
			toPort = port
		}
	}
	result = append(result, PortRange{
		Protocol: protocol,
		FromPort: fromPort,
		ToPort:   toPort,
	})
	return
}

// PortNumbers returns a list of all the port numbers in the set for
// the given protocol.
func (ps PortSet) Ports(protocols ...string) []Port {
	if len(protocols) == 0 {
		protocols = ps.Protocols()
	}

	var results []Port
	for _, portRange := range ps.PortRanges(protocols...) {
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			results = append(results, Port{portRange.Protocol, p})
		}
	}
	return results
}

// PortNumbers returns a list of all the port numbers in the set for
// the given protocol.
func (ps PortSet) PortNumbers(protocol string) []int {
	ports, ok := ps.values[protocol]
	if !ok {
		return nil
	}
	return ports.Values()
}

// PortStrings returns a list of stringified ports in the set
// for the given protocol.
func (ps PortSet) PortStrings(protocol string) []string {
	ports, ok := ps.values[protocol]
	if !ok {
		return nil
	}
	var result []string
	for _, port := range ports.Values() {
		portStr := strconv.Itoa(port)
		result = append(result, portStr)
	}
	return result
}

// Add adds a port to the PortSet.
func (ps *PortSet) Add(protocol string, port int) {
	if ps.values == nil {
		panic("uninitalised set")
	}
	ports, ok := ps.values[protocol]
	if !ok {
		ps.values[protocol] = set.NewInts(port)
	} else {
		ports.Add(port)
	}
}

// AddRanges adds port ranges to the PortSet.
func (ps *PortSet) AddRanges(portRanges ...PortRange) {
	for _, portRange := range portRanges {
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			ps.Add(portRange.Protocol, p)
		}
	}
}

// Remove removes the given port from the set.
func (ps *PortSet) Remove(protocol string, port int) {
	ports, ok := ps.values[protocol]
	if ok {
		ports.Remove(port)
	}
}

// RemoveRanges removes all ports in the given PortRange values
// from the set.
func (ps *PortSet) RemoveRanges(portRanges ...PortRange) {
	for _, portRange := range portRanges {
		_, ok := ps.values[portRange.Protocol]
		if ok {
			for p := portRange.FromPort; p <= portRange.ToPort; p++ {
				ps.Remove(portRange.Protocol, p)
			}
		}
	}
}

// Contains returns true if the provided port is in the set.
func (ps *PortSet) Contains(protocol string, port int) bool {
	ports, ok := ps.values[protocol]
	if !ok {
		return false
	}
	return ports.Contains(port)
}

// ContainsRanges returns true if the provided port ranges are
// in the set.
func (ps *PortSet) ContainsRanges(portRanges ...PortRange) bool {
	for _, portRange := range portRanges {
		ports, ok := ps.values[portRange.Protocol]
		if !ok {
			return false
		}
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			if !ports.Contains(p) {
				return false
			}
		}
	}
	return true
}

// Union returns a new PortSet of the shared values
// that are common between both PortSets.
func (ps PortSet) Union(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		result.values[protocol] = value.Union(nil)
	}
	for protocol, value := range other.values {
		ports, ok := result.values[protocol]
		if !ok {
			value = nil
		}
		result.values[protocol] = ports.Union(value)
	}
	return result
}

// Intersection returns a new PortSet of the values that are in both
// this set and the other, but not in just one of either.
func (ps PortSet) Intersection(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		ports, ok := other.values[protocol]
		if ok {
			result.values[protocol] = value.Intersection(ports)
		}
	}
	return result
}

// Difference returns a new PortSet of the values
// that are not in the other PortSet.
func (ps PortSet) Difference(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		ports, ok := other.values[protocol]
		if !ok {
			result.values[protocol] = value
		} else {
			result.values[protocol] = value.Difference(ports)
		}
	}
	return result
}
<commit_msg>Clean up some formatting.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package network

import (
	"sort"
	"strconv"

	"github.com/juju/utils/set"
)

// PortSet is a set-like container of Port values.
type PortSet struct {
	values map[string]set.Ints
}

// NewPortSet creates a map of protocols to sets of stringified port numbers.
func NewPortSet(portRanges ...PortRange) PortSet {
	var result PortSet
	result.values = make(map[string]set.Ints)
	result.AddRanges(portRanges...)
	return result
}

// Size returns the number of ports in the set.
func (ps PortSet) Size() int {
	size := 0
	for _, ports := range ps.values {
		size += len(ports)
	}
	return size
}

// IsEmpty returns true if the PortSet is empty.
func (ps PortSet) IsEmpty() bool {
	return len(ps.values) == 0
}

// Values returns a list of all the ports in the set.
func (ps PortSet) Values() []Port {
	return ps.Ports()
}

// Protocols returns a list of protocols known to the PortSet.
func (ps PortSet) Protocols() []string {
	var result []string
	for key := range ps.values {
		result = append(result, key)
	}
	return result
}

// PortRanges returns a list of all the port ranges in the set for the
// given protocols. If no protocols are provided all known protocols in
// the set are used.
func (ps PortSet) PortRanges(protocols ...string) []PortRange {
	if len(protocols) == 0 {
		protocols = ps.Protocols()
	}

	var result []PortRange
	for _, protocol := range protocols {
		ranges := collapsePorts(protocol, ps.PortNumbers(protocol)...)
		result = append(result, ranges...)
	}
	return result
}

func collapsePorts(protocol string, ports ...int) (result []PortRange) {
	if len(ports) == 0 {
		return nil
	}

	sort.Ints(ports)

	fromPort := 0
	toPort := 0
	for _, port := range ports {
		if fromPort == 0 {
			// new port range
			fromPort = port
			toPort = port
		} else if port == toPort+1 {
			// continuing port range
			toPort = port
		} else {
			// break in port range
			result = append(result, PortRange{
				Protocol: protocol,
				FromPort: fromPort,
				ToPort:   toPort,
			})
			fromPort = port
			toPort = port
		}
	}
	result = append(result, PortRange{
		Protocol: protocol,
		FromPort: fromPort,
		ToPort:   toPort,
	})
	return
}

// PortNumbers returns a list of all the port numbers in the set for
// the given protocol.
func (ps PortSet) Ports(protocols ...string) []Port {
	if len(protocols) == 0 {
		protocols = ps.Protocols()
	}

	var results []Port
	for _, portRange := range ps.PortRanges(protocols...) {
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			results = append(results, Port{portRange.Protocol, p})
		}
	}
	return results
}

// PortNumbers returns a list of all the port numbers in the set for
// the given protocol.
func (ps PortSet) PortNumbers(protocol string) []int {
	ports, ok := ps.values[protocol]
	if !ok {
		return nil
	}
	return ports.Values()
}

// PortStrings returns a list of stringified ports in the set
// for the given protocol.
func (ps PortSet) PortStrings(protocol string) []string {
	ports, ok := ps.values[protocol]
	if !ok {
		return nil
	}
	var result []string
	for _, port := range ports.Values() {
		portStr := strconv.Itoa(port)
		result = append(result, portStr)
	}
	return result
}

// Add adds a port to the PortSet.
func (ps *PortSet) Add(protocol string, port int) {
	if ps.values == nil {
		panic("uninitalised set")
	}
	ports, ok := ps.values[protocol]
	if !ok {
		ps.values[protocol] = set.NewInts(port)
	} else {
		ports.Add(port)
	}
}

// AddRanges adds port ranges to the PortSet.
func (ps *PortSet) AddRanges(portRanges ...PortRange) {
	for _, portRange := range portRanges {
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			ps.Add(portRange.Protocol, p)
		}
	}
}

// Remove removes the given port from the set.
func (ps *PortSet) Remove(protocol string, port int) {
	ports, ok := ps.values[protocol]
	if ok {
		ports.Remove(port)
	}
}

// RemoveRanges removes all ports in the given PortRange values
// from the set.
func (ps *PortSet) RemoveRanges(portRanges ...PortRange) {
	for _, portRange := range portRanges {
		_, ok := ps.values[portRange.Protocol]
		if ok {
			for p := portRange.FromPort; p <= portRange.ToPort; p++ {
				ps.Remove(portRange.Protocol, p)
			}
		}
	}
}

// Contains returns true if the provided port is in the set.
func (ps *PortSet) Contains(protocol string, port int) bool {
	ports, ok := ps.values[protocol]
	if !ok {
		return false
	}
	return ports.Contains(port)
}

// ContainsRanges returns true if the provided port ranges are
// in the set.
func (ps *PortSet) ContainsRanges(portRanges ...PortRange) bool {
	for _, portRange := range portRanges {
		ports, ok := ps.values[portRange.Protocol]
		if !ok {
			return false
		}
		for p := portRange.FromPort; p <= portRange.ToPort; p++ {
			if !ports.Contains(p) {
				return false
			}
		}
	}
	return true
}

// Union returns a new PortSet of the shared values
// that are common between both PortSets.
func (ps PortSet) Union(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		result.values[protocol] = value.Union(nil)
	}
	for protocol, value := range other.values {
		ports, ok := result.values[protocol]
		if !ok {
			value = nil
		}
		result.values[protocol] = ports.Union(value)
	}
	return result
}

// Intersection returns a new PortSet of the values that are in both
// this set and the other, but not in just one of either.
func (ps PortSet) Intersection(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		ports, ok := other.values[protocol]
		if ok {
			result.values[protocol] = value.Intersection(ports)
		}
	}
	return result
}

// Difference returns a new PortSet of the values
// that are not in the other PortSet.
func (ps PortSet) Difference(other PortSet) PortSet {
	result := NewPortSet()
	for protocol, value := range ps.values {
		ports, ok := other.values[protocol]
		if !ok {
			result.values[protocol] = value
		} else {
			result.values[protocol] = value.Difference(ports)
		}
	}
	return result
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"time"

	"net/http"
	_ "net/http/pprof"

	"github.com/Sirupsen/logrus"
	"github.com/deshboard/boilerplate-grpc-service/app"
	"github.com/evalphobia/logrus_fluent"
	"github.com/kelseyhightower/envconfig"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/sagikazarmark/serverz"
	"golang.org/x/net/trace"
	"google.golang.org/grpc/grpclog"
	"gopkg.in/airbrake/gobrake.v2"
	logrus_airbrake "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
)

// Global context variables
var (
	config   = &app.Configuration{}
	logger   = logrus.New().WithField("service", app.ServiceName) // Use logrus.FieldLogger type
	tracer   = opentracing.GlobalTracer()
	shutdown = serverz.NewShutdown(logger)
)

func init() {
	// Register shutdown handler in logrus
	logrus.RegisterExitHandler(shutdown.Handle)

	// Set global gRPC logger
	grpclog.SetLogger(logger)

	// Load configuration from environment
	err := envconfig.Process("app", config)
	if err != nil {
		logger.Fatal(err)
	}

	defaultAddr := ""

	// Listen on loopback interface in development mode
	if config.Environment == "development" {
		defaultAddr = "127.0.0.1"
	}

	// Load flags into configuration
	flag.StringVar(&config.ServiceAddr, "service", defaultAddr+":80", "Service address.")
	flag.StringVar(&config.HealthAddr, "health", defaultAddr+":10000", "Health service address.")
	flag.StringVar(&config.DebugAddr, "debug", defaultAddr+":10001", "Debug service address.")
	flag.DurationVar(&config.ShutdownTimeout, "shutdown", 2*time.Second, "Shutdown timeout.")

	// This is probably OK as the service runs in Docker
	trace.AuthRequest = func(req *http.Request) (any, sensitive bool) {
		return true, true
	}

	// Initialize Airbrake
	if config.AirbrakeEnabled {
		airbrakeHook := logrus_airbrake.NewHook(config.AirbrakeProjectID, config.AirbrakeAPIKey, config.Environment)
		airbrake := airbrakeHook.Airbrake

		airbrake.SetHost(config.AirbrakeEndpoint)

		airbrake.AddFilter(func(notice *gobrake.Notice) *gobrake.Notice {
			notice.Context["version"] = app.Version
			notice.Context["commit"] = app.CommitHash

			return notice
		})

		logger.Logger.Hooks.Add(airbrakeHook)
		shutdown.Register(airbrake.Close)
	}

	// Initialize Fluentd
	if config.FluentdEnabled {
		fluentdHook, err := logrus_fluent.New(config.FluentdHost, config.FluentdPort)
		if err != nil {
			logger.Panic(err)
		}

		fluentdHook.SetTag(app.ServiceName)
		fluentdHook.AddFilter("error", logrus_fluent.FilterError)

		logger.Logger.Hooks.Add(fluentdHook)
		shutdown.Register(fluentdHook.Fluent.Close)
	}
}
<commit_msg>Add server field for grpc logger<commit_after>package main

import (
	"flag"
	"time"

	"net/http"
	_ "net/http/pprof"

	"github.com/Sirupsen/logrus"
	"github.com/deshboard/boilerplate-grpc-service/app"
	"github.com/evalphobia/logrus_fluent"
	"github.com/kelseyhightower/envconfig"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/sagikazarmark/serverz"
	"golang.org/x/net/trace"
	"google.golang.org/grpc/grpclog"
	"gopkg.in/airbrake/gobrake.v2"
	logrus_airbrake "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
)

// Global context variables
var (
	config   = &app.Configuration{}
	logger   = logrus.New().WithField("service", app.ServiceName) // Use logrus.FieldLogger type
	tracer   = opentracing.GlobalTracer()
	shutdown = serverz.NewShutdown(logger)
)

func init() {
	// Register shutdown handler in logrus
	logrus.RegisterExitHandler(shutdown.Handle)

	// Set global gRPC logger
	grpclog.SetLogger(logger.WithField("server", "grpc"))

	// Load configuration from environment
	err := envconfig.Process("app", config)
	if err != nil {
		logger.Fatal(err)
	}

	defaultAddr := ""

	// Listen on loopback interface in development mode
	if config.Environment == "development" {
		defaultAddr = "127.0.0.1"
	}

	// Load flags into configuration
	flag.StringVar(&config.ServiceAddr, "service", defaultAddr+":80", "Service address.")
	flag.StringVar(&config.HealthAddr, "health", defaultAddr+":10000", "Health service address.")
	flag.StringVar(&config.DebugAddr, "debug", defaultAddr+":10001", "Debug service address.")
	flag.DurationVar(&config.ShutdownTimeout, "shutdown", 2*time.Second, "Shutdown timeout.")

	// This is probably OK as the service runs in Docker
	trace.AuthRequest = func(req *http.Request) (any, sensitive bool) {
		return true, true
	}

	// Initialize Airbrake
	if config.AirbrakeEnabled {
		airbrakeHook := logrus_airbrake.NewHook(config.AirbrakeProjectID, config.AirbrakeAPIKey, config.Environment)
		airbrake := airbrakeHook.Airbrake

		airbrake.SetHost(config.AirbrakeEndpoint)

		airbrake.AddFilter(func(notice *gobrake.Notice) *gobrake.Notice {
			notice.Context["version"] = app.Version
			notice.Context["commit"] = app.CommitHash

			return notice
		})

		logger.Logger.Hooks.Add(airbrakeHook)
		shutdown.Register(airbrake.Close)
	}

	// Initialize Fluentd
	if config.FluentdEnabled {
		fluentdHook, err := logrus_fluent.New(config.FluentdHost, config.FluentdPort)
		if err != nil {
			logger.Panic(err)
		}

		fluentdHook.SetTag(app.ServiceName)
		fluentdHook.AddFilter("error", logrus_fluent.FilterError)

		logger.Logger.Hooks.Add(fluentdHook)
		shutdown.Register(fluentdHook.Fluent.Close)
	}
}
<|endoftext|>


<commit_before>package tfdiags

import (
	"github.com/hashicorp/hcl2/hcl"
)

// hclDiagnostic is a Diagnostic implementation that wraps a HCL Diagnostic
type hclDiagnostic struct {
	diag *hcl.Diagnostic
}

var _ Diagnostic = hclDiagnostic{}

func (d hclDiagnostic) Severity() Severity {
	switch d.diag.Severity {
	case hcl.DiagWarning:
		return Warning
	default:
		return Error
	}
}

func (d hclDiagnostic) Description() Description {
	return Description{
		Summary: d.diag.Summary,
		Detail:  d.diag.Detail,
	}
}

func (d hclDiagnostic) Source() Source {
	var ret Source
	if d.diag.Subject != nil {
		ret.Subject = &SourceRange{
			Filename: d.diag.Subject.Filename,
			Start: SourcePos{
				Line:   d.diag.Subject.Start.Line,
				Column: d.diag.Subject.Start.Column,
				Byte:   d.diag.Subject.Start.Byte,
			},
			End: SourcePos{
				Line:   d.diag.Subject.End.Line,
				Column: d.diag.Subject.End.Column,
				Byte:   d.diag.Subject.End.Byte,
			},
		}
	}
	if d.diag.Context != nil {
		ret.Context = &SourceRange{
			Filename: d.diag.Context.Filename,
			Start: SourcePos{
				Line:   d.diag.Context.Start.Line,
				Column: d.diag.Context.Start.Column,
				Byte:   d.diag.Context.Start.Byte,
			},
			End: SourcePos{
				Line:   d.diag.Context.End.Line,
				Column: d.diag.Context.End.Column,
				Byte:   d.diag.Context.End.Byte,
			},
		}
	}
	return ret
}
<commit_msg>tfdiags: Helper to construct SourceRange from hcl.Range<commit_after>package tfdiags

import (
	"github.com/hashicorp/hcl2/hcl"
)

// hclDiagnostic is a Diagnostic implementation that wraps a HCL Diagnostic
type hclDiagnostic struct {
	diag *hcl.Diagnostic
}

var _ Diagnostic = hclDiagnostic{}

func (d hclDiagnostic) Severity() Severity {
	switch d.diag.Severity {
	case hcl.DiagWarning:
		return Warning
	default:
		return Error
	}
}

func (d hclDiagnostic) Description() Description {
	return Description{
		Summary: d.diag.Summary,
		Detail:  d.diag.Detail,
	}
}

func (d hclDiagnostic) Source() Source {
	var ret Source
	if d.diag.Subject != nil {
		rng := SourceRangeFromHCL(*d.diag.Subject)
		ret.Subject = &rng
	}
	if d.diag.Context != nil {
		rng := SourceRangeFromHCL(*d.diag.Context)
		ret.Context = &rng
	}
	return ret
}

// SourceRangeFromHCL constructs a SourceRange from the corresponding range
// type within the HCL package.
func SourceRangeFromHCL(hclRange hcl.Range) SourceRange {
	return SourceRange{
		Filename: hclRange.Filename,
		Start: SourcePos{
			Line:   hclRange.Start.Line,
			Column: hclRange.Start.Column,
			Byte:   hclRange.Start.Byte,
		},
		End: SourcePos{
			Line:   hclRange.End.Line,
			Column: hclRange.End.Column,
			Byte:   hclRange.End.Byte,
		},
	}
}

// ToHCL constructs a HCL Range from the receiving SourceRange. This is the
// opposite of SourceRangeFromHCL.
func (r SourceRange) ToHCL() hcl.Range {
	return hcl.Range{
		Filename: r.Filename,
		Start: hcl.Pos{
			Line:   r.Start.Line,
			Column: r.Start.Column,
			Byte:   r.Start.Byte,
		},
		End: hcl.Pos{
			Line:   r.End.Line,
			Column: r.End.Column,
			Byte:   r.End.Byte,
		},
	}
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/gosimple/slug"
	"github.com/grafana/grafana/pkg/components/simplejson"
	"github.com/grafana/grafana/pkg/setting"
)

// Typed errors
var (
	ErrDashboardNotFound                         = errors.New("Dashboard not found")
	ErrDashboardFolderNotFound                   = errors.New("Folder not found")
	ErrDashboardSnapshotNotFound                 = errors.New("Dashboard snapshot not found")
	ErrDashboardWithSameUIDExists                = errors.New("A dashboard with the same uid already exists")
	ErrDashboardWithSameNameInFolderExists       = errors.New("A dashboard with the same name in the folder already exists")
	ErrDashboardVersionMismatch                  = errors.New("The dashboard has been changed by someone else")
	ErrDashboardTitleEmpty                       = errors.New("Dashboard title cannot be empty")
	ErrDashboardFolderCannotHaveParent           = errors.New("A Dashboard Folder cannot be added to another folder")
	ErrDashboardsWithSameSlugExists              = errors.New("Multiple dashboards with the same slug exists")
	ErrDashboardFailedGenerateUniqueUid          = errors.New("Failed to generate unique dashboard id")
	ErrDashboardTypeMismatch                     = errors.New("Dashboard cannot be changed to a folder")
	ErrDashboardFolderWithSameNameAsDashboard    = errors.New("Folder name cannot be the same as one of its dashboards")
	ErrDashboardWithSameNameAsFolder             = errors.New("Dashboard name cannot be the same as folder")
	ErrDashboardFolderNameExists                 = errors.New("A folder with that name already exists")
	ErrDashboardUpdateAccessDenied               = errors.New("Access denied to save dashboard")
	ErrDashboardInvalidUid                       = errors.New("uid contains illegal characters")
	ErrDashboardUidToLong                        = errors.New("uid to long. max 40 characters")
	ErrDashboardCannotSaveProvisionedDashboard   = errors.New("Cannot save provisioned dashboard")
	ErrDashboardRefreshIntervalTooShort          = errors.New("Dashboard refresh interval is too low")
	ErrDashboardCannotDeleteProvisionedDashboard = errors.New("provisioned dashboard cannot be deleted")
	ErrDashboardIdentifierNotSet                 = errors.New("Unique identfier needed to be able to get a dashboard")
	RootFolderName                               = "General"
)

type UpdatePluginDashboardError struct {
	PluginId string
}

func (d UpdatePluginDashboardError) Error() string {
	return "Dashboard belong to plugin"
}

var (
	DashTypeJson     = "file"
	DashTypeDB       = "db"
	DashTypeScript   = "script"
	DashTypeSnapshot = "snapshot"
)

// Dashboard model
type Dashboard struct {
	Id       int64
	Uid      string
	Slug     string
	OrgId    int64
	GnetId   int64
	Version  int
	PluginId string

	Created time.Time
	Updated time.Time

	UpdatedBy int64
	CreatedBy int64
	FolderId  int64
	IsFolder  bool
	HasAcl    bool

	Title string
	Data  *simplejson.Json
}

func (d *Dashboard) SetId(id int64) {
	d.Id = id
	d.Data.Set("id", id)
}

func (d *Dashboard) SetUid(uid string) {
	d.Uid = uid
	d.Data.Set("uid", uid)
}

func (d *Dashboard) SetVersion(version int) {
	d.Version = version
	d.Data.Set("version", version)
}

// GetDashboardIdForSavePermissionCheck return the dashboard id to be used for checking permission of dashboard
func (d *Dashboard) GetDashboardIdForSavePermissionCheck() int64 {
	if d.Id == 0 {
		return d.FolderId
	}

	return d.Id
}

// NewDashboard creates a new dashboard
func NewDashboard(title string) *Dashboard {
	dash := &Dashboard{}
	dash.Data = simplejson.New()
	dash.Data.Set("title", title)
	dash.Title = title
	dash.Created = time.Now()
	dash.Updated = time.Now()
	dash.UpdateSlug()
	return dash
}

// NewDashboardFolder creates a new dashboard folder
func NewDashboardFolder(title string) *Dashboard {
	folder := NewDashboard(title)
	folder.IsFolder = true
	folder.Data.Set("schemaVersion", 17)
	folder.Data.Set("version", 0)
	folder.IsFolder = true
	return folder
}

// GetTags turns the tags in data json into go string array
func (dash *Dashboard) GetTags() []string {
	return dash.Data.Get("tags").MustStringArray()
}

func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
	dash := &Dashboard{}
	dash.Data = data
	dash.Title = dash.Data.Get("title").MustString()
	dash.UpdateSlug()
	update := false

	if id, err := dash.Data.Get("id").Float64(); err == nil {
		dash.Id = int64(id)
		update = true
	}

	if uid, err := dash.Data.Get("uid").String(); err == nil {
		dash.Uid = uid
		update = true
	}

	if version, err := dash.Data.Get("version").Float64(); err == nil && update {
		dash.Version = int(version)
		dash.Updated = time.Now()
	} else {
		dash.Data.Set("version", 0)
		dash.Created = time.Now()
		dash.Updated = time.Now()
	}

	if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
		dash.GnetId = int64(gnetId)
	}

	return dash
}

// GetDashboardModel turns the command into the saveable model
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
	dash := NewDashboardFromJson(cmd.Dashboard)
	userId := cmd.UserId

	if userId == 0 {
		userId = -1
	}

	dash.UpdatedBy = userId
	dash.OrgId = cmd.OrgId
	dash.PluginId = cmd.PluginId
	dash.IsFolder = cmd.IsFolder
	dash.FolderId = cmd.FolderId
	dash.UpdateSlug()
	return dash
}

// GetString a
func (dash *Dashboard) GetString(prop string, defaultValue string) string {
	return dash.Data.Get(prop).MustString(defaultValue)
}

// UpdateSlug updates the slug
func (dash *Dashboard) UpdateSlug() {
	title := dash.Data.Get("title").MustString()
	dash.Slug = SlugifyTitle(title)
}

func SlugifyTitle(title string) string {
	return slug.Make(strings.ToLower(title))
}

// GetUrl return the html url for a folder if it's folder, otherwise for a dashboard
func (dash *Dashboard) GetUrl() string {
	return GetDashboardFolderUrl(dash.IsFolder, dash.Uid, dash.Slug)
}

// Return the html url for a dashboard
func (dash *Dashboard) GenerateUrl() string {
	return GetDashboardUrl(dash.Uid, dash.Slug)
}

// GetDashboardFolderUrl return the html url for a folder if it's folder, otherwise for a dashboard
func GetDashboardFolderUrl(isFolder bool, uid string, slug string) string {
	if isFolder {
		return GetFolderUrl(uid, slug)
	}

	return GetDashboardUrl(uid, slug)
}

// GetDashboardUrl return the html url for a dashboard
func GetDashboardUrl(uid string, slug string) string {
	return fmt.Sprintf("%s/d/%s/%s", setting.AppSubUrl, uid, slug)
}

// GetFullDashboardUrl return the full url for a dashboard
func GetFullDashboardUrl(uid string, slug string) string {
	return fmt.Sprintf("%sd/%s/%s", setting.AppUrl, uid, slug)
}

// GetFolderUrl return the html url for a folder
func GetFolderUrl(folderUid string, slug string) string {
	return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug)
}

type ValidateDashboardBeforeSaveResult struct {
	IsParentFolderChanged bool
}

//
// COMMANDS
//

type SaveDashboardCommand struct {
	Dashboard    *simplejson.Json `json:"dashboard" binding:"Required"`
	UserId       int64            `json:"userId"`
	Overwrite    bool             `json:"overwrite"`
	Message      string           `json:"message"`
	OrgId        int64            `json:"-"`
	RestoredFrom int              `json:"-"`
	PluginId     string           `json:"-"`
	FolderId     int64            `json:"folderId"`
	IsFolder     bool             `json:"isFolder"`

	UpdatedAt time.Time

	Result *Dashboard
}

type DashboardProvisioning struct {
	Id          int64
	DashboardId int64
	Name        string
	ExternalId  string
	CheckSum    string
	Updated     int64
}

type SaveProvisionedDashboardCommand struct {
	DashboardCmd          *SaveDashboardCommand
	DashboardProvisioning *DashboardProvisioning

	Result *Dashboard
}

type DeleteDashboardCommand struct {
	Id    int64
	OrgId int64
}

type ValidateDashboardBeforeSaveCommand struct {
	OrgId     int64
	Dashboard *Dashboard
	Overwrite bool
	Result    *ValidateDashboardBeforeSaveResult
}

//
// QUERIES
//

type GetDashboardQuery struct {
	Slug  string // required if no Id or Uid is specified
	Id    int64  // optional if slug is set
	Uid   string // optional if slug is set
	OrgId int64

	Result *Dashboard
}

type DashboardTagCloudItem struct {
	Term  string `json:"term"`
	Count int    `json:"count"`
}

type GetDashboardTagsQuery struct {
	OrgId  int64
	Result []*DashboardTagCloudItem
}

type GetDashboardsQuery struct {
	DashboardIds []int64
	Result       []*Dashboard
}

type GetDashboardPermissionsForUserQuery struct {
	DashboardIds []int64
	OrgId        int64
	UserId       int64
	OrgRole      RoleType
	Result       []*DashboardPermissionForUser
}

type GetDashboardsByPluginIdQuery struct {
	OrgId    int64
	PluginId string
	Result   []*Dashboard
}

type GetDashboardSlugByIdQuery struct {
	Id     int64
	Result string
}

type GetProvisionedDashboardDataByIdQuery struct {
	DashboardId int64
	Result      *DashboardProvisioning
}

type GetProvisionedDashboardDataQuery struct {
	Name   string
	Result []*DashboardProvisioning
}

type GetDashboardsBySlugQuery struct {
	OrgId int64
	Slug  string

	Result []*Dashboard
}

type DashboardPermissionForUser struct {
	DashboardId    int64          `json:"dashboardId"`
	Permission     PermissionType `json:"permission"`
	PermissionName string         `json:"permissionName"`
}

type DashboardRef struct {
	Uid  string
	Slug string
}

type GetDashboardRefByIdQuery struct {
	Id     int64
	Result *DashboardRef
}

type UnprovisionDashboardCommand struct {
	Id int64
}
<commit_msg>Dashboard: Add failsafe for slug generation (#23709)<commit_after>package models

import (
	"encoding/base64"
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/gosimple/slug"
	"github.com/grafana/grafana/pkg/components/simplejson"
	"github.com/grafana/grafana/pkg/setting"
)

// Typed errors
var (
	ErrDashboardNotFound                         = errors.New("Dashboard not found")
	ErrDashboardFolderNotFound                   = errors.New("Folder not found")
	ErrDashboardSnapshotNotFound                 = errors.New("Dashboard snapshot not found")
	ErrDashboardWithSameUIDExists                = errors.New("A dashboard with the same uid already exists")
	ErrDashboardWithSameNameInFolderExists       = errors.New("A dashboard with the same name in the folder already exists")
	ErrDashboardVersionMismatch                  = errors.New("The dashboard has been changed by someone else")
	ErrDashboardTitleEmpty                       = errors.New("Dashboard title cannot be empty")
	ErrDashboardFolderCannotHaveParent           = errors.New("A Dashboard Folder cannot be added to another folder")
	ErrDashboardsWithSameSlugExists              = errors.New("Multiple dashboards with the same slug exists")
	ErrDashboardFailedGenerateUniqueUid          = errors.New("Failed to generate unique dashboard id")
	ErrDashboardTypeMismatch                     = errors.New("Dashboard cannot be changed to a folder")
	ErrDashboardFolderWithSameNameAsDashboard    = errors.New("Folder name cannot be the same as one of its dashboards")
	ErrDashboardWithSameNameAsFolder             = errors.New("Dashboard name cannot be the same as folder")
	ErrDashboardFolderNameExists                 = errors.New("A folder with that name already exists")
	ErrDashboardUpdateAccessDenied               = errors.New("Access denied to save dashboard")
	ErrDashboardInvalidUid                       = errors.New("uid contains illegal characters")
	ErrDashboardUidToLong                        = errors.New("uid to long. max 40 characters")
	ErrDashboardCannotSaveProvisionedDashboard   = errors.New("Cannot save provisioned dashboard")
	ErrDashboardRefreshIntervalTooShort          = errors.New("Dashboard refresh interval is too low")
	ErrDashboardCannotDeleteProvisionedDashboard = errors.New("provisioned dashboard cannot be deleted")
	ErrDashboardIdentifierNotSet                 = errors.New("Unique identfier needed to be able to get a dashboard")
	RootFolderName                               = "General"
)

type UpdatePluginDashboardError struct {
	PluginId string
}

func (d UpdatePluginDashboardError) Error() string {
	return "Dashboard belong to plugin"
}

var (
	DashTypeJson     = "file"
	DashTypeDB       = "db"
	DashTypeScript   = "script"
	DashTypeSnapshot = "snapshot"
)

// Dashboard model
type Dashboard struct {
	Id       int64
	Uid      string
	Slug     string
	OrgId    int64
	GnetId   int64
	Version  int
	PluginId string

	Created time.Time
	Updated time.Time

	UpdatedBy int64
	CreatedBy int64
	FolderId  int64
	IsFolder  bool
	HasAcl    bool

	Title string
	Data  *simplejson.Json
}

func (d *Dashboard) SetId(id int64) {
	d.Id = id
	d.Data.Set("id", id)
}

func (d *Dashboard) SetUid(uid string) {
	d.Uid = uid
	d.Data.Set("uid", uid)
}

func (d *Dashboard) SetVersion(version int) {
	d.Version = version
	d.Data.Set("version", version)
}

// GetDashboardIdForSavePermissionCheck return the dashboard id to be used for checking permission of dashboard
func (d *Dashboard) GetDashboardIdForSavePermissionCheck() int64 {
	if d.Id == 0 {
		return d.FolderId
	}

	return d.Id
}

// NewDashboard creates a new dashboard
func NewDashboard(title string) *Dashboard {
	dash := &Dashboard{}
	dash.Data = simplejson.New()
	dash.Data.Set("title", title)
	dash.Title = title
	dash.Created = time.Now()
	dash.Updated = time.Now()
	dash.UpdateSlug()
	return dash
}

// NewDashboardFolder creates a new dashboard folder
func NewDashboardFolder(title string) *Dashboard {
	folder := NewDashboard(title)
	folder.IsFolder = true
	folder.Data.Set("schemaVersion", 17)
	folder.Data.Set("version", 0)
	folder.IsFolder = true
	return folder
}

// GetTags turns the tags in data json into go string array
func (dash *Dashboard) GetTags() []string {
	return dash.Data.Get("tags").MustStringArray()
}

func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
	dash := &Dashboard{}
	dash.Data = data
	dash.Title = dash.Data.Get("title").MustString()
	dash.UpdateSlug()
	update := false

	if id, err := dash.Data.Get("id").Float64(); err == nil {
		dash.Id = int64(id)
		update = true
	}

	if uid, err := dash.Data.Get("uid").String(); err == nil {
		dash.Uid = uid
		update = true
	}

	if version, err := dash.Data.Get("version").Float64(); err == nil && update {
		dash.Version = int(version)
		dash.Updated = time.Now()
	} else {
		dash.Data.Set("version", 0)
		dash.Created = time.Now()
		dash.Updated = time.Now()
	}

	if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
		dash.GnetId = int64(gnetId)
	}

	return dash
}

// GetDashboardModel turns the command into the saveable model
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
	dash := NewDashboardFromJson(cmd.Dashboard)
	userId := cmd.UserId

	if userId == 0 {
		userId = -1
	}

	dash.UpdatedBy = userId
	dash.OrgId = cmd.OrgId
	dash.PluginId = cmd.PluginId
	dash.IsFolder = cmd.IsFolder
	dash.FolderId = cmd.FolderId
	dash.UpdateSlug()
	return dash
}

// GetString a
func (dash *Dashboard) GetString(prop string, defaultValue string) string {
	return dash.Data.Get(prop).MustString(defaultValue)
}

// UpdateSlug updates the slug
func (dash *Dashboard) UpdateSlug() {
	title := dash.Data.Get("title").MustString()
	dash.Slug = SlugifyTitle(title)
}

func SlugifyTitle(title string) string {
	s := slug.Make(strings.ToLower(title))
	if s == "" {
		// If the dashboard name is only characters outside of the
		// sluggable characters, the slug creation will return an
		// empty string which will mess up URLs. This failsafe picks
		// that up and creates the slug as a base64 identifier instead.
		s = base64.RawURLEncoding.EncodeToString([]byte(title))
		if slug.MaxLength != 0 && len(s) > slug.MaxLength {
			s = s[:slug.MaxLength]
		}
	}
	return s
}

// GetUrl return the html url for a folder if it's folder, otherwise for a dashboard
func (dash *Dashboard) GetUrl() string {
	return GetDashboardFolderUrl(dash.IsFolder, dash.Uid, dash.Slug)
}

// Return the html url for a dashboard
func (dash *Dashboard) GenerateUrl() string {
	return GetDashboardUrl(dash.Uid, dash.Slug)
}

// GetDashboardFolderUrl return the html url for a folder if it's folder, otherwise for a dashboard
func GetDashboardFolderUrl(isFolder bool, uid string, slug string) string {
	if isFolder {
		return GetFolderUrl(uid, slug)
	}

	return GetDashboardUrl(uid, slug)
}

// GetDashboardUrl return the html url for a dashboard
func GetDashboardUrl(uid string, slug string) string {
	return fmt.Sprintf("%s/d/%s/%s", setting.AppSubUrl, uid, slug)
}

// GetFullDashboardUrl return the full url for a dashboard
func GetFullDashboardUrl(uid string, slug string) string {
	return fmt.Sprintf("%sd/%s/%s", setting.AppUrl, uid, slug)
}

// GetFolderUrl return the html url for a folder
func GetFolderUrl(folderUid string, slug string) string {
	return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug)
}

type ValidateDashboardBeforeSaveResult struct {
	IsParentFolderChanged bool
}

//
// COMMANDS
//

type SaveDashboardCommand struct {
	Dashboard    *simplejson.Json `json:"dashboard" binding:"Required"`
	UserId       int64            `json:"userId"`
	Overwrite    bool             `json:"overwrite"`
	Message      string           `json:"message"`
	OrgId        int64            `json:"-"`
	RestoredFrom int              `json:"-"`
	PluginId     string           `json:"-"`
	FolderId     int64            `json:"folderId"`
	IsFolder     bool             `json:"isFolder"`

	UpdatedAt time.Time

	Result *Dashboard
}

type DashboardProvisioning struct {
	Id          int64
	DashboardId int64
	Name        string
	ExternalId  string
	CheckSum    string
	Updated     int64
}

type SaveProvisionedDashboardCommand struct {
	DashboardCmd          *SaveDashboardCommand
	DashboardProvisioning *DashboardProvisioning

	Result *Dashboard
}

type DeleteDashboardCommand struct {
	Id    int64
	OrgId int64
}

type ValidateDashboardBeforeSaveCommand struct {
	OrgId     int64
	Dashboard *Dashboard
	Overwrite bool
	Result    *ValidateDashboardBeforeSaveResult
}

//
// QUERIES
//

type GetDashboardQuery struct {
	Slug  string // required if no Id or Uid is specified
	Id    int64  // optional if slug is set
	Uid   string // optional if slug is set
	OrgId int64

	Result *Dashboard
}

type DashboardTagCloudItem struct {
	Term  string `json:"term"`
	Count int    `json:"count"`
}

type GetDashboardTagsQuery struct {
	OrgId  int64
	Result []*DashboardTagCloudItem
}

type GetDashboardsQuery struct {
	DashboardIds []int64
	Result       []*Dashboard
}

type GetDashboardPermissionsForUserQuery struct {
	DashboardIds []int64
	OrgId        int64
	UserId       int64
	OrgRole      RoleType
	Result       []*DashboardPermissionForUser
}

type GetDashboardsByPluginIdQuery struct {
	OrgId    int64
	PluginId string
	Result   []*Dashboard
}

type GetDashboardSlugByIdQuery struct {
	Id     int64
	Result string
}

type GetProvisionedDashboardDataByIdQuery struct {
	DashboardId int64
	Result      *DashboardProvisioning
}

type GetProvisionedDashboardDataQuery struct {
	Name   string
	Result []*DashboardProvisioning
}

type GetDashboardsBySlugQuery struct {
	OrgId int64
	Slug  string

	Result []*Dashboard
}

type DashboardPermissionForUser struct {
	DashboardId    int64          `json:"dashboardId"`
	Permission     PermissionType `json:"permission"`
	PermissionName string         `json:"permissionName"`
}

type DashboardRef struct {
	Uid  string
	Slug string
}

type GetDashboardRefByIdQuery struct {
	Id     int64
	Result *DashboardRef
}

type UnprovisionDashboardCommand struct {
	Id int64
}
<|endoftext|>


<commit_before>package plugin

import (
	"fmt"
	"net"

	log "github.com/golang/glog"

	osclient "github.com/openshift/origin/pkg/client"
	osconfigapi "github.com/openshift/origin/pkg/cmd/server/api"
	"github.com/openshift/origin/pkg/util/netutils"

	kclient "k8s.io/kubernetes/pkg/client/unversioned"
	kerrors "k8s.io/kubernetes/pkg/util/errors"
)

type OsdnMaster struct {
	registry        *Registry
	subnetAllocator *netutils.SubnetAllocator
	vnids           *vnidMap
	netIDManager    *netutils.NetIDAllocator
	adminNamespaces []string
}

func StartMaster(networkConfig osconfigapi.MasterNetworkConfig, osClient *osclient.Client, kClient *kclient.Client) error {
	if !IsOpenShiftNetworkPlugin(networkConfig.NetworkPluginName) {
		return nil
	}

	log.Infof("Initializing SDN master of type %q", networkConfig.NetworkPluginName)
	master := &OsdnMaster{
		registry:        newRegistry(osClient, kClient),
		vnids:           newVnidMap(),
		adminNamespaces: make([]string, 0),
	}

	// Validate command-line/config parameters
	ni, err := validateClusterNetwork(networkConfig.ClusterNetworkCIDR, networkConfig.HostSubnetLength, networkConfig.ServiceNetworkCIDR, networkConfig.NetworkPluginName)
	if err != nil {
		return err
	}

	changed, net_err := master.isClusterNetworkChanged(ni)
	if changed {
		if err = master.validateNetworkConfig(ni); err != nil {
			return err
		}
		if err = master.registry.UpdateClusterNetwork(ni); err != nil {
			return err
		}
	} else if net_err != nil {
		if err = master.registry.CreateClusterNetwork(ni); err != nil {
			return err
		}
	}

	if err = master.SubnetStartMaster(ni.ClusterNetwork, networkConfig.HostSubnetLength); err != nil {
		return err
	}

	if IsOpenShiftMultitenantNetworkPlugin(networkConfig.NetworkPluginName) {
		if err = master.VnidStartMaster(); err != nil {
			return err
		}
	}

	return nil
}

func (master *OsdnMaster) validateNetworkConfig(ni *NetworkInfo) error {
	hostIPNets, err := netutils.GetHostIPNetworks([]string{TUN, LBR})
	if err != nil {
		return err
	}

	errList := []error{}

	// Ensure cluster and service network don't overlap with host networks
	for _, ipNet := range hostIPNets {
		if ipNet.Contains(ni.ClusterNetwork.IP) {
			errList = append(errList, fmt.Errorf("Error: Cluster IP: %s conflicts with host network: %s", ni.ClusterNetwork.IP.String(), ipNet.String()))
		}
		if ni.ClusterNetwork.Contains(ipNet.IP) {
			errList = append(errList, fmt.Errorf("Error: Host network with IP: %s conflicts with cluster network: %s", ipNet.IP.String(), ni.ClusterNetwork.String()))
		}
		if ipNet.Contains(ni.ServiceNetwork.IP) {
			errList = append(errList, fmt.Errorf("Error: Service IP: %s conflicts with host network: %s", ni.ServiceNetwork.String(), ipNet.String()))
		}
		if ni.ServiceNetwork.Contains(ipNet.IP) {
			errList = append(errList, fmt.Errorf("Error: Host network with IP: %s conflicts with service network: %s", ipNet.IP.String(), ni.ServiceNetwork.String()))
		}
	}

	// Ensure each host subnet is within the cluster network
	subnets, err := master.registry.GetSubnets()
	if err != nil {
		return fmt.Errorf("Error in initializing/fetching subnets: %v", err)
	}
	for _, sub := range subnets {
		subnetIP, _, _ := net.ParseCIDR(sub.Subnet)
		if subnetIP == nil {
			errList = append(errList, fmt.Errorf("Failed to parse network address: %s", sub.Subnet))
			continue
		}
		if !ni.ClusterNetwork.Contains(subnetIP) {
			errList = append(errList, fmt.Errorf("Error: Existing node subnet: %s is not part of cluster network: %s", sub.Subnet, ni.ClusterNetwork.String()))
		}
	}

	// Ensure each service is within the services network
	services, err := master.registry.GetServices()
	if err != nil {
		return err
	}
	for _, svc := range services {
		if !ni.ServiceNetwork.Contains(net.ParseIP(svc.Spec.ClusterIP)) {
			errList = append(errList, fmt.Errorf("Error: Existing service with IP: %s is not part of service network: %s", svc.Spec.ClusterIP, ni.ServiceNetwork.String()))
		}
	}

	return kerrors.NewAggregate(errList)
}

func (master *OsdnMaster) isClusterNetworkChanged(curNetwork *NetworkInfo) (bool, error) {
	oldNetwork, err := master.registry.GetNetworkInfo()
	if err != nil {
		return false, err
	}

	if curNetwork.ClusterNetwork.String() != oldNetwork.ClusterNetwork.String() ||
		curNetwork.HostSubnetLength != oldNetwork.HostSubnetLength ||
		curNetwork.ServiceNetwork.String() != oldNetwork.ServiceNetwork.String() {
		return true, nil
	}
	return false, nil
}
<commit_msg>Bug 1365450 - Fix SDN plugin name change<commit_after>package plugin

import (
	"fmt"
	"net"

	log "github.com/golang/glog"

	osclient "github.com/openshift/origin/pkg/client"
	osconfigapi "github.com/openshift/origin/pkg/cmd/server/api"
	"github.com/openshift/origin/pkg/util/netutils"

	kclient "k8s.io/kubernetes/pkg/client/unversioned"
	kerrors "k8s.io/kubernetes/pkg/util/errors"
)

type OsdnMaster struct {
	registry        *Registry
	subnetAllocator *netutils.SubnetAllocator
	vnids           *vnidMap
	netIDManager    *netutils.NetIDAllocator
	adminNamespaces []string
}

func StartMaster(networkConfig osconfigapi.MasterNetworkConfig, osClient *osclient.Client, kClient *kclient.Client) error {
	if !IsOpenShiftNetworkPlugin(networkConfig.NetworkPluginName) {
		return nil
	}

	log.Infof("Initializing SDN master of type %q", networkConfig.NetworkPluginName)
	master := &OsdnMaster{
		registry:        newRegistry(osClient, kClient),
		vnids:           newVnidMap(),
		adminNamespaces: make([]string, 0),
	}

	// Validate command-line/config parameters
	ni, err := validateClusterNetwork(networkConfig.ClusterNetworkCIDR, networkConfig.HostSubnetLength, networkConfig.ServiceNetworkCIDR, networkConfig.NetworkPluginName)
	if err != nil {
		return err
	}

	changed, net_err := master.isClusterNetworkChanged(ni)
	if changed {
		if err = master.validateNetworkConfig(ni); err != nil {
			return err
		}
		if err = master.registry.UpdateClusterNetwork(ni); err != nil {
			return err
		}
	} else if net_err != nil {
		if err = master.registry.CreateClusterNetwork(ni); err != nil {
			return err
		}
	}

	if err = master.SubnetStartMaster(ni.ClusterNetwork, networkConfig.HostSubnetLength); err != nil {
		return err
	}

	if IsOpenShiftMultitenantNetworkPlugin(networkConfig.NetworkPluginName) {
		if err = master.VnidStartMaster(); err != nil {
			return err
		}
	}

	return nil
}

func (master *OsdnMaster) validateNetworkConfig(ni *NetworkInfo) error {
	hostIPNets, err := netutils.GetHostIPNetworks([]string{TUN, LBR})
	if err != nil {
		return err
	}

	errList := []error{}

	// Ensure cluster and service network don't overlap with host networks
	for _, ipNet := range hostIPNets {
		if ipNet.Contains(ni.ClusterNetwork.IP) {
			errList = append(errList, fmt.Errorf("Error: Cluster IP: %s conflicts with host network: %s", ni.ClusterNetwork.IP.String(), ipNet.String()))
		}
		if ni.ClusterNetwork.Contains(ipNet.IP) {
			errList = append(errList, fmt.Errorf("Error: Host network with IP: %s conflicts with cluster network: %s", ipNet.IP.String(), ni.ClusterNetwork.String()))
		}
		if ipNet.Contains(ni.ServiceNetwork.IP) {
			errList = append(errList, fmt.Errorf("Error: Service IP: %s conflicts with host network: %s", ni.ServiceNetwork.String(), ipNet.String()))
		}
		if ni.ServiceNetwork.Contains(ipNet.IP) {
			errList = append(errList, fmt.Errorf("Error: Host network with IP: %s conflicts with service network: %s", ipNet.IP.String(), ni.ServiceNetwork.String()))
		}
	}

	// Ensure each host subnet is within the cluster network
	subnets, err := master.registry.GetSubnets()
	if err != nil {
		return fmt.Errorf("Error in initializing/fetching subnets: %v", err)
	}
	for _, sub := range subnets {
		subnetIP, _, _ := net.ParseCIDR(sub.Subnet)
		if subnetIP == nil {
			errList = append(errList, fmt.Errorf("Failed to parse network address: %s", sub.Subnet))
			continue
		}
		if !ni.ClusterNetwork.Contains(subnetIP) {
			errList = append(errList, fmt.Errorf("Error: Existing node subnet: %s is not part of cluster network: %s", sub.Subnet, ni.ClusterNetwork.String()))
		}
	}

	// Ensure each service is within the services network
	services, err := master.registry.GetServices()
	if err != nil {
		return err
	}
	for _, svc := range services {
		if !ni.ServiceNetwork.Contains(net.ParseIP(svc.Spec.ClusterIP)) {
			errList = append(errList, fmt.Errorf("Error: Existing service with IP: %s is not part of service network: %s", svc.Spec.ClusterIP, ni.ServiceNetwork.String()))
		}
	}

	return kerrors.NewAggregate(errList)
}

func (master *OsdnMaster) isClusterNetworkChanged(curNetwork *NetworkInfo) (bool, error) {
	oldNetwork, err := master.registry.GetNetworkInfo()
	if err != nil {
		return false, err
	}

	if curNetwork.ClusterNetwork.String() != oldNetwork.ClusterNetwork.String() ||
		curNetwork.HostSubnetLength != oldNetwork.HostSubnetLength ||
		curNetwork.ServiceNetwork.String() != oldNetwork.ServiceNetwork.String() ||
		curNetwork.PluginName != oldNetwork.PluginName {
		return true, nil
	}
	return false, nil
}
<|endoftext|>


<commit_before>package plugins

import (
	"fmt"

	"github.com/InnovaCo/serve/manifest"
	"github.com/InnovaCo/serve/utils"
)

func init() {
	manifest.PluginRegestry.Add("deploy.debian", DeployDebian{})
}

type DeployDebian struct{}

func (p DeployDebian) Run(data manifest.Manifest) error {
	if data.GetBool("purge") {
		return p.Uninstall(data)
	} else {
		return p.Install(data)
	}
}

func (p DeployDebian) Install(data manifest.Manifest) error {
	if err := runSshCmd(
		data.GetString("cluster"),
		data.GetString("ssh-user"),
		fmt.Sprintf("sudo %s/debian-way/deploy.sh --package=%s", data.GetString("ci-tools-path"), data.GetString("package")),
	); err != nil {
		return err
	}

	return registerPluginData("deploy.debian", data.GetString("package"), data.String(), data.GetString("consul-host"))
}

func (p DeployDebian) Uninstall(data manifest.Manifest) error {
	if err := runSshCmd(
		data.GetString("cluster"),
		data.GetString("ssh-user"),
		fmt.Sprintf("sudo apt-get -y purge %s", data.GetString("package")),
	); err != nil {
		return err
	}

	return deletePluginData("deploy.debian", data.GetString("package"), data.GetString("consul-host"))
}

func runSshCmd(cluster, sshUser, cmd string) error {
	return utils.RunCmd(
		`dig +short %s | sort | uniq | parallel -j 1 ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no %s@{} "%s"`,
		cluster,
		sshUser,
		cmd,
	)
}
<commit_msg>add env<commit_after>package plugins

import (
	"fmt"

	"github.com/InnovaCo/serve/manifest"
	"github.com/InnovaCo/serve/utils"
)

func init() {
	manifest.PluginRegestry.Add("deploy.debian", DeployDebian{})
}

type DeployDebian struct{}

func (p DeployDebian) Run(data manifest.Manifest) error {
	if data.GetBool("purge") {
		return p.Uninstall(data)
	} else {
		return p.Install(data)
	}
}

func (p DeployDebian) Install(data manifest.Manifest) error {
	if err := runSshCmd(
		data.GetString("cluster"),
		data.GetString("ssh-user"),
		fmt.Sprintf("sudo %s/debian-way/deploy.sh --package=%s", data.GetString("ci-tools-path"), data.GetString("package")),
	); err != nil {
		return err
	}

	return registerPluginData("deploy.debian", data.GetString("package"), data.String(), data.GetString("consul-host"))
}

func (p DeployDebian) Uninstall(data manifest.Manifest) error {
	if err := runSshCmd(
		data.GetString("cluster"),
		data.GetString("ssh-user"),
		"env",
	); err != nil {
		return err
	}

	if err := runSshCmd(
		data.GetString("cluster"),
		data.GetString("ssh-user"),
		fmt.Sprintf("sudo apt-get purge %s -y", data.GetString("package")),
	); err != nil {
		return err
	}

	return deletePluginData("deploy.debian", data.GetString("package"), data.GetString("consul-host"))
}

func runSshCmd(cluster, sshUser, cmd string) error {
	return utils.RunCmd(
		`dig +short %s | sort | uniq | parallel -j 1 ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no %s@{} "%s"`,
		cluster,
		sshUser,
		cmd,
	)
}
<|endoftext|>


<commit_before>package internalversion

import (
	"fmt"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"

	apps "github.com/openshift/origin/pkg/apps/apis/apps"
	imageapi "github.com/openshift/origin/pkg/image/apis/image"
)

// DeploymentConfigListerExpansion allows custom methods to be added to
// DeploymentConfigLister.
type DeploymentConfigListerExpansion interface {
	GetConfigForController(rc *v1.ReplicationController) (*apps.DeploymentConfig, error)
	GetConfigsForImageStream(stream *imageapi.ImageStream) ([]*apps.DeploymentConfig, error)
}

// DeploymentConfigNamespaceListerExpansion allows custom methods to be added to
// DeploymentConfigNamespaceLister.
type DeploymentConfigNamespaceListerExpansion interface{}

// GetConfigForController returns the managing deployment config for the provided replication controller.
func (s *deploymentConfigLister) GetConfigForController(rc *v1.ReplicationController) (*apps.DeploymentConfig, error) {
	dcName := rc.Annotations[apps.DeploymentConfigAnnotation]
	obj, exists, err := s.indexer.GetByKey(rc.Namespace + "/" + dcName)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, errors.NewNotFound(apps.Resource("deploymentconfig"), dcName)
	}
	return obj.(*apps.DeploymentConfig), nil
}

// GetConfigsForImageStream returns all the deployment configs that point to the provided image stream
// by searching through using the ImageStreamReferenceIndex (deployment configs are indexed in the cache
// by namespace and by image stream references).
func (s *deploymentConfigLister) GetConfigsForImageStream(stream *imageapi.ImageStream) ([]*apps.DeploymentConfig, error) {
	items, err := s.indexer.ByIndex(ImageStreamReferenceIndex, stream.Namespace+"/"+stream.Name)
	if err != nil {
		return nil, err
	}

	var configs []*apps.DeploymentConfig

	for _, obj := range items {
		config := obj.(*apps.DeploymentConfig)
		configs = append(configs, config)
	}

	return configs, nil
}

const (
	ImageStreamReferenceIndex = "imagestreamref"
)

// ImageStreamReferenceIndexFunc is a default index function that indexes based on image stream references.
func ImageStreamReferenceIndexFunc(obj interface{}) ([]string, error) {
	switch t := obj.(type) {
	case *apps.DeploymentConfig:
		var keys []string
		for _, trigger := range t.Spec.Triggers {
			if trigger.Type != apps.DeploymentTriggerOnImageChange {
				continue
			}
			params := trigger.ImageChangeParams
			name, _, _ := imageapi.SplitImageStreamTag(params.From.Name)
			keys = append(keys, params.From.Namespace+"/"+name)
		}

		if len(keys) == 0 {
			// Return an empty key for configs that don't hold object references.
			keys = append(keys, "")
		}

		return keys, nil
	}
	return nil, fmt.Errorf("image stream reference index not implemented for %#v", obj)
}
<commit_msg>apps: remove unused deployment config lister expansion<commit_after>package internalversion

// DeploymentConfigListerExpansion allows custom methods to be added to
// DeploymentConfigLister.
type DeploymentConfigListerExpansion interface {
}

// DeploymentConfigNamespaceListerExpansion allows custom methods to be added to
// DeploymentConfigNamespaceLister.
type DeploymentConfigNamespaceListerExpansion interface{}
<|endoftext|>


<commit_before>package faker

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"strings"
	"time"
)

var r = rand.New(rand.NewSource(time.Now().UnixNano()))

type noSamplesError string

func (str noSamplesError) Error() string {
	return fmt.Sprintf("No samples for language: %s", str)
}

// Config used to congigure faker
type Config struct {
	Lang         string
	UseLocalData bool
	EnFallback   bool
}

// Faker is the interface for faking things
type Faker interface {
	FirstName() (string, error)
	LastName() (string, error)
	FullName() (string, error)
}

// cat/subcat/lang/samples
type samplesMap map[string]map[string]map[string][]string

type faker struct {
	lang         string
	useLocalData bool
	enFallback   bool
	samples      samplesMap
}

// NewFaker returns new faker object
func NewFaker(config Config) (Faker, error) {
	if config.Lang == "" {
		config.Lang = "en"
	}

	err := checkLang(config)
	if err != nil {
		return nil, err
	}

	return &faker{
		lang:         config.Lang,
		useLocalData: config.UseLocalData,
		enFallback:   config.EnFallback,
		samples:      make(samplesMap),
	}, nil
}

func checkLang(config Config) error {
	availLangs := []string{"en", "br", "ca", "da", "de", "fi", "fr", "mx", "nl", "se", "sn", "uk", "us", "ja", "ar", "cn", "cs",
		"ga", "it", "kr", "nb", "ph", "th", "vn"}

	found := false
	for _, lang := range availLangs {
		if config.Lang == lang {
			found = true
			break
		}
	}
	if !found {
		return fmt.Errorf("The language passed (%s) is not available", config.Lang)
	}
	return nil
}

func (f *faker) lookup(params ...string) (string, error) {
	if len(params) < 2 {
		return "", fmt.Errorf("Insufficient params to lookup rhe samples")
	}

	cat := params[0]
	subcat := params[1]
	lang := f.lang
	if len(params) > 2 {
		lang = params[2]
	}

	var samples []string
	var err error

	_, ok := f.samples[cat]
	if ok {
		samples, ok = f.samples[cat][subcat][lang]
	}

	if !ok {
		samples, err = f.populateSamples(cat, subcat, lang)
		if err != nil {
			return "", err
		}
	}

	return samples[r.Intn(len(samples))], nil
}

func (f *faker) readSamplesFile(cat, subcat, lang string) ([]byte, error) {
	var suffix string
	if lang != "en" {
		suffix = "_" + lang
	}
	fullpath := fmt.Sprintf("/data/%s%s/%s", cat, suffix, subcat)
	file, err := FS(f.useLocalData).Open(fullpath)
	if err != nil {
		if f.lang != "en" && f.enFallback {
			return f.readSamplesFile(cat, subcat, "en")
		}
		return nil, noSamplesError(f.lang)
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}

func (f *faker) populateSamples(cat, subcat, lang string) ([]string, error) {
	data, err := f.readSamplesFile(cat, subcat, lang)
	if err != nil {
		return nil, err
	}

	if _, ok := f.samples[cat]; !ok {
		f.samples[cat] = make(map[string]map[string][]string)
	}

	if _, ok := f.samples[cat][subcat]; !ok {
		f.samples[cat][subcat] = make(map[string][]string)
	}

	samples := strings.Split(string(data), "\n")

	f.samples[cat][subcat][lang] = samples
	return samples, nil
}
<commit_msg>removed unnecessary type for the noSamplesError error<commit_after>package faker

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"strings"
	"time"
)

var r = rand.New(rand.NewSource(time.Now().UnixNano()))

// Config used to congigure faker
type Config struct {
	Lang         string
	UseLocalData bool
	EnFallback   bool
}

// Faker is the interface for faking things
type Faker interface {
	FirstName() (string, error)
	LastName() (string, error)
	FullName() (string, error)
}

// cat/subcat/lang/samples
type samplesMap map[string]map[string]map[string][]string

type faker struct {
	lang         string
	useLocalData bool
	enFallback   bool
	samples      samplesMap
}

// NewFaker returns new faker object
func NewFaker(config Config) (Faker, error) {
	if config.Lang == "" {
		config.Lang = "en"
	}

	err := checkLang(config)
	if err != nil {
		return nil, err
	}

	return &faker{
		lang:         config.Lang,
		useLocalData: config.UseLocalData,
		enFallback:   config.EnFallback,
		samples:      make(samplesMap),
	}, nil
}

func checkLang(config Config) error {
	availLangs := []string{"en", "br", "ca", "da", "de", "fi", "fr", "mx", "nl", "se", "sn", "uk", "us", "ja", "ar", "cn", "cs",
		"ga", "it", "kr", "nb", "ph", "th", "vn"}

	found := false
	for _, lang := range availLangs {
		if config.Lang == lang {
			found = true
			break
		}
	}
	if !found {
		return fmt.Errorf("The language passed (%s) is not available", config.Lang)
	}
	return nil
}

func (f *faker) lookup(params ...string) (string, error) {
	if len(params) < 2 {
		return "", fmt.Errorf("Insufficient params to lookup rhe samples")
	}

	cat := params[0]
	subcat := params[1]
	lang := f.lang
	if len(params) > 2 {
		lang = params[2]
	}

	var samples []string
	var err error

	_, ok := f.samples[cat]
	if ok {
		samples, ok = f.samples[cat][subcat][lang]
	}

	if !ok {
		samples, err = f.populateSamples(cat, subcat, lang)
		if err != nil {
			return "", err
		}
	}

	return samples[r.Intn(len(samples))], nil
}

func (f *faker) readSamplesFile(cat, subcat, lang string) ([]byte, error) {
	var suffix string
	if lang != "en" {
		suffix = "_" + lang
	}
	fullpath := fmt.Sprintf("/data/%s%s/%s", cat, suffix, subcat)
	file, err := FS(f.useLocalData).Open(fullpath)
	if err != nil {
		if f.lang != "en" && f.enFallback {
			return f.readSamplesFile(cat, subcat, "en")
		}
		return nil, fmt.Errorf("No samples for language: %s", lang)
	}
	defer file.Close()

	return ioutil.ReadAll(file)
}

func (f *faker) populateSamples(cat, subcat, lang string) ([]string, error) {
	data, err := f.readSamplesFile(cat, subcat, lang)
	if err != nil {
		return nil, err
	}

	if _, ok := f.samples[cat]; !ok {
		f.samples[cat] = make(map[string]map[string][]string)
	}

	if _, ok := f.samples[cat][subcat]; !ok {
		f.samples[cat][subcat] = make(map[string][]string)
	}

	samples := strings.Split(string(data), "\n")

	f.samples[cat][subcat][lang] = samples
	return samples, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 VMware, 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 auth

import (
	"fmt"
	"time"

	"github.com/vmware/harbor/src/common/models"
	"github.com/vmware/harbor/src/common/utils/log"
	"github.com/vmware/harbor/src/ui/config"
)

// 1.5 seconds
const frozenTime time.Duration = 1500 * time.Millisecond

const (
	// DBAuth is the database auth mode.
	DBAuth = "db_auth"
	// LDAPAuth is the ldap auth mode.
	LDAPAuth = "ldap_auth"
	// UAAAuth is the uaa auth mode.
	UAAAuth = "uaa_auth"
)

var lock = NewUserLock(frozenTime)

// AuthenticateHelper provides interface to authenticate user credentials.
type AuthenticateHelper interface {

	// Authenticate ...
	Authenticate(m models.AuthModel) (*models.User, error)
	// OnBoardUser will check if a user exists in user table, if not insert the user and
	// put the id in the pointer of user model, if it does exist, return the user's profile.
	OnBoardUser(u *models.User) error
	// Get user information from account repository
	SearchUser(username string) (*models.User, error)
}

var registry = make(map[string]AuthenticateHelper)

// Register add different authenticators to registry map.
func Register(name string, AuthenticateHelper AuthenticateHelper) {
	if _, dup := registry[name]; dup {
		log.Infof("authenticator: %s has been registered", name)
		return
	}
	registry[name] = AuthenticateHelper
}

// Login authenticates user credentials based on setting.
func Login(m models.AuthModel) (*models.User, error) {

	authMode, err := config.AuthMode()
	if err != nil {
		return nil, err
	}
	if authMode == "" || m.Principal == "admin" {
		authMode = "db_auth"
	}
	log.Debug("Current AUTH_MODE is ", authMode)

	authenticator, ok := registry[authMode]
	if !ok {
		return nil, fmt.Errorf("Unrecognized auth_mode: %s", authMode)
	}
	if lock.IsLocked(m.Principal) {
		log.Debugf("%s is locked due to login failure, login failed", m.Principal)
		return nil, nil
	}
	user, err := authenticator.Authenticate(m)
	if user == nil && err == nil {
		log.Debugf("Login failed, locking %s, and sleep for %v", m.Principal, frozenTime)
		lock.Lock(m.Principal)
		time.Sleep(frozenTime)
	}
	return user, err
}

// getAuthenticatorByMode --
func getAuthenticateHelperByMode(authMode string) (AuthenticateHelper, error) {
	if authMode == "" {
		authMode = "db_auth"
	}
	AuthenticateHelper, ok := registry[authMode]
	if !ok {
		return nil, fmt.Errorf("Can not get current authenticator")
	}
	return AuthenticateHelper, nil
}

// OnBoardUser will check if a user exists in user table, if not insert the user and
// put the id in the pointer of user model, if it does exist, return the user's profile.
func OnBoardUser(user *models.User) error {
	authMode, err := config.AuthMode()
	if err != nil {
		return err
	}
	auth, err := getAuthenticateHelperByMode(authMode)
	if err != nil {
		return err
	}
	return auth.OnBoardUser(user)
}

// SearchUser --
func SearchUser(username string) (*models.User, error) {
	authMode, err := config.AuthMode()
	if err != nil {
		return nil, err
	}
	auth, err := getAuthenticateHelperByMode(authMode)
	if err != nil {
		return nil, err
	}
	return auth.SearchUser(username)
}
<commit_msg>Small refactory.<commit_after>// Copyright (c) 2017 VMware, 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 auth

import (
	"fmt"
	"time"

	"github.com/vmware/harbor/src/common/models"
	"github.com/vmware/harbor/src/common/utils/log"
	"github.com/vmware/harbor/src/ui/config"
)

// 1.5 seconds
const frozenTime time.Duration = 1500 * time.Millisecond

const (
	// DBAuth is the database auth mode.
	DBAuth = "db_auth"
	// LDAPAuth is the ldap auth mode.
	LDAPAuth = "ldap_auth"
	// UAAAuth is the uaa auth mode.
	UAAAuth = "uaa_auth"
)

var lock = NewUserLock(frozenTime)

// AuthenticateHelper provides interface for user management in different auth modes.
type AuthenticateHelper interface {

	// Authenticate ...
	Authenticate(m models.AuthModel) (*models.User, error)
	// OnBoardUser will check if a user exists in user table, if not insert the user and
	// put the id in the pointer of user model, if it does exist, fill in the user model based
	// on the data record of the user
	OnBoardUser(u *models.User) error
	// Get user information from account repository
	SearchUser(username string) (*models.User, error)
}

var registry = make(map[string]AuthenticateHelper)

// Register add different authenticators to registry map.
func Register(name string, h AuthenticateHelper) {
	if _, dup := registry[name]; dup {
		log.Infof("authenticator: %s has been registered", name)
		return
	}
	registry[name] = h
}

// Login authenticates user credentials based on setting.
func Login(m models.AuthModel) (*models.User, error) {

	authMode, err := config.AuthMode()
	if err != nil {
		return nil, err
	}
	if authMode == "" || m.Principal == "admin" {
		authMode = "db_auth"
	}
	log.Debug("Current AUTH_MODE is ", authMode)

	authenticator, ok := registry[authMode]
	if !ok {
		return nil, fmt.Errorf("Unrecognized auth_mode: %s", authMode)
	}
	if lock.IsLocked(m.Principal) {
		log.Debugf("%s is locked due to login failure, login failed", m.Principal)
		return nil, nil
	}
	user, err := authenticator.Authenticate(m)
	if user == nil && err == nil {
		log.Debugf("Login failed, locking %s, and sleep for %v", m.Principal, frozenTime)
		lock.Lock(m.Principal)
		time.Sleep(frozenTime)
	}
	return user, err
}

func getHelper() (AuthenticateHelper, error) {
	authMode, err := config.AuthMode()
	if err != nil {
		return nil, err
	}
	AuthenticateHelper, ok := registry[authMode]
	if !ok {
		return nil, fmt.Errorf("Can not get authenticator, authmode: %s", authMode)
	}
	return AuthenticateHelper, nil
}

// OnBoardUser will check if a user exists in user table, if not insert the user and
// put the id in the pointer of user model, if it does exist, return the user's profile.
func OnBoardUser(user *models.User) error {
	helper, err := getHelper()
	if err != nil {
		return err
	}
	return helper.OnBoardUser(user)
}

// SearchUser --
func SearchUser(username string) (*models.User, error) {
	helper, err := getHelper()
	if err != nil {
		return nil, err
	}
	return helper.SearchUser(username)
}
<|endoftext|>


<commit_before>// parsing mathematical expressions
//
//go:generate nex lexer.nex
//go:generate go tool yacc -o parser.y.go parser.y
package parser

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"sort"
	"strconv"
	"strings"
	"text/template"
)

func Formula(n int) string {
	if true {
		var terms []string
		for i := 0; i < n; i++ {
			terms = append(terms, fmt.Sprintf("x%d", i))
		}
		return "f:=" + strings.Join(terms, "*")
	}
	var terms []string
	for i := 0; i < n; i++ {
		term := fmt.Sprintf("%f * x%d", rand.Float64(), i)
		terms = append(terms, term)
	}
	return fmt.Sprintf("f := sqrt(a*x) + pow(a,b) + a-b+c/d + log(1 + exp(-y * (%s)))", strings.Join(terms, "+"))
}

func computeDerivatives(w io.Writer, steps []Step, private string) {
	n := len(steps)
	for i := 0; i < n; i++ {
		j := n - i - 1
		step := steps[j]
		x0 := 0.0
		if i == 0 {
			x0 = 1.0
		}
		fmt.Fprintf(w, "b_%s := %f\n", step.lhs, x0)
		for k := j + 1; k < n; k++ {
			s3 := steps[k]
			if d := derivative(s3, step, private); len(d) > 0 {
				fmt.Fprintf(w, "b_%s += b_%s * (%s)\n", step.lhs, s3.lhs, d)
			}
		}
		if step.decl {
			fmt.Fprintf(w, "grad_%s[\"%s\"] = b_%s\n", private, step.rhs, step.lhs)
		}
	}
}

type Step struct {
	decl bool
	lhs  string
	rhs  string
	f    string
	args []string
}

func derivative(num, denom Step, private string) string {
	var args []int
	for i, a := range num.args {
		if a == denom.lhs {
			args = append(args, i)
		}
	}
	if len(args) == 0 {
		return ""
	}
	var list []string
	for _, a := range args {
		list = append(list, fmt.Sprintf("d_%s_%s(%d,%s)", num.f, private, a, strings.Join(num.args, ",")))
	}
	return strings.Join(list, "+")
}

type NodeType string

const (
	numberNT     NodeType = "NUM"
	identifierNT NodeType = "IDENT"
	functionNT   NodeType = "FUNC"
)

type Node struct {
	Type     NodeType `json:"T,omitempty"`
	S        string   `json:",omitempty"`
	F        float64  `json:",omitempty"`
	Children []*Node  `json:"C,omitempty"`
	Name     string   `json:"N,omitempty"`
}

func (n Node) String() string {
	buf, _ := json.Marshal(n)
	return string(buf)
}

func Run(args []string) {
	var private, templates, formula, output string
	var dx float64
	flags := flag.NewFlagSet("parse", flag.ExitOnError)
	flags.StringVar(&formula, "formula", Formula(10), "the formula to parse")
	flags.StringVar(&private, "private", defaultPrivateString, "the private variable string")
	flags.StringVar(&templates, "templates", defaultTemplates, "directory of go template functions")
	flags.StringVar(&output, "output", "compute.go", "name of go program to output")
	flags.Float64Var(&dx, "dx", defaultDx, "infinitesimal for numerical differentiation")
	flags.Parse(args)

	code, err := Parse(private, templates, formula, 0.00001)
	if err != nil {
		log.Fatal(err)
	}
	f, err := os.Create(output)
	if err != nil {
		log.Fatal(err)
	}
	f.Write(code)
	f.Close()
}

const (
	defaultPrivateString = "pvt"
	defaultDx            = 0.00001
	defaultTemplates     = "src/xoba/ad/parser/templates"
)

func Parse(private, templates, formula string, dx float64) ([]byte, error) {
	if len(private) == 0 {
		private = defaultPrivateString
	}
	if dx == 0 {
		dx = defaultDx
	}
	if len(templates) == 0 {
		templates = defaultTemplates
	}
	lex := NewContext(NewLexer(strings.NewReader(formula)))
	yyParse(lex)
	if len(lex.errors) > 0 {
		return nil, lex.errors[0]
	}
	if lex.lhs == nil || lex.rhs == nil {
		return nil, fmt.Errorf("parse error: lhs or rhs is nil")
	}
	vars := make(map[string]string)
	vp := &VarParser{vars: vars}
	sp := &StepParser{vars: vars}
	var steps []Step
	steps = append(steps, vp.getVars(lex.rhs, private)...)
	steps = append(steps, sp.program(lex.rhs, private)...)
	y := steps[len(steps)-1].lhs

	checker := new(bytes.Buffer)
	{
		fmt.Fprintf(checker, "delta_%s := %f\n", private, dx)
		fmt.Fprintf(checker, `calc_%s := func() float64 {
%s
return %s
}
`, private, formula, lex.lhs.S)
		fmt.Fprintf(checker, "tmp1_%s := calc_%s()\n", private, private)
		for k := range vars {
			fmt.Fprintln(checker, "{")
			fmt.Fprintf(checker, "%s += delta_%s\n", k, private)
			fmt.Fprintf(checker, "tmp2_%s := calc_%s()\n", private, private)
			fmt.Fprintf(checker, "%s -= delta_%s\n", k, private)
			fmt.Fprintf(checker, "grad_%s[%q] = (tmp2_%s - tmp1_%s)/delta_%s\n", private, k, private, private, private)
			fmt.Fprintln(checker, "}")
		}
	}

	pgm := new(bytes.Buffer)
	for _, s := range steps {
		fmt.Fprintln(pgm, s)
	}
	computeDerivatives(pgm, steps, private)
	var list []string
	for v := range vars {
		list = append(list, v)
	}
	sort.Strings(list)

	f := new(bytes.Buffer)

	decls := new(bytes.Buffer)
	for _, v := range list {
		fmt.Fprintf(decls, "%s := rand.Float64();\n", v)
		fmt.Fprintf(decls, "fmt.Printf(\"setting %s = %%f\\n\",%s)\n", v, v)
	}
	fmt.Fprintln(decls, `fmt.Println();`)

	var imports Imports
	imports.Add("fmt")
	imports.Add("math")
	imports.Add("time")
	imports.Add("math/rand")

	t := template.Must(template.New("output.go").Parse(`package main
{{.imports}}

// automatically compute the value and gradient of {{.qformula}}
func ComputeAD({{.vars}} float64) (float64,map[string]float64) {
grad_{{.private}} := make(map[string]float64)
{{.program}} return {{.y}},grad_{{.private}};
}

func main() {
fmt.Println("running autodiff code on {{.formula}}\n");
rand.Seed(time.Now().UTC().UnixNano())
{{.decls}}

	c1, grad1 := ComputeAD({{.vars}})
	fmt.Printf("autodiff value   : %f\n", c1)
	fmt.Printf("autodiff gradient: %v\n\n", grad1)

	c2, grad2 := ComputeNumerical({{.vars}})
	fmt.Printf("numeric value   : %f\n", c2)
	fmt.Printf("numeric gradient: %v\n\n", grad2)

	var total float64
	add := func(n string, x float64) {
		fmt.Printf("%s difference: %f\n", n, x)
		total += math.Abs(x)
	}
	add("value", c1-c2)
	for k, v := range grad2 {
		add(fmt.Sprintf("grad[%3s]", k), grad1[k]-v)
	}
fmt.Printf("\nsum of absolute differences: %f\n",total);
}

// numerically compute the value and gradient of {{.qformula}}
func ComputeNumerical({{.vars}} float64) (float64,map[string]float64) {
grad_{{.private}} := make(map[string]float64)
{{.checker}} return tmp1_{{.private}},grad_{{.private}};
}

{{.funcs}}

`))

	templateImports, code, err := GenTemplates(templates, private)
	if err != nil {
		return nil, err
	}
	imports.AddAll(templateImports)

	t.Execute(f, map[string]interface{}{
		"decls":    decls.String(),
		"formula":  formula,
		"qformula": fmt.Sprintf("%q", formula),
		"lhs":      lex.lhs.S,
		"vars":     strings.Join(list, ", "),
		"program":  pgm.String(),
		"checker":  checker.String(),
		"y":        y,
		"funcs":    code,
		"private":  private,
		"imports":  imports.String(),
	})

	return GofmtBuffer(f.Bytes())
}

type Imports struct {
	list []string
}

func (i Imports) String() string {
	m := make(map[string]bool)
	for _, x := range i.list {
		x = strings.Replace(x, `"`, ``, -1)
		m[x] = true
	}
	out := new(bytes.Buffer)
	fmt.Fprintf(out, "import (\n")
	for k := range m {
		fmt.Fprintf(out, "%q\n", k)
	}
	fmt.Fprintf(out, ")\n")
	return out.String()
}

func (i *Imports) Add(x string) {
	i.list = append(i.list, x)
}

func (i *Imports) AddAll(list []string) {
	for _, x := range list {
		i.Add(x)
	}
}

func formatImports(list []string) string {
	var out []string
	m := make(map[string]bool)
	for _, x := range list {
		m[x] = true
	}
	for k := range m {
		out = append(out, k)
	}
	return strings.Join(out, "\n")
}

func Gofmt(p string) error {
	cmd := exec.Command("gofmt", "-w", p)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func GofmtBuffer(code []byte) ([]byte, error) {
	out := new(bytes.Buffer)
	cmd := exec.Command("gofmt")
	cmd.Stdin = bytes.NewReader(code)
	cmd.Stdout = out
	if err := cmd.Run(); err != nil {
		return nil, err
	}
	return out.Bytes(), nil
}

type VarParser struct {
	i    int
	vars map[string]string
}

// gets all the vars and name them in-place
func (v *VarParser) getVars(rhs *Node, private string) (out []Step) {
	switch rhs.Type {
	case identifierNT:
		if _, ok := v.vars[rhs.S]; !ok {
			rhs.Name = fmt.Sprintf("v_%d_%s", v.i, private)
			v.vars[rhs.S] = rhs.Name
			v.i++
			step := Step{
				decl: true,
				lhs:  rhs.Name,
				rhs:  rhs.S,
			}
			out = append(out, step)
		} else {
			rhs.Name = v.vars[rhs.S]
		}
	case functionNT:
		for _, n := range rhs.Children {
			out = append(out, v.getVars(n, private)...)
		}
	}
	return
}

type StepParser struct {
	i    int
	vars map[string]string
}

func (s Step) String() string {
	return fmt.Sprintf("%s := %s;", s.lhs, s.rhs)
}

func (s *StepParser) program(rhs *Node, private string) (out []Step) {
	switch rhs.Type {
	case numberNT:
		rhs.Name = fmt.Sprintf("%f", rhs.F)
	case functionNT:
		var args []string
		for _, n := range rhs.Children {
			steps := s.program(n, private)
			out = append(out, steps...)
			args = append(args, n.Name)
		}
		step := Step{
			lhs:  fmt.Sprintf("s_%d_%s", s.i, private),
			rhs:  fmt.Sprintf("%s_%s(%s)", rhs.S, private, strings.Join(args, ",")),
			f:    rhs.S,
			args: args,
		}
		out = append(out, step)
		rhs.Name = step.lhs
		s.i++
	}
	return out
}

func Function(ident string, args ...*Node) *Node {
	return &Node{
		Type:     functionNT,
		S:        ident,
		Children: args,
	}
}

func Number(n float64) *Node {
	return &Node{
		Type: numberNT,
		F:    n,
	}
}

func LexIdentifier(s string) *Node {
	return &Node{
		Type: identifierNT,
		S:    s,
	}
}

func LexNumber(s string) *Node {
	n, _ := strconv.ParseFloat(s, 64)
	return Number(n)
}

func Negate(a *Node) *Node {
	return Function("multiply", Number(-1), a)
}

type context struct {
	lhs *Node
	rhs *Node
	yyLexer
	errors []error
}

func NewContext(y yyLexer) *context {
	return &context{yyLexer: y}
}

func (c *context) Error(e string) {
	c.Error2(fmt.Errorf("%s", e))
}

func (c *context) Error2(e error) {
	log.Printf("oops: %v\n", e)
	c.errors = append(c.errors, e)
}
<commit_msg>show more place values because it matters for ad vs numerical accuracy!<commit_after>// parsing mathematical expressions
//
//go:generate nex lexer.nex
//go:generate go tool yacc -o parser.y.go parser.y
package parser

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"sort"
	"strconv"
	"strings"
	"text/template"
)

func Formula(n int) string {
	if true {
		var terms []string
		for i := 0; i < n; i++ {
			terms = append(terms, fmt.Sprintf("x%d", i))
		}
		return "f:=" + strings.Join(terms, "*")
	}
	var terms []string
	for i := 0; i < n; i++ {
		term := fmt.Sprintf("%f * x%d", rand.Float64(), i)
		terms = append(terms, term)
	}
	return fmt.Sprintf("f := sqrt(a*x) + pow(a,b) + a-b+c/d + log(1 + exp(-y * (%s)))", strings.Join(terms, "+"))
}

func computeDerivatives(w io.Writer, steps []Step, private string) {
	n := len(steps)
	for i := 0; i < n; i++ {
		j := n - i - 1
		step := steps[j]
		x0 := 0.0
		if i == 0 {
			x0 = 1.0
		}
		fmt.Fprintf(w, "b_%s := %f\n", step.lhs, x0)
		for k := j + 1; k < n; k++ {
			s3 := steps[k]
			if d := derivative(s3, step, private); len(d) > 0 {
				fmt.Fprintf(w, "b_%s += b_%s * (%s)\n", step.lhs, s3.lhs, d)
			}
		}
		if step.decl {
			fmt.Fprintf(w, "grad_%s[\"%s\"] = b_%s\n", private, step.rhs, step.lhs)
		}
	}
}

type Step struct {
	decl bool
	lhs  string
	rhs  string
	f    string
	args []string
}

func derivative(num, denom Step, private string) string {
	var args []int
	for i, a := range num.args {
		if a == denom.lhs {
			args = append(args, i)
		}
	}
	if len(args) == 0 {
		return ""
	}
	var list []string
	for _, a := range args {
		list = append(list, fmt.Sprintf("d_%s_%s(%d,%s)", num.f, private, a, strings.Join(num.args, ",")))
	}
	return strings.Join(list, "+")
}

type NodeType string

const (
	numberNT     NodeType = "NUM"
	identifierNT NodeType = "IDENT"
	functionNT   NodeType = "FUNC"
)

type Node struct {
	Type     NodeType `json:"T,omitempty"`
	S        string   `json:",omitempty"`
	F        float64  `json:",omitempty"`
	Children []*Node  `json:"C,omitempty"`
	Name     string   `json:"N,omitempty"`
}

func (n Node) String() string {
	buf, _ := json.Marshal(n)
	return string(buf)
}

func Run(args []string) {
	var private, templates, formula, output string
	var dx float64
	flags := flag.NewFlagSet("parse", flag.ExitOnError)
	flags.StringVar(&formula, "formula", Formula(10), "the formula to parse")
	flags.StringVar(&private, "private", defaultPrivateString, "the private variable string")
	flags.StringVar(&templates, "templates", defaultTemplates, "directory of go template functions")
	flags.StringVar(&output, "output", "compute.go", "name of go program to output")
	flags.Float64Var(&dx, "dx", defaultDx, "infinitesimal for numerical differentiation")
	flags.Parse(args)

	code, err := Parse(private, templates, formula, 0.00001)
	if err != nil {
		log.Fatal(err)
	}
	f, err := os.Create(output)
	if err != nil {
		log.Fatal(err)
	}
	f.Write(code)
	f.Close()
}

const (
	defaultPrivateString = "pvt"
	defaultDx            = 0.00001
	defaultTemplates     = "src/xoba/ad/parser/templates"
)

func Parse(private, templates, formula string, dx float64) ([]byte, error) {
	if len(private) == 0 {
		private = defaultPrivateString
	}
	if dx == 0 {
		dx = defaultDx
	}
	if len(templates) == 0 {
		templates = defaultTemplates
	}
	lex := NewContext(NewLexer(strings.NewReader(formula)))
	yyParse(lex)
	if len(lex.errors) > 0 {
		return nil, lex.errors[0]
	}
	if lex.lhs == nil || lex.rhs == nil {
		return nil, fmt.Errorf("parse error: lhs or rhs is nil")
	}
	vars := make(map[string]string)
	vp := &VarParser{vars: vars}
	sp := &StepParser{vars: vars}
	var steps []Step
	steps = append(steps, vp.getVars(lex.rhs, private)...)
	steps = append(steps, sp.program(lex.rhs, private)...)
	y := steps[len(steps)-1].lhs

	checker := new(bytes.Buffer)
	{
		fmt.Fprintf(checker, "delta_%s := %f\n", private, dx)
		fmt.Fprintf(checker, `calc_%s := func() float64 {
%s
return %s
}
`, private, formula, lex.lhs.S)
		fmt.Fprintf(checker, "tmp1_%s := calc_%s()\n", private, private)
		for k := range vars {
			fmt.Fprintln(checker, "{")
			fmt.Fprintf(checker, "%s += delta_%s\n", k, private)
			fmt.Fprintf(checker, "tmp2_%s := calc_%s()\n", private, private)
			fmt.Fprintf(checker, "%s -= delta_%s\n", k, private)
			fmt.Fprintf(checker, "grad_%s[%q] = (tmp2_%s - tmp1_%s)/delta_%s\n", private, k, private, private, private)
			fmt.Fprintln(checker, "}")
		}
	}

	pgm := new(bytes.Buffer)
	for _, s := range steps {
		fmt.Fprintln(pgm, s)
	}
	computeDerivatives(pgm, steps, private)
	var list []string
	for v := range vars {
		list = append(list, v)
	}
	sort.Strings(list)

	f := new(bytes.Buffer)

	decls := new(bytes.Buffer)
	for _, v := range list {
		fmt.Fprintf(decls, "%s := rand.Float64();\n", v)
		fmt.Fprintf(decls, "fmt.Printf(\"setting %s = %%.20f\\n\",%s)\n", v, v)
	}
	fmt.Fprintln(decls, `fmt.Println();`)

	var imports Imports
	imports.Add("fmt")
	imports.Add("math")
	imports.Add("time")
	imports.Add("math/rand")

	t := template.Must(template.New("output.go").Parse(`package main
{{.imports}}

// automatically compute the value and gradient of {{.qformula}}
func ComputeAD({{.vars}} float64) (float64,map[string]float64) {
grad_{{.private}} := make(map[string]float64)
{{.program}} return {{.y}},grad_{{.private}};
}

func main() {
fmt.Println("running autodiff code on {{.formula}}\n");
rand.Seed(time.Now().UTC().UnixNano())
{{.decls}}

	c1, grad1 := ComputeAD({{.vars}})
	fmt.Printf("autodiff value   : %f\n", c1)
	fmt.Printf("autodiff gradient: %v\n\n", grad1)

	c2, grad2 := ComputeNumerical({{.vars}})
	fmt.Printf("numeric value   : %f\n", c2)
	fmt.Printf("numeric gradient: %v\n\n", grad2)

	var total float64
	add := func(n string, x float64) {
		fmt.Printf("%s difference: %f\n", n, x)
		total += math.Abs(x)
	}
	add("value", c1-c2)
	for k, v := range grad2 {
		add(fmt.Sprintf("grad[%3s]", k), grad1[k]-v)
	}
fmt.Printf("\nsum of absolute differences: %f\n",total);
}

// numerically compute the value and gradient of {{.qformula}}
func ComputeNumerical({{.vars}} float64) (float64,map[string]float64) {
grad_{{.private}} := make(map[string]float64)
{{.checker}} return tmp1_{{.private}},grad_{{.private}};
}

{{.funcs}}

`))

	templateImports, code, err := GenTemplates(templates, private)
	if err != nil {
		return nil, err
	}
	imports.AddAll(templateImports)

	t.Execute(f, map[string]interface{}{
		"decls":    decls.String(),
		"formula":  formula,
		"qformula": fmt.Sprintf("%q", formula),
		"lhs":      lex.lhs.S,
		"vars":     strings.Join(list, ", "),
		"program":  pgm.String(),
		"checker":  checker.String(),
		"y":        y,
		"funcs":    code,
		"private":  private,
		"imports":  imports.String(),
	})

	return GofmtBuffer(f.Bytes())
}

type Imports struct {
	list []string
}

func (i Imports) String() string {
	m := make(map[string]bool)
	for _, x := range i.list {
		x = strings.Replace(x, `"`, ``, -1)
		m[x] = true
	}
	out := new(bytes.Buffer)
	fmt.Fprintf(out, "import (\n")
	for k := range m {
		fmt.Fprintf(out, "%q\n", k)
	}
	fmt.Fprintf(out, ")\n")
	return out.String()
}

func (i *Imports) Add(x string) {
	i.list = append(i.list, x)
}

func (i *Imports) AddAll(list []string) {
	for _, x := range list {
		i.Add(x)
	}
}

func formatImports(list []string) string {
	var out []string
	m := make(map[string]bool)
	for _, x := range list {
		m[x] = true
	}
	for k := range m {
		out = append(out, k)
	}
	return strings.Join(out, "\n")
}

func Gofmt(p string) error {
	cmd := exec.Command("gofmt", "-w", p)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func GofmtBuffer(code []byte) ([]byte, error) {
	out := new(bytes.Buffer)
	cmd := exec.Command("gofmt")
	cmd.Stdin = bytes.NewReader(code)
	cmd.Stdout = out
	if err := cmd.Run(); err != nil {
		return nil, err
	}
	return out.Bytes(), nil
}

type VarParser struct {
	i    int
	vars map[string]string
}

// gets all the vars and name them in-place
func (v *VarParser) getVars(rhs *Node, private string) (out []Step) {
	switch rhs.Type {
	case identifierNT:
		if _, ok := v.vars[rhs.S]; !ok {
			rhs.Name = fmt.Sprintf("v_%d_%s", v.i, private)
			v.vars[rhs.S] = rhs.Name
			v.i++
			step := Step{
				decl: true,
				lhs:  rhs.Name,
				rhs:  rhs.S,
			}
			out = append(out, step)
		} else {
			rhs.Name = v.vars[rhs.S]
		}
	case functionNT:
		for _, n := range rhs.Children {
			out = append(out, v.getVars(n, private)...)
		}
	}
	return
}

type StepParser struct {
	i    int
	vars map[string]string
}

func (s Step) String() string {
	return fmt.Sprintf("%s := %s;", s.lhs, s.rhs)
}

func (s *StepParser) program(rhs *Node, private string) (out []Step) {
	switch rhs.Type {
	case numberNT:
		rhs.Name = fmt.Sprintf("%f", rhs.F)
	case functionNT:
		var args []string
		for _, n := range rhs.Children {
			steps := s.program(n, private)
			out = append(out, steps...)
			args = append(args, n.Name)
		}
		step := Step{
			lhs:  fmt.Sprintf("s_%d_%s", s.i, private),
			rhs:  fmt.Sprintf("%s_%s(%s)", rhs.S, private, strings.Join(args, ",")),
			f:    rhs.S,
			args: args,
		}
		out = append(out, step)
		rhs.Name = step.lhs
		s.i++
	}
	return out
}

func Function(ident string, args ...*Node) *Node {
	return &Node{
		Type:     functionNT,
		S:        ident,
		Children: args,
	}
}

func Number(n float64) *Node {
	return &Node{
		Type: numberNT,
		F:    n,
	}
}

func LexIdentifier(s string) *Node {
	return &Node{
		Type: identifierNT,
		S:    s,
	}
}

func LexNumber(s string) *Node {
	n, _ := strconv.ParseFloat(s, 64)
	return Number(n)
}

func Negate(a *Node) *Node {
	return Function("multiply", Number(-1), a)
}

type context struct {
	lhs *Node
	rhs *Node
	yyLexer
	errors []error
}

func NewContext(y yyLexer) *context {
	return &context{yyLexer: y}
}

func (c *context) Error(e string) {
	c.Error2(fmt.Errorf("%s", e))
}

func (c *context) Error2(e error) {
	log.Printf("oops: %v\n", e)
	c.errors = append(c.errors, e)
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	fmt.Printf("Hello world!")
}
<commit_msg>get KEY from env var<commit_after>package main

import (
	"fmt"
	"os"
)

var (
	CONSUMER_KEY string
	CONSUMER_KEY_SECRET string
	ACCESS_TOKEN string
	ACCESS_TOKEN_SECRET string
)
func main() {

	_ = configureToken()

	fmt.Println(CONSUMER_KEY)
	fmt.Println(CONSUMER_KEY_SECRET)
	fmt.Println(ACCESS_TOKEN)
	fmt.Println(ACCESS_TOKEN_SECRET)
}

func  configureToken()(error) {
	CONSUMER_KEY = os.Getenv("CONSUMER_KEY")
	CONSUMER_KEY_SECRET = os.Getenv("CONSUMER_KEY_SECRET")
	ACCESS_TOKEN = os.Getenv("ACCESS_TOKEN")
	ACCESS_TOKEN_SECRET = os.Getenv("ACCESS_TOKEN_SECRET")

	if CONSUMER_KEY != "" || CONSUMER_KEY_SECRET == "" || ACCESS_TOKEN == "" || ACCESS_TOKEN_SECRET == "" {
		return  fmt.Errorf("error %d", 1)
	}
	return nil
}
<|endoftext|>