<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 main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os/exec"
	"time"
)

type configEntry struct {
	GithubUser string
	GitilesURL string
	Name       string
	Exclude    string
}

func readConfig(filename string) ([]configEntry, error) {
	var result []configEntry

	if filename == "" {
		return result, nil
	}

	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	if err := json.Unmarshal(content, &result); err != nil {
		return nil, err
	}

	return result, nil
}

func periodicMirror(repoDir string, cfgFile string, interval time.Duration) {
	t := time.NewTicker(interval)

	var lastCfg []configEntry
	for ; true; <-t.C {
		// We reread the file so we can pickup changes without
		// restarting the service management.
		cfg, err := readConfig(cfgFile)
		if err != nil {
			log.Printf("readConfig(%s): %v", cfgFile, err)
			continue
		} else {
			lastCfg = cfg
		}
		for _, c := range lastCfg {
			if c.GithubUser != "" {
				cmd := exec.Command("zoekt-mirror-github", "-user", c.GithubUser, "-name", c.Name,
					"-exclude", c.Exclude, "-dest", repoDir)
				loggedRun(cmd)
			} else if c.GitilesURL != "" {
				cmd := exec.Command("zoekt-mirror-gitiles",
					"-exclude", c.Exclude, "-dest", repoDir, "-name", c.Name, c.GitilesURL)
				loggedRun(cmd)
			}
		}
	}
}
<commit_msg>Rerun mirror update when mirror.json 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 main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/fsnotify/fsnotify"
)

type configEntry struct {
	GithubUser string
	GitilesURL string
	Name       string
	Exclude    string
}

func readConfig(filename string) ([]configEntry, error) {
	var result []configEntry

	if filename == "" {
		return result, nil
	}

	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	if err := json.Unmarshal(content, &result); err != nil {
		return nil, err
	}

	return result, nil
}

func watchFile(path string) (<-chan struct{}, error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, err
	}

	if err := watcher.Add(filepath.Dir(path)); err != nil {
		return nil, err
	}

	out := make(chan struct{}, 1)
	go func() {
		var last time.Time
		for {
			select {
			case <-watcher.Events:
				fi, err := os.Stat(path)
				if err == nil && fi.ModTime() != last {
					out <- struct{}{}
					last = fi.ModTime()
				}
			case err := <-watcher.Errors:
				if err != nil {
					log.Printf("watcher error: %v", err)
				}
			}
		}
	}()
	return out, nil
}

func periodicMirror(repoDir string, cfgFile string, interval time.Duration) {
	t := time.NewTicker(interval)
	watcher, err := watchFile(cfgFile)
	if err != nil {
		log.Printf("watchFile(%q): %v", cfgFile, err)
	}

	var lastCfg []configEntry
	for {

		select {
		case <-watcher:
			log.Printf("mirror config %s changed", cfgFile)
		case <-t.C:
		}

		cfg, err := readConfig(cfgFile)
		if err != nil {
			log.Printf("readConfig(%s): %v", cfgFile, err)
			continue
		} else {
			lastCfg = cfg
		}
		for _, c := range lastCfg {
			if c.GithubUser != "" {
				cmd := exec.Command("zoekt-mirror-github", "-user", c.GithubUser, "-name", c.Name,
					"-exclude", c.Exclude, "-dest", repoDir)
				loggedRun(cmd)
			} else if c.GitilesURL != "" {
				cmd := exec.Command("zoekt-mirror-gitiles",
					"-exclude", c.Exclude, "-dest", repoDir, "-name", c.Name, c.GitilesURL)
				loggedRun(cmd)
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2020 Authors of Cilium
//
// 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 cmd

import (
	"context"
	"fmt"
	"net"
	"time"

	flowpb "github.com/cilium/cilium/api/v1/flow"
	"github.com/cilium/cilium/api/v1/models"
	observerpb "github.com/cilium/cilium/api/v1/observer"
	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	"github.com/cilium/cilium/pkg/hubble/listener"
	"github.com/cilium/cilium/pkg/hubble/metrics"
	"github.com/cilium/cilium/pkg/hubble/observer"
	"github.com/cilium/cilium/pkg/hubble/observer/observeroption"
	"github.com/cilium/cilium/pkg/hubble/parser"
	"github.com/cilium/cilium/pkg/hubble/peer"
	"github.com/cilium/cilium/pkg/hubble/server"
	"github.com/cilium/cilium/pkg/hubble/server/serveroption"
	"github.com/cilium/cilium/pkg/identity"
	identitymodel "github.com/cilium/cilium/pkg/identity/model"
	"github.com/cilium/cilium/pkg/ipcache"
	"github.com/cilium/cilium/pkg/loadbalancer"
	"github.com/cilium/cilium/pkg/logging"
	"github.com/cilium/cilium/pkg/logging/logfields"
	"github.com/cilium/cilium/pkg/option"

	"github.com/go-openapi/strfmt"
	"github.com/sirupsen/logrus"
)

func (d *Daemon) getHubbleStatus(ctx context.Context) *models.HubbleStatus {
	if !option.Config.EnableHubble {
		return &models.HubbleStatus{State: models.HubbleStatusStateDisabled}
	}

	if d.hubbleObserver == nil {
		return &models.HubbleStatus{
			State: models.HubbleStatusStateWarning,
			Msg:   "Server not initialized",
		}
	}

	req := &observerpb.ServerStatusRequest{}
	status, err := d.hubbleObserver.ServerStatus(ctx, req)
	if err != nil {
		return &models.HubbleStatus{State: models.HubbleStatusStateFailure, Msg: err.Error()}
	}

	metricsState := models.HubbleStatusMetricsStateDisabled
	if option.Config.HubbleMetricsServer != "" {
		// TODO: The metrics package should be refactored to be able report its actual state
		metricsState = models.HubbleStatusMetricsStateOk
	}

	hubbleStatus := &models.HubbleStatus{
		State: models.StatusStateOk,
		Observer: &models.HubbleStatusObserver{
			CurrentFlows: int64(status.NumFlows),
			MaxFlows:     int64(status.MaxFlows),
			SeenFlows:    int64(status.SeenFlows),
			Uptime:       strfmt.Duration(time.Duration(status.UptimeNs)),
		},
		Metrics: &models.HubbleStatusMetrics{
			State: metricsState,
		},
	}

	return hubbleStatus
}

func (d *Daemon) launchHubble() {
	logger := logging.DefaultLogger.WithField(logfields.LogSubsys, "hubble")
	if !option.Config.EnableHubble {
		logger.Info("Hubble server is disabled")
		return
	}

	payloadParser, err := parser.New(logger, d, d, d, d, d)
	if err != nil {
		logger.WithError(err).Error("Failed to initialize Hubble")
		return
	}
	d.hubbleObserver, err = observer.NewLocalServer(payloadParser, logger,
		observeroption.WithMaxFlows(option.Config.HubbleFlowBufferSize),
		observeroption.WithMonitorBuffer(option.Config.HubbleEventQueueSize),
		observeroption.WithCiliumDaemon(d))
	if err != nil {
		logger.WithError(err).Error("Failed to initialize Hubble")
		return
	}
	go d.hubbleObserver.Start()
	d.monitorAgent.GetMonitor().RegisterNewListener(d.ctx, listener.NewHubbleListener(d.hubbleObserver))

	// configure a local hubble instance that serves more gRPC services
	sockPath := "unix://" + option.Config.HubbleSocketPath
	localSrv, err := server.NewServer(logger,
		serveroption.WithUnixSocketListener(sockPath),
		serveroption.WithHealthService(),
		serveroption.WithObserverService(d.hubbleObserver),
		serveroption.WithPeerService(peer.NewService(d.nodeDiscovery.Manager)),
	)
	if err != nil {
		logger.WithError(err).Error("Failed to initialize local Hubble server")
		return
	}
	logger.WithField("address", sockPath).Info("Starting local Hubble server")
	if err := localSrv.Serve(); err != nil {
		logger.WithError(err).Error("Failed to start local Hubble server")
		return
	}
	go func() {
		<-d.ctx.Done()
		localSrv.Stop()
	}()

	// configure another hubble instance that serve fewer gRPC services
	address := option.Config.HubbleListenAddress
	if address != "" {
		// TODO: remove warning once mutual TLS has been implemented
		logger.WithField("address", address).Warn("Hubble server will be exposing its API insecurely on this address")
		srv, err := server.NewServer(logger,
			serveroption.WithTCPListener(address),
			serveroption.WithHealthService(),
			serveroption.WithObserverService(d.hubbleObserver),
		)
		if err != nil {
			logger.WithError(err).Error("Failed to initialize Hubble server")
			return
		}
		logger.WithField("address", address).Info("Starting Hubble server")
		if err := srv.Serve(); err != nil {
			logger.WithError(err).Error("Failed to start Hubble server")
			return
		}
		go func() {
			<-d.ctx.Done()
			srv.Stop()
		}()
	}

	if option.Config.HubbleMetricsServer != "" {
		logger.WithFields(logrus.Fields{
			"address": option.Config.HubbleMetricsServer,
			"metrics": option.Config.HubbleMetrics,
		}).Info("Starting Hubble Metrics server")
		if err := metrics.EnableMetrics(log, option.Config.HubbleMetricsServer, option.Config.HubbleMetrics); err != nil {
			logger.WithError(err).Warn("Failed to initialize Hubble metrics server")
			return
		}
	}
}

// GetIdentity looks up identity by ID from Cilium's identity cache. Hubble uses the identity info
// to populate source and destination labels of flows.
//
//  - IdentityGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L40
func (d *Daemon) GetIdentity(securityIdentity uint32) (*models.Identity, error) {
	ident := d.identityAllocator.LookupIdentityByID(context.Background(), identity.NumericIdentity(securityIdentity))
	if ident == nil {
		return nil, fmt.Errorf("identity %d not found", securityIdentity)
	}
	return identitymodel.CreateModel(ident), nil
}

// GetEndpointInfo returns endpoint info for a given IP address. Hubble uses this function to populate
// fields like namespace and pod name for local endpoints.
//
//  - EndpointGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L34
func (d *Daemon) GetEndpointInfo(ip net.IP) (endpoint v1.EndpointInfo, ok bool) {
	ep := d.endpointManager.LookupIP(ip)
	if ep == nil {
		return nil, false
	}
	return ep, true
}

// GetNamesOf implements DNSGetter.GetNamesOf. It looks up DNS names of a given IP from the
// FQDN cache of an endpoint specified by sourceEpID.
//
//  - DNSGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L27
func (d *Daemon) GetNamesOf(sourceEpID uint32, ip net.IP) []string {
	ep := d.endpointManager.LookupCiliumID(uint16(sourceEpID))
	if ep == nil {
		return nil
	}
	return ep.DNSHistory.LookupIP(ip)
}

// GetServiceByAddr looks up service by IP/port. Hubble uses this function to annotate flows
// with service information.
//
//  - ServiceGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L52
func (d *Daemon) GetServiceByAddr(ip net.IP, port uint16) (flowpb.Service, bool) {
	addr := loadbalancer.L3n4Addr{
		IP: ip,
		L4Addr: loadbalancer.L4Addr{
			Port: port,
		},
	}
	namespace, name, ok := d.svc.GetServiceNameByAddr(addr)
	if !ok {
		return flowpb.Service{}, false
	}
	return flowpb.Service{
		Namespace: namespace,
		Name:      name,
	}, true
}

// GetK8sMetadata returns the Kubernetes metadata for the given IP address.
// It implements hubble parser's IPGetter.GetK8sMetadata.
func (d *Daemon) GetK8sMetadata(ip net.IP) *ipcache.K8sMetadata {
	if ip == nil {
		return nil
	}
	return ipcache.IPIdentityCache.GetK8sMetadata(ip.String())
}

// LookupSecIDByIP returns the security ID for the given IP. If the security ID
// cannot be found, ok is false.
// It implements hubble parser's IPGetter.LookupSecIDByIP.
func (d *Daemon) LookupSecIDByIP(ip net.IP) (id ipcache.Identity, ok bool) {
	if ip == nil {
		return ipcache.Identity{}, false
	}

	if id, ok = ipcache.IPIdentityCache.LookupByIP(ip.String()); ok {
		return id, ok
	}

	ipv6Prefixes, ipv4Prefixes := d.GetCIDRPrefixLengths()
	prefixes := ipv4Prefixes
	bits := net.IPv4len * 8
	if ip.To4() == nil {
		prefixes = ipv6Prefixes
		bits = net.IPv6len * 8
	}
	for _, prefixLen := range prefixes {
		if prefixLen == bits {
			// IP lookup was already done above; skip it here
			continue
		}
		mask := net.CIDRMask(prefixLen, bits)
		cidr := net.IPNet{
			IP:   ip.Mask(mask),
			Mask: mask,
		}
		if id, ok = ipcache.IPIdentityCache.LookupByPrefix(cidr.String()); ok {
			return id, ok
		}
	}
	return id, false
}
<commit_msg>hubble: enable metrics before starting server<commit_after>// Copyright 2020 Authors of Cilium
//
// 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 cmd

import (
	"context"
	"fmt"
	"net"
	"time"

	flowpb "github.com/cilium/cilium/api/v1/flow"
	"github.com/cilium/cilium/api/v1/models"
	observerpb "github.com/cilium/cilium/api/v1/observer"
	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	"github.com/cilium/cilium/pkg/hubble/listener"
	"github.com/cilium/cilium/pkg/hubble/metrics"
	"github.com/cilium/cilium/pkg/hubble/observer"
	"github.com/cilium/cilium/pkg/hubble/observer/observeroption"
	"github.com/cilium/cilium/pkg/hubble/parser"
	"github.com/cilium/cilium/pkg/hubble/peer"
	"github.com/cilium/cilium/pkg/hubble/server"
	"github.com/cilium/cilium/pkg/hubble/server/serveroption"
	"github.com/cilium/cilium/pkg/identity"
	identitymodel "github.com/cilium/cilium/pkg/identity/model"
	"github.com/cilium/cilium/pkg/ipcache"
	"github.com/cilium/cilium/pkg/loadbalancer"
	"github.com/cilium/cilium/pkg/logging"
	"github.com/cilium/cilium/pkg/logging/logfields"
	"github.com/cilium/cilium/pkg/option"

	"github.com/go-openapi/strfmt"
	"github.com/sirupsen/logrus"
)

func (d *Daemon) getHubbleStatus(ctx context.Context) *models.HubbleStatus {
	if !option.Config.EnableHubble {
		return &models.HubbleStatus{State: models.HubbleStatusStateDisabled}
	}

	if d.hubbleObserver == nil {
		return &models.HubbleStatus{
			State: models.HubbleStatusStateWarning,
			Msg:   "Server not initialized",
		}
	}

	req := &observerpb.ServerStatusRequest{}
	status, err := d.hubbleObserver.ServerStatus(ctx, req)
	if err != nil {
		return &models.HubbleStatus{State: models.HubbleStatusStateFailure, Msg: err.Error()}
	}

	metricsState := models.HubbleStatusMetricsStateDisabled
	if option.Config.HubbleMetricsServer != "" {
		// TODO: The metrics package should be refactored to be able report its actual state
		metricsState = models.HubbleStatusMetricsStateOk
	}

	hubbleStatus := &models.HubbleStatus{
		State: models.StatusStateOk,
		Observer: &models.HubbleStatusObserver{
			CurrentFlows: int64(status.NumFlows),
			MaxFlows:     int64(status.MaxFlows),
			SeenFlows:    int64(status.SeenFlows),
			Uptime:       strfmt.Duration(time.Duration(status.UptimeNs)),
		},
		Metrics: &models.HubbleStatusMetrics{
			State: metricsState,
		},
	}

	return hubbleStatus
}

func (d *Daemon) launchHubble() {
	logger := logging.DefaultLogger.WithField(logfields.LogSubsys, "hubble")
	if !option.Config.EnableHubble {
		logger.Info("Hubble server is disabled")
		return
	}

	if option.Config.HubbleMetricsServer != "" {
		logger.WithFields(logrus.Fields{
			"address": option.Config.HubbleMetricsServer,
			"metrics": option.Config.HubbleMetrics,
		}).Info("Starting Hubble Metrics server")
		if err := metrics.EnableMetrics(log, option.Config.HubbleMetricsServer, option.Config.HubbleMetrics); err != nil {
			logger.WithError(err).Warn("Failed to initialize Hubble metrics server")
			return
		}
	}

	payloadParser, err := parser.New(logger, d, d, d, d, d)
	if err != nil {
		logger.WithError(err).Error("Failed to initialize Hubble")
		return
	}
	d.hubbleObserver, err = observer.NewLocalServer(payloadParser, logger,
		observeroption.WithMaxFlows(option.Config.HubbleFlowBufferSize),
		observeroption.WithMonitorBuffer(option.Config.HubbleEventQueueSize),
		observeroption.WithCiliumDaemon(d))
	if err != nil {
		logger.WithError(err).Error("Failed to initialize Hubble")
		return
	}
	go d.hubbleObserver.Start()
	d.monitorAgent.GetMonitor().RegisterNewListener(d.ctx, listener.NewHubbleListener(d.hubbleObserver))

	// configure a local hubble instance that serves more gRPC services
	sockPath := "unix://" + option.Config.HubbleSocketPath
	localSrv, err := server.NewServer(logger,
		serveroption.WithUnixSocketListener(sockPath),
		serveroption.WithHealthService(),
		serveroption.WithObserverService(d.hubbleObserver),
		serveroption.WithPeerService(peer.NewService(d.nodeDiscovery.Manager)),
	)
	if err != nil {
		logger.WithError(err).Error("Failed to initialize local Hubble server")
		return
	}
	logger.WithField("address", sockPath).Info("Starting local Hubble server")
	if err := localSrv.Serve(); err != nil {
		logger.WithError(err).Error("Failed to start local Hubble server")
		return
	}
	go func() {
		<-d.ctx.Done()
		localSrv.Stop()
	}()

	// configure another hubble instance that serve fewer gRPC services
	address := option.Config.HubbleListenAddress
	if address != "" {
		// TODO: remove warning once mutual TLS has been implemented
		logger.WithField("address", address).Warn("Hubble server will be exposing its API insecurely on this address")
		srv, err := server.NewServer(logger,
			serveroption.WithTCPListener(address),
			serveroption.WithHealthService(),
			serveroption.WithObserverService(d.hubbleObserver),
		)
		if err != nil {
			logger.WithError(err).Error("Failed to initialize Hubble server")
			return
		}
		logger.WithField("address", address).Info("Starting Hubble server")
		if err := srv.Serve(); err != nil {
			logger.WithError(err).Error("Failed to start Hubble server")
			return
		}
		go func() {
			<-d.ctx.Done()
			srv.Stop()
		}()
	}
}

// GetIdentity looks up identity by ID from Cilium's identity cache. Hubble uses the identity info
// to populate source and destination labels of flows.
//
//  - IdentityGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L40
func (d *Daemon) GetIdentity(securityIdentity uint32) (*models.Identity, error) {
	ident := d.identityAllocator.LookupIdentityByID(context.Background(), identity.NumericIdentity(securityIdentity))
	if ident == nil {
		return nil, fmt.Errorf("identity %d not found", securityIdentity)
	}
	return identitymodel.CreateModel(ident), nil
}

// GetEndpointInfo returns endpoint info for a given IP address. Hubble uses this function to populate
// fields like namespace and pod name for local endpoints.
//
//  - EndpointGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L34
func (d *Daemon) GetEndpointInfo(ip net.IP) (endpoint v1.EndpointInfo, ok bool) {
	ep := d.endpointManager.LookupIP(ip)
	if ep == nil {
		return nil, false
	}
	return ep, true
}

// GetNamesOf implements DNSGetter.GetNamesOf. It looks up DNS names of a given IP from the
// FQDN cache of an endpoint specified by sourceEpID.
//
//  - DNSGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L27
func (d *Daemon) GetNamesOf(sourceEpID uint32, ip net.IP) []string {
	ep := d.endpointManager.LookupCiliumID(uint16(sourceEpID))
	if ep == nil {
		return nil
	}
	return ep.DNSHistory.LookupIP(ip)
}

// GetServiceByAddr looks up service by IP/port. Hubble uses this function to annotate flows
// with service information.
//
//  - ServiceGetter: https://github.com/cilium/hubble/blob/04ab72591faca62a305ce0715108876167182e04/pkg/parser/getters/getters.go#L52
func (d *Daemon) GetServiceByAddr(ip net.IP, port uint16) (flowpb.Service, bool) {
	addr := loadbalancer.L3n4Addr{
		IP: ip,
		L4Addr: loadbalancer.L4Addr{
			Port: port,
		},
	}
	namespace, name, ok := d.svc.GetServiceNameByAddr(addr)
	if !ok {
		return flowpb.Service{}, false
	}
	return flowpb.Service{
		Namespace: namespace,
		Name:      name,
	}, true
}

// GetK8sMetadata returns the Kubernetes metadata for the given IP address.
// It implements hubble parser's IPGetter.GetK8sMetadata.
func (d *Daemon) GetK8sMetadata(ip net.IP) *ipcache.K8sMetadata {
	if ip == nil {
		return nil
	}
	return ipcache.IPIdentityCache.GetK8sMetadata(ip.String())
}

// LookupSecIDByIP returns the security ID for the given IP. If the security ID
// cannot be found, ok is false.
// It implements hubble parser's IPGetter.LookupSecIDByIP.
func (d *Daemon) LookupSecIDByIP(ip net.IP) (id ipcache.Identity, ok bool) {
	if ip == nil {
		return ipcache.Identity{}, false
	}

	if id, ok = ipcache.IPIdentityCache.LookupByIP(ip.String()); ok {
		return id, ok
	}

	ipv6Prefixes, ipv4Prefixes := d.GetCIDRPrefixLengths()
	prefixes := ipv4Prefixes
	bits := net.IPv4len * 8
	if ip.To4() == nil {
		prefixes = ipv6Prefixes
		bits = net.IPv6len * 8
	}
	for _, prefixLen := range prefixes {
		if prefixLen == bits {
			// IP lookup was already done above; skip it here
			continue
		}
		mask := net.CIDRMask(prefixLen, bits)
		cidr := net.IPNet{
			IP:   ip.Mask(mask),
			Mask: mask,
		}
		if id, ok = ipcache.IPIdentityCache.LookupByPrefix(cidr.String()); ok {
			return id, ok
		}
	}
	return id, false
}
<|endoftext|>


<commit_before>// Package xjs provides some simple, but often needed shortcut funcs for gopherJS
package xjs

import (
	"fmt"
	"strings"

	"honnef.co/go/js/dom"
)

var docNode = dom.GetWindow().Document()

// DocumentFragment returns a new DocumentFragment as a dom.Node
func DocumentFragment() dom.Node {
	return docNode.Underlying().Call("createDocumentFragment")
}

// RemoveChildren removes all of the child nodes of the node given
func RemoveChildren(node dom.Node) dom.Node {
	for node.HasChildNodes() {
		node.RemoveChild(node.LastChild())
	}
	return node
}

// SetInnerText removes all child nodes from the given node and sets a single
// Text Node with the given string
func SetInnerText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	node.AppendChild(TextNode(text))
	return node
}

// SetPreText does similar to SetInnerText, but linebreaks are converted to
s
func SetPreText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	for n, part := range strings.Split(text, "\n") {
		if n > 0 {
			node.AppendChild(CreateElement("br"))
		}
		node.AppendChild(TextNode(part))
	}
	return node
}

// CreateElement is a shortcut to create an element with the given name
func CreateElement(name string) dom.Element {
	return dom.GetWindow().Document().CreateElement(name)
}

// Alert provides for formated alert boxes
func Alert(format string, params ...interface{}) {
	dom.GetWindow().Alert(fmt.Sprintf(format, params...))
}

// TextNode creates a text node containing the givin text
func TextNode(text string) *dom.Text {
	return docNode.CreateTextNode(text)
}
<commit_msg>Renamed TextNode -> Text<commit_after>// Package xjs provides some simple, but often needed shortcut funcs for gopherJS
package xjs

import (
	"fmt"
	"strings"

	"honnef.co/go/js/dom"
)

var docNode = dom.GetWindow().Document()

// DocumentFragment returns a new DocumentFragment as a dom.Node
func DocumentFragment() dom.Node {
	return docNode.Underlying().Call("createDocumentFragment")
}

// RemoveChildren removes all of the child nodes of the node given
func RemoveChildren(node dom.Node) dom.Node {
	for node.HasChildNodes() {
		node.RemoveChild(node.LastChild())
	}
	return node
}

// SetInnerText removes all child nodes from the given node and sets a single
// Text Node with the given string
func SetInnerText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	node.AppendChild(Text(text))
	return node
}

// SetPreText does similar to SetInnerText, but linebreaks are converted to
s
func SetPreText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	for n, part := range strings.Split(text, "\n") {
		if n > 0 {
			node.AppendChild(CreateElement("br"))
		}
		node.AppendChild(Text(part))
	}
	return node
}

// CreateElement is a shortcut to create an element with the given name
func CreateElement(name string) dom.Element {
	return dom.GetWindow().Document().CreateElement(name)
}

// Alert provides for formated alert boxes
func Alert(format string, params ...interface{}) {
	dom.GetWindow().Alert(fmt.Sprintf(format, params...))
}

// TextNode creates a text node containing the givin text
func Text(text string) *dom.Text {
	return docNode.CreateTextNode(text)
}
<|endoftext|>


<commit_before>// Package xjs provides some simple, but often needed shortcut funcs for gopherJS
package xjs

import (
	"fmt"
	"strings"

	"honnef.co/go/js/dom"
)

var docNode = dom.GetWindow().Document()

// Get the document's body element
func Body() dom.HTMLElement {
	return docNode.(dom.HTMLDocument).Body()
}

// DocumentFragment returns a new DocumentFragment as a dom.Node
func DocumentFragment() dom.Node {
	return dom.WrapNode(docNode.Underlying().Call("createDocumentFragment"))
}

// RemoveChildren removes all of the child nodes of the node given
func RemoveChildren(node dom.Node) dom.Node {
	for node.HasChildNodes() {
		node.RemoveChild(node.LastChild())
	}
	return node
}

// SetInnerText removes all child nodes from the given node and sets a single
// Text Node with the given string
func SetInnerText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	node.AppendChild(Text(text))
	return node
}

// SetPreText does similar to SetInnerText, but linebreaks are converted to
s
func SetPreText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	for n, part := range strings.Split(text, "\n") {
		if n > 0 {
			node.AppendChild(CreateElement("br"))
		}
		node.AppendChild(Text(part))
	}
	return node
}

// CreateElement is a shortcut to create an element with the given name
func CreateElement(name string) dom.Element {
	return dom.GetWindow().Document().CreateElement(name)
}

// Alert provides for formated alert boxes
func Alert(format string, params ...interface{}) {
	dom.GetWindow().Alert(fmt.Sprintf(format, params...))
}

// TextNode creates a text node containing the givin text
func Text(text string) *dom.Text {
	return docNode.CreateTextNode(text)
}

// AppendChildren appends all the given children to the parent.
//
// It uses a DocumentFragment to avoid multiple paint updates to a page
func AppendChildren(parent dom.Node, children ...dom.Node) dom.Node {
	for _, child := range children {
		parent.AppendChild(child)
	}
	return parent
}
<commit_msg>Corrected comment<commit_after>// Package xjs provides some simple, but often needed shortcut funcs for gopherJS
package xjs

import (
	"fmt"
	"strings"

	"honnef.co/go/js/dom"
)

var docNode = dom.GetWindow().Document()

// Get the document's body element
func Body() dom.HTMLElement {
	return docNode.(dom.HTMLDocument).Body()
}

// DocumentFragment returns a new DocumentFragment as a dom.Node
func DocumentFragment() dom.Node {
	return dom.WrapNode(docNode.Underlying().Call("createDocumentFragment"))
}

// RemoveChildren removes all of the child nodes of the node given
func RemoveChildren(node dom.Node) dom.Node {
	for node.HasChildNodes() {
		node.RemoveChild(node.LastChild())
	}
	return node
}

// SetInnerText removes all child nodes from the given node and sets a single
// Text Node with the given string
func SetInnerText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	node.AppendChild(Text(text))
	return node
}

// SetPreText does similar to SetInnerText, but linebreaks are converted to
s
func SetPreText(node dom.Node, text string) dom.Node {
	RemoveChildren(node)
	for n, part := range strings.Split(text, "\n") {
		if n > 0 {
			node.AppendChild(CreateElement("br"))
		}
		node.AppendChild(Text(part))
	}
	return node
}

// CreateElement is a shortcut to create an element with the given name
func CreateElement(name string) dom.Element {
	return dom.GetWindow().Document().CreateElement(name)
}

// Alert provides for formated alert boxes
func Alert(format string, params ...interface{}) {
	dom.GetWindow().Alert(fmt.Sprintf(format, params...))
}

// TextNode creates a text node containing the givin text
func Text(text string) *dom.Text {
	return docNode.CreateTextNode(text)
}

// AppendChildren appends all the given children to the parent.
func AppendChildren(parent dom.Node, children ...dom.Node) dom.Node {
	for _, child := range children {
		parent.AppendChild(child)
	}
	return parent
}
<|endoftext|>


<commit_before>package yaurtww

import (
	"log"

	flag "github.com/docker/docker/pkg/mflag"
)

type Manifest struct {
	Version string
	Assets  []ManifestAsset
}

type ManifestAsset struct {
	MD5Sum   string
	FileName string
}

// const CDN_URL = "http://cdn.urbanterror.info/urt/%s/%s/q3ut4/%s"
const CDN_URL = "http://cdn.urbanterror.info/urt/"

var (
	ManifestPath *string
	DownloadPath = flag.String([]string{"d", "-dest"}, "./", "Path to destination directory")
	Version      = flag.Bool([]string{"v", "-version"}, false, "Print the name and version")
)

func init() {
	ManifestPath = flag.String([]string{"m", "-manifest"}, RequiredFlag("Manifest is required."), "Path to yaurtww manifest")
}

func RequiredFlag(ErrorMessage string) string {
	// shim to trick the compiler so that we can actually call os.Exit(1) and
	// print a helpful error message when a flag is required.
	log.Fatalln(ErrorMessage)
	return "requiredstring"
}
<commit_msg>init ReadManifest()<commit_after>package yaurtww

import (
	"io/ioutil"
	"log"

	flag "github.com/docker/docker/pkg/mflag"
)

type Manifest struct {
	Version string
	Assets  []ManifestAsset
}

type ManifestAsset struct {
	MD5Sum   string
	FileName string
}

// const CDN_URL = "http://cdn.urbanterror.info/urt/%s/%s/q3ut4/%s"
const CDN_URL = "http://cdn.urbanterror.info/urt/"

var (
	ManifestPath *string
	DownloadPath = flag.String([]string{"d", "-dest"}, "./", "Path to destination directory")
	Version      = flag.Bool([]string{"v", "-version"}, false, "Print the name and version")
)

func init() {
	ManifestPath = flag.String([]string{"m", "-manifest"}, RequiredFlag("Manifest is required."), "Path to yaurtww manifest")
}

func RequiredFlag(ErrorMessage string) string {
	// shim to trick the compiler so that we can actually call os.Exit(1) and
	// print a helpful error message when a flag is required.
	log.Fatalln(ErrorMessage)
	return "requiredstring"
}

func ReadManifest(path *string) (*Manifest, error) {
	var manifest = Manifest{}
	file, err := ioutil.ReadFile(*path)
	if err != nil {
		return manifest, err
	}
	return manifest, nil
}
<|endoftext|>


<commit_before>// Copyright 2016
// 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 server

import (
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
	"github.com/nhurel/dim/lib/utils"
)

// GetAuthorization finds the first Authorization matching the request
func GetAuthorization(req *http.Request, auths []*Authorization) *Authorization {
	for _, auth := range auths {
		if auth.Applies(req) {
			return auth
		}
	}
	return nil
}

func securityFilter(cfg *Config, hf http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		auth := GetAuthorization(r, cfg.Authorizations)
		if auth != nil {
			if err := grantAccess(r, auth); err != nil {
				u, _, _ := r.BasicAuth()
				logrus.WithFields(logrus.Fields{"username": u, "url": r.URL}).Infoln("Rejecting request")
				http.Error(w, err.Error(), http.StatusForbidden)
				return
			}
		}
		hf(w, r)
	}
}

func grantAccess(req *http.Request, auth *Authorization) error {
	if auth.Username != "" {
		u, p, ok := req.BasicAuth()
		if ok {
			if u == auth.Username && utils.Sha256(p) == auth.Password {
				return nil
			}
		}
		return fmt.Errorf("You are not allowed to access URLs matching %s", auth.Path)
	}
	return nil
}
<commit_msg>Return HTTP code 401 instead of 403 when rejecting a request #patch<commit_after>// Copyright 2016
// 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 server

import (
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
	"github.com/nhurel/dim/lib/utils"
)

// GetAuthorization finds the first Authorization matching the request
func GetAuthorization(req *http.Request, auths []*Authorization) *Authorization {
	for _, auth := range auths {
		if auth.Applies(req) {
			return auth
		}
	}
	return nil
}

func securityFilter(cfg *Config, hf http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		auth := GetAuthorization(r, cfg.Authorizations)
		if auth != nil {
			if err := grantAccess(r, auth); err != nil {
				u, _, _ := r.BasicAuth()
				logrus.WithFields(logrus.Fields{"username": u, "url": r.URL}).Infoln("Rejecting request")
				http.Error(w, err.Error(), http.StatusUnauthorized)
				return
			}
		}
		hf(w, r)
	}
}

func grantAccess(req *http.Request, auth *Authorization) error {
	if auth.Username != "" {
		u, p, ok := req.BasicAuth()
		if ok {
			if u == auth.Username && utils.Sha256(p) == auth.Password {
				return nil
			}
		}
		return fmt.Errorf("You are not allowed to access URLs matching %s", auth.Path)
	}
	return nil
}
<|endoftext|>


<commit_before>package config

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"strings"

	"github.com/EngineerBetter/concourse-up/iaas"
)

const terraformStateFileName = "terraform.tfstate"
const configFilePath = "config.json"

// IClient is an interface for the config file client
type IClient interface {
	Load() (Config, error)
	DeleteAll(config Config) error
	LoadOrCreate(deployArgs *DeployArgs) (Config, bool, error)
	Update(Config) error
	StoreAsset(filename string, contents []byte) error
	HasAsset(filename string) (bool, error)
	LoadAsset(filename string) ([]byte, error)
	DeleteAsset(filename string) error
}

// Client is a client for loading the config file  from S3
type Client struct {
	Iaas         iaas.IClient
	Project      string
	Namespace    string
	BucketName   string
	BucketExists bool
	BucketError  error
}

// New instantiates a new client
func New(iaas iaas.IClient, project, namespace string) *Client {
	namespace = determineNamespace(namespace, iaas.Region())
	bucketName, exists, err := determineBucketName(iaas, namespace, project)

	return &Client{
		iaas,
		project,
		namespace,
		bucketName,
		exists,
		err,
	}
}

// StoreAsset stores an associated configuration file
func (client *Client) StoreAsset(filename string, contents []byte) error {
	return client.Iaas.WriteFile(client.configBucket(),
		filename,
		contents,
	)
}

// LoadAsset loads an associated configuration file
func (client *Client) LoadAsset(filename string) ([]byte, error) {
	return client.Iaas.LoadFile(
		client.configBucket(),
		filename,
	)
}

// DeleteAsset deletes an associated configuration file
func (client *Client) DeleteAsset(filename string) error {
	return client.Iaas.DeleteFile(
		client.configBucket(),
		filename,
	)
}

// HasAsset returns true if an associated configuration file exists
func (client *Client) HasAsset(filename string) (bool, error) {
	return client.Iaas.HasFile(
		client.configBucket(),
		filename,
	)
}

// Update stores the conconcourse up config file to S3
func (client *Client) Update(config Config) error {
	bytes, err := json.Marshal(config)
	if err != nil {
		return err
	}

	return client.Iaas.WriteFile(client.configBucket(), configFilePath, bytes)
}

// DeleteAll deletes the entire configuration bucket
func (client *Client) DeleteAll(config Config) error {
	return client.Iaas.DeleteVersionedBucket(config.ConfigBucket)
}

// Load loads an existing config file from S3
func (client *Client) Load() (Config, error) {
	if client.BucketError != nil {
		return Config{}, client.BucketError
	}
	configBytes, err := client.Iaas.LoadFile(
		client.configBucket(),
		configFilePath,
	)
	if err != nil {
		return Config{}, err
	}

	conf := Config{}
	if err := json.Unmarshal(configBytes, &conf); err != nil {
		return Config{}, err
	}

	return conf, nil
}

// LoadOrCreate loads an existing config file from S3, or creates a default if one doesn't already exist
func (client *Client) LoadOrCreate(deployArgs *DeployArgs) (Config, bool, error) {
	if client.BucketError != nil {
		return Config{}, false, client.BucketError
	}

	config, err := generateDefaultConfig(
		deployArgs.IAAS,
		client.Project,
		deployment(client.Project),
		client.configBucket(),
		deployArgs.AWSRegion,
		client.Namespace,
	)
	if err != nil {
		return Config{}, false, err
	}
	defaultConfigBytes, err := json.Marshal(&config)
	if err != nil {
		return Config{}, false, err
	}

	if !client.BucketExists {
		err = client.Iaas.CreateBucket(client.configBucket())
		if err != nil {
			return Config{}, false, err
		}
	}

	configBytes, createdNewFile, err := client.Iaas.EnsureFileExists(
		client.configBucket(),
		configFilePath,
		defaultConfigBytes,
	)

	if err != nil {
		return Config{}, createdNewFile, err
	}
	err = json.Unmarshal(configBytes, &config)
	if err != nil {
		return Config{}, createdNewFile, err
	}
	allow, err := parseCIDRBlocks(deployArgs.AllowIPs)
	if err != nil {
		return Config{}, createdNewFile, err
	}
	config, err = updateAllowedIPs(config, DBSizes[deployArgs.DBSize], allow)
	if err != nil {
		return Config{}, createdNewFile, err
	}
	if deployArgs.GithubAuthIsSet {
		config.GithubClientID = deployArgs.GithubAuthClientID
		config.GithubClientSecret = deployArgs.GithubAuthClientSecret
		config.GithubAuthIsSet = deployArgs.GithubAuthIsSet
	}
	config.Spot = deployArgs.Spot
	if deployArgs.TagsIsSet {
		config.Tags = deployArgs.Tags
		config.TagsIsSet = deployArgs.TagsIsSet
	}
	return config, createdNewFile, nil
}

func (client *Client) configBucket() string {
	return client.BucketName
}

func deployment(project string) string {
	return fmt.Sprintf("concourse-up-%s", project)
}

func createBucketName(deployment, extension string) string {
	return fmt.Sprintf("%s-%s-config", deployment, extension)
}

func determineBucketName(iaas iaas.IClient, namespace, project string) (string, bool, error) {
	regionBucketName := createBucketName(deployment(project), iaas.Region())
	namespaceBucketName := createBucketName(deployment(project), namespace)

	foundRegionNamedBucket, err := iaas.BucketExists(regionBucketName)
	if err != nil {
		return "", false, err
	}
	foundNamespacedBucket, err := iaas.BucketExists(namespaceBucketName)
	if err != nil {
		return "", false, err
	}

	foundOne := foundRegionNamedBucket || foundNamespacedBucket

	switch {
	case !foundRegionNamedBucket && foundNamespacedBucket:
		return namespaceBucketName, foundOne, nil
	case foundRegionNamedBucket && !foundNamespacedBucket:
		return regionBucketName, foundOne, nil
	case foundRegionNamedBucket && foundNamespacedBucket && iaas.Region() != namespace:
		return "", foundOne, fmt.Errorf("found both region %q and namespaced %q buckets for %q deployment", regionBucketName, namespaceBucketName, project)
	default:
		return namespaceBucketName, foundOne, nil
	}
}

type cidrBlocks []*net.IPNet

func parseCIDRBlocks(s string) (cidrBlocks, error) {
	var x cidrBlocks
	for _, ip := range strings.Split(s, ",") {
		ip = strings.TrimSpace(ip)
		_, ipNet, err := net.ParseCIDR(ip)
		if err != nil {
			ipNet = &net.IPNet{
				IP:   net.ParseIP(ip),
				Mask: net.CIDRMask(32, 32),
			}
		}
		if ipNet.IP == nil {
			return nil, fmt.Errorf("could not parse %q as an IP address or CIDR range", ip)
		}
		x = append(x, ipNet)
	}
	return x, nil
}

func (b cidrBlocks) String() (string, error) {
	var buf bytes.Buffer
	for i, ipNet := range b {
		if i > 0 {
			_, err := fmt.Fprintf(&buf, ", %q", ipNet)
			if err != nil {
				return "", err
			}
		} else {
			_, err := fmt.Fprintf(&buf, "%q", ipNet)
			if err != nil {
				return "", err
			}
		}
	}
	return buf.String(), nil
}

func determineNamespace(namespace, region string) string {
	if namespace == "" {
		return region
	}
	return namespace
}
<commit_msg>unecessary case in determineBucketName being removed<commit_after>package config

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"strings"

	"github.com/EngineerBetter/concourse-up/iaas"
)

const terraformStateFileName = "terraform.tfstate"
const configFilePath = "config.json"

// IClient is an interface for the config file client
type IClient interface {
	Load() (Config, error)
	DeleteAll(config Config) error
	LoadOrCreate(deployArgs *DeployArgs) (Config, bool, error)
	Update(Config) error
	StoreAsset(filename string, contents []byte) error
	HasAsset(filename string) (bool, error)
	LoadAsset(filename string) ([]byte, error)
	DeleteAsset(filename string) error
}

// Client is a client for loading the config file  from S3
type Client struct {
	Iaas         iaas.IClient
	Project      string
	Namespace    string
	BucketName   string
	BucketExists bool
	BucketError  error
}

// New instantiates a new client
func New(iaas iaas.IClient, project, namespace string) *Client {
	namespace = determineNamespace(namespace, iaas.Region())
	bucketName, exists, err := determineBucketName(iaas, namespace, project)

	return &Client{
		iaas,
		project,
		namespace,
		bucketName,
		exists,
		err,
	}
}

// StoreAsset stores an associated configuration file
func (client *Client) StoreAsset(filename string, contents []byte) error {
	return client.Iaas.WriteFile(client.configBucket(),
		filename,
		contents,
	)
}

// LoadAsset loads an associated configuration file
func (client *Client) LoadAsset(filename string) ([]byte, error) {
	return client.Iaas.LoadFile(
		client.configBucket(),
		filename,
	)
}

// DeleteAsset deletes an associated configuration file
func (client *Client) DeleteAsset(filename string) error {
	return client.Iaas.DeleteFile(
		client.configBucket(),
		filename,
	)
}

// HasAsset returns true if an associated configuration file exists
func (client *Client) HasAsset(filename string) (bool, error) {
	return client.Iaas.HasFile(
		client.configBucket(),
		filename,
	)
}

// Update stores the conconcourse up config file to S3
func (client *Client) Update(config Config) error {
	bytes, err := json.Marshal(config)
	if err != nil {
		return err
	}

	return client.Iaas.WriteFile(client.configBucket(), configFilePath, bytes)
}

// DeleteAll deletes the entire configuration bucket
func (client *Client) DeleteAll(config Config) error {
	return client.Iaas.DeleteVersionedBucket(config.ConfigBucket)
}

// Load loads an existing config file from S3
func (client *Client) Load() (Config, error) {
	if client.BucketError != nil {
		return Config{}, client.BucketError
	}
	configBytes, err := client.Iaas.LoadFile(
		client.configBucket(),
		configFilePath,
	)
	if err != nil {
		return Config{}, err
	}

	conf := Config{}
	if err := json.Unmarshal(configBytes, &conf); err != nil {
		return Config{}, err
	}

	return conf, nil
}

// LoadOrCreate loads an existing config file from S3, or creates a default if one doesn't already exist
func (client *Client) LoadOrCreate(deployArgs *DeployArgs) (Config, bool, error) {
	if client.BucketError != nil {
		return Config{}, false, client.BucketError
	}

	config, err := generateDefaultConfig(
		deployArgs.IAAS,
		client.Project,
		deployment(client.Project),
		client.configBucket(),
		deployArgs.AWSRegion,
		client.Namespace,
	)
	if err != nil {
		return Config{}, false, err
	}
	defaultConfigBytes, err := json.Marshal(&config)
	if err != nil {
		return Config{}, false, err
	}

	if !client.BucketExists {
		err = client.Iaas.CreateBucket(client.configBucket())
		if err != nil {
			return Config{}, false, err
		}
	}

	configBytes, createdNewFile, err := client.Iaas.EnsureFileExists(
		client.configBucket(),
		configFilePath,
		defaultConfigBytes,
	)
	if err != nil {
		return Config{}, createdNewFile, err
	}

	err = json.Unmarshal(configBytes, &config)
	if err != nil {
		return Config{}, createdNewFile, err
	}

	allow, err := parseCIDRBlocks(deployArgs.AllowIPs)
	if err != nil {
		return Config{}, createdNewFile, err
	}

	config, err = updateAllowedIPs(config, DBSizes[deployArgs.DBSize], allow)
	if err != nil {
		return Config{}, createdNewFile, err
	}

	if deployArgs.GithubAuthIsSet {
		config.GithubClientID = deployArgs.GithubAuthClientID
		config.GithubClientSecret = deployArgs.GithubAuthClientSecret
		config.GithubAuthIsSet = deployArgs.GithubAuthIsSet
	}
	config.Spot = deployArgs.Spot
	if deployArgs.TagsIsSet {
		config.Tags = deployArgs.Tags
		config.TagsIsSet = deployArgs.TagsIsSet
	}
	return config, createdNewFile, nil
}

func (client *Client) configBucket() string {
	return client.BucketName
}

func deployment(project string) string {
	return fmt.Sprintf("concourse-up-%s", project)
}

func createBucketName(deployment, extension string) string {
	return fmt.Sprintf("%s-%s-config", deployment, extension)
}

func determineBucketName(iaas iaas.IClient, namespace, project string) (string, bool, error) {
	regionBucketName := createBucketName(deployment(project), iaas.Region())
	namespaceBucketName := createBucketName(deployment(project), namespace)

	foundRegionNamedBucket, err := iaas.BucketExists(regionBucketName)
	if err != nil {
		return "", false, err
	}
	foundNamespacedBucket, err := iaas.BucketExists(namespaceBucketName)
	if err != nil {
		return "", false, err
	}

	foundOne := foundRegionNamedBucket || foundNamespacedBucket

	switch {
	case !foundRegionNamedBucket && foundNamespacedBucket:
		return namespaceBucketName, foundOne, nil
	case foundRegionNamedBucket && !foundNamespacedBucket:
		return regionBucketName, foundOne, nil
	default:
		return namespaceBucketName, foundOne, nil
	}
}

type cidrBlocks []*net.IPNet

func parseCIDRBlocks(s string) (cidrBlocks, error) {
	var x cidrBlocks
	for _, ip := range strings.Split(s, ",") {
		ip = strings.TrimSpace(ip)
		_, ipNet, err := net.ParseCIDR(ip)
		if err != nil {
			ipNet = &net.IPNet{
				IP:   net.ParseIP(ip),
				Mask: net.CIDRMask(32, 32),
			}
		}
		if ipNet.IP == nil {
			return nil, fmt.Errorf("could not parse %q as an IP address or CIDR range", ip)
		}
		x = append(x, ipNet)
	}
	return x, nil
}

func (b cidrBlocks) String() (string, error) {
	var buf bytes.Buffer
	for i, ipNet := range b {
		if i > 0 {
			_, err := fmt.Fprintf(&buf, ", %q", ipNet)
			if err != nil {
				return "", err
			}
		} else {
			_, err := fmt.Fprintf(&buf, "%q", ipNet)
			if err != nil {
				return "", err
			}
		}
	}
	return buf.String(), nil
}

func determineNamespace(namespace, region string) string {
	if namespace == "" {
		return region
	}
	return namespace
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

// Package config implements the configuration for a BitTorrent tracker
package config

import (
	"encoding/json"
	"io"
	"os"
	"time"
)

// Duration wraps a time.Duration and adds JSON marshalling.
type Duration struct{ time.Duration }

// MarshalJSON transforms a duration into JSON.
func (d *Duration) MarshalJSON() ([]byte, error) {
	return json.Marshal(d.String())
}

// UnmarshalJSON transform JSON into a Duration.
func (d *Duration) UnmarshalJSON(b []byte) error {
	var str string
	err := json.Unmarshal(b, &str)
	d.Duration, err = time.ParseDuration(str)
	return err
}

// DriverConfig is the configuration used to connect to a tracker.Driver or
// a backend.Driver.
type DriverConfig struct {
	Name   string            `json:"driver"`
	Params map[string]string `json:"params,omitempty"`
}

// Config is a configuration for a Server.
type Config struct {
	Addr    string       `json:"addr"`
	Tracker DriverConfig `json:"tracker"`
	Backend DriverConfig `json:"backend"`

	Private   bool `json:"private"`
	Freeleech bool `json:"freeleech"`
	Whitelist bool `json:"whitelist"`

	Announce        Duration `json:"announce"`
	MinAnnounce     Duration `json:"min_announce"`
	RequestTimeout  Duration `json:"request_timeout"`
	NumWantFallback int      `json:"default_num_want"`
}

var DefaultConfig = Config{
	Addr: ":6881",
	Tracker: DriverConfig{
		Name: "mock",
	},
	Backend: DriverConfig{
		Name: "mock",
	},
	Private:         false,
	Freeleech:       false,
	Whitelist:       false,
	Announce:        Duration{30 * time.Minute},
	MinAnnounce:     Duration{15 * time.Minute},
	RequestTimeout:  Duration{10 * time.Second},
	NumWantFallback: 50,
}

// Open is a shortcut to open a file, read it, and generate a Config.
// It supports relative and absolute paths. Given "", it returns the result of
// New.
func Open(path string) (*Config, error) {
	if path == "" {
		return &DefaultConfig, nil
	}

	f, err := os.Open(os.ExpandEnv(path))
	if err != nil {
		return nil, err
	}
	defer f.Close()

	conf, err := Decode(f)
	if err != nil {
		return nil, err
	}
	return conf, nil
}

// Decode attempts to decode a JSON encoded reader into a *Config.
func Decode(r io.Reader) (*Config, error) {
	conf := &Config{}
	err := json.NewDecoder(r).Decode(conf)
	if err != nil {
		return nil, err
	}
	return conf, nil
}
<commit_msg>default to addr 127.0.0.1:6881<commit_after>// Copyright 2014 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

// Package config implements the configuration for a BitTorrent tracker
package config

import (
	"encoding/json"
	"io"
	"os"
	"time"
)

// Duration wraps a time.Duration and adds JSON marshalling.
type Duration struct{ time.Duration }

// MarshalJSON transforms a duration into JSON.
func (d *Duration) MarshalJSON() ([]byte, error) {
	return json.Marshal(d.String())
}

// UnmarshalJSON transform JSON into a Duration.
func (d *Duration) UnmarshalJSON(b []byte) error {
	var str string
	err := json.Unmarshal(b, &str)
	d.Duration, err = time.ParseDuration(str)
	return err
}

// DriverConfig is the configuration used to connect to a tracker.Driver or
// a backend.Driver.
type DriverConfig struct {
	Name   string            `json:"driver"`
	Params map[string]string `json:"params,omitempty"`
}

// Config is a configuration for a Server.
type Config struct {
	Addr    string       `json:"addr"`
	Tracker DriverConfig `json:"tracker"`
	Backend DriverConfig `json:"backend"`

	Private   bool `json:"private"`
	Freeleech bool `json:"freeleech"`
	Whitelist bool `json:"whitelist"`

	Announce        Duration `json:"announce"`
	MinAnnounce     Duration `json:"min_announce"`
	RequestTimeout  Duration `json:"request_timeout"`
	NumWantFallback int      `json:"default_num_want"`
}

var DefaultConfig = Config{
	Addr: "127.0.0.1:6881",
	Tracker: DriverConfig{
		Name: "mock",
	},
	Backend: DriverConfig{
		Name: "mock",
	},
	Private:         false,
	Freeleech:       false,
	Whitelist:       false,
	Announce:        Duration{30 * time.Minute},
	MinAnnounce:     Duration{15 * time.Minute},
	RequestTimeout:  Duration{10 * time.Second},
	NumWantFallback: 50,
}

// Open is a shortcut to open a file, read it, and generate a Config.
// It supports relative and absolute paths. Given "", it returns the result of
// New.
func Open(path string) (*Config, error) {
	if path == "" {
		return &DefaultConfig, nil
	}

	f, err := os.Open(os.ExpandEnv(path))
	if err != nil {
		return nil, err
	}
	defer f.Close()

	conf, err := Decode(f)
	if err != nil {
		return nil, err
	}
	return conf, nil
}

// Decode attempts to decode a JSON encoded reader into a *Config.
func Decode(r io.Reader) (*Config, error) {
	conf := &Config{}
	err := json.NewDecoder(r).Decode(conf)
	if err != nil {
		return nil, err
	}
	return conf, nil
}
<|endoftext|>


<commit_before>package config

import (
	//"encoding/json"
	//"fmt"
	"github.com/pr8kerl/f5er/f5"
	"io/ioutil"
	"log"
	"path/filepath"
	"gopkg.in/yaml.v2"
)

type Rule struct {
	Local  string `yaml:"local"`
	Remote string `yaml:"remote"`
}

type Vip struct {
	Name        string `yaml:"name"`
	Destination string `yaml:"destination"`
	Pool        string `yaml:"pool"`
	Rules       []Rule `yaml:"rules"`
}

type Config struct {
	Vips []Vip
}

// Load parses the YAML input s into a Config.
func LoadConfig(s string) (*Config, error) {
	cfg := &Config{}
	err := yaml.Unmarshal([]byte(s), cfg)
	if err != nil {
		return nil, err
	}
	return cfg, nil
}

// LoadFile parses the given YAML file into a Config.
func LoadConfigFile(filename string) (*Config, error) {
	absPath, _ := filepath.Abs(filename)
	content, err := ioutil.ReadFile(absPath)
	if err != nil {
		return nil, err
	}
	cfg, err := LoadConfig(string(content))
	if err != nil {
		return nil, err
	}
	//resolveFilepaths(filepath.Dir(filename), cfg)
	return cfg, nil
}

func GetVirtualServer(vs string, bigip *f5.Device) (Vip, error) {
	err, virtual := bigip.ShowVirtual(vs)
	if err != nil {
		log.Fatalf("Error getting virtual: %s", err)
	}
	var vip Vip
	vip.Name = virtual.FullPath
	vip.Destination = virtual.Destination
	vip.Pool = virtual.Pool
	for _, r := range virtual.Rules {
		var rule Rule
		rule.Remote = r
		rule.Local = ""
		vip.Rules = append(vip.Rules, rule)
	}
	return vip, nil
}

func ShowConfig(bigip *f5.Device) (Config, error) {
	err, virtuals := bigip.ShowVirtuals()
	if err != nil {
		log.Fatalf("Error getting virtuals: %s", err)
	}
	var config Config
	for _, v := range virtuals.Items {
		var vip Vip
		vip.Name = v.FullPath
		vip.Destination = v.Destination
		vip.Pool = v.Pool
		for _, r := range v.Rules {
			var rule Rule
			rule.Remote = r
			rule.Local = ""
			vip.Rules = append(vip.Rules, rule)
		}
		config.Vips = append(config.Vips, vip)
	}
	return config, err
}
<commit_msg>go fmt<commit_after>package config

import (
	//"encoding/json"
	//"fmt"
	"github.com/pr8kerl/f5er/f5"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"path/filepath"
)

type Rule struct {
	Local  string `yaml:"local"`
	Remote string `yaml:"remote"`
}

type Vip struct {
	Name        string `yaml:"name"`
	Destination string `yaml:"destination"`
	Pool        string `yaml:"pool"`
	Rules       []Rule `yaml:"rules"`
}

type Config struct {
	Vips []Vip
}

// Load parses the YAML input s into a Config.
func LoadConfig(s string) (*Config, error) {
	cfg := &Config{}
	err := yaml.Unmarshal([]byte(s), cfg)
	if err != nil {
		return nil, err
	}
	return cfg, nil
}

// LoadFile parses the given YAML file into a Config.
func LoadConfigFile(filename string) (*Config, error) {
	absPath, _ := filepath.Abs(filename)
	content, err := ioutil.ReadFile(absPath)
	if err != nil {
		return nil, err
	}
	cfg, err := LoadConfig(string(content))
	if err != nil {
		return nil, err
	}
	//resolveFilepaths(filepath.Dir(filename), cfg)
	return cfg, nil
}

func GetVirtualServer(vs string, bigip *f5.Device) (Vip, error) {
	err, virtual := bigip.ShowVirtual(vs)
	if err != nil {
		log.Fatalf("Error getting virtual: %s", err)
	}
	var vip Vip
	vip.Name = virtual.FullPath
	vip.Destination = virtual.Destination
	vip.Pool = virtual.Pool
	for _, r := range virtual.Rules {
		var rule Rule
		rule.Remote = r
		rule.Local = ""
		vip.Rules = append(vip.Rules, rule)
	}
	return vip, nil
}

func ShowConfig(bigip *f5.Device) (Config, error) {
	err, virtuals := bigip.ShowVirtuals()
	if err != nil {
		log.Fatalf("Error getting virtuals: %s", err)
	}
	var config Config
	for _, v := range virtuals.Items {
		var vip Vip
		vip.Name = v.FullPath
		vip.Destination = v.Destination
		vip.Pool = v.Pool
		for _, r := range v.Rules {
			var rule Rule
			rule.Remote = r
			rule.Local = ""
			vip.Rules = append(vip.Rules, rule)
		}
		config.Vips = append(config.Vips, vip)
	}
	return config, err
}
<|endoftext|>


<commit_before>package config

//
type ConfigInfo struct {
	Server *serverModel `yaml:"server"`
	Wechat *wechatModel `yaml:"wechat"`
}

//
type serverModel struct {
	Mode string `yaml:"mode"` // run mode
	Host string `yaml:"host"` // server host
	Port string `yaml:"port"` // server port
}

//
type wechatModel struct {
	AppID     string `yaml:"appID"`
	AppSecret string `yaml:"appSecret"`
}

var Config ConfigInfo

func loadConfigInformation(fPath string) error {
	filePath := path.Join(fPath, "config.yaml")
	configData, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Printf(" config file read failed: %s", err)
		os.Exit(-1)
		return err
	}
	err = yaml.Unmarshal(configData, &Config)
	if err != nil {
		fmt.Printf(" config parse failed: %s", err)
		return err
	}
	return nil
}

func LoadConfig() {
	var err error
	fPath, _ := os.Getwd()
	fPath = path.Join(fPath, "config")
	configPath := flag.String("c", fPath, "config file path")
	flag.Parse()
	err = loadConfigInformation(*configPath)
	// fmt.Printf("%+v\n%+v",Config.Server, Config.Wechat)
	if err != nil {
		return
	}
}
<commit_msg>fix bug<commit_after>package config

import (
	"flag"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"path"
)

//
type ConfigInfo struct {
	Server *serverModel `yaml:"server"`
	Wechat *wechatModel `yaml:"wechat"`
}

//
type serverModel struct {
	Mode string `yaml:"mode"` // run mode
	Host string `yaml:"host"` // server host
	Port string `yaml:"port"` // server port
}

//
type wechatModel struct {
	AppID     string `yaml:"appID"`
	AppSecret string `yaml:"appSecret"`
}

var Config ConfigInfo

func loadConfigInformation(fPath string) error {
	filePath := path.Join(fPath, "config.yaml")
	configData, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Printf(" config file read failed: %s", err)
		os.Exit(-1)
		return err
	}
	err = yaml.Unmarshal(configData, &Config)
	if err != nil {
		fmt.Printf(" config parse failed: %s", err)
		return err
	}
	return nil
}

func LoadConfig() {
	var err error
	fPath, _ := os.Getwd()
	fPath = path.Join(fPath, "config")
	configPath := flag.String("c", fPath, "config file path")
	flag.Parse()
	err = loadConfigInformation(*configPath)
	// fmt.Printf("%+v\n%+v",Config.Server, Config.Wechat)
	if err != nil {
		return
	}
}
<|endoftext|>


<commit_before>package config

import (
	"encoding/json"
	"fmt"
	"index/suffixarray"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/pkg/errors"
)

var (
	globalConfig *GlobalConfig
)

// GlobalConfig represents global configuration.
type GlobalConfig struct {
	DockerHost string `json:"docker_host"`
}

// Config represents application configuration.
type Config struct {
	Env   []string `json:"env"`
	Files []string `json:"files"`
	Image string   `json:"image"`
	Host  string   `json:"host"`
	Links []string `json:"links"`
	Port  int      `json:"port"`
	Path  string   `json:"path"`
}

// Default sets the default config.
func (c *Config) Default() error {
	if c.Port == 0 {
		c.Port = 80
	}

	if c.Host == "" {
		path, err := os.Getwd()
		if err != nil {
			return err
		}

		parts := strings.Split(path, "/")
		c.Host = fmt.Sprintf("%s.dev", parts[len(parts)-1])
	}

	c.Path = path(c.Path)

	if c.Image == "" {
		c.Image = "joshix/caddy"
		c.Port = 2015
	}

	r := regexp.MustCompile("\\:")
	index := suffixarray.New([]byte(c.Path))
	result := index.FindAllIndex(r, -1)

	if len(result) == 0 {
		c.Path = c.Path + ":/var/www/html:rw"
	} else if len(result) == 1 {
		c.Path = c.Path + ":rw"
	}

	c.Env = append(c.Env, "VIRTUAL_HOST="+c.Host)
	c.Env = append(c.Env, fmt.Sprintf("VIRTUAL_PORT=%d", c.Port))

	if len(c.Links) == 0 {
		c.Links = []string{}
	}

	return nil
}

func path(p string) string {
	if strings.HasPrefix(p, "/") {
		return p
	}

	path, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	if strings.HasPrefix(p, "./") {
		p = strings.Replace(p, "./", "", -1)
	}

	return filepath.Join(path, p)
}

// ReadConfig tries to reads the given path or create a default config.
func ReadConfig(path string) (*Config, error) {
	c := &Config{}
	b, err := ioutil.ReadFile(path)

	if !os.IsNotExist(err) {
		if err := json.Unmarshal(b, c); err != nil {
			return nil, errors.Wrap(err, "Parsing json")
		}
	}

	if err := c.Default(); err != nil {
		return nil, errors.Wrap(err, "Default config")
	}

	return c, nil
}

// SetGlobal sets the global config.
func SetGlobal(g *GlobalConfig) {
	globalConfig = g
}

// Global returns the global config.
func Global() *GlobalConfig {
	return globalConfig
}
<commit_msg>Fix files path<commit_after>package config

import (
	"encoding/json"
	"fmt"
	"index/suffixarray"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/pkg/errors"
)

var (
	globalConfig *GlobalConfig
)

// GlobalConfig represents global configuration.
type GlobalConfig struct {
	DockerHost string `json:"docker_host"`
}

// Config represents application configuration.
type Config struct {
	Env   []string `json:"env"`
	Files []string `json:"files"`
	Image string   `json:"image"`
	Host  string   `json:"host"`
	Links []string `json:"links"`
	Port  int      `json:"port"`
	Path  string   `json:"path"`
}

// Default sets the default config.
func (c *Config) Default() error {
	if c.Port == 0 {
		c.Port = 80
	}

	if c.Host == "" {
		path, err := os.Getwd()
		if err != nil {
			return err
		}

		parts := strings.Split(path, "/")
		c.Host = fmt.Sprintf("%s.dev", parts[len(parts)-1])
	}

	c.Path = path(c.Path)

	if c.Image == "" {
		c.Image = "joshix/caddy"
		c.Port = 2015
	}

	r := regexp.MustCompile("\\:")
	index := suffixarray.New([]byte(c.Path))
	result := index.FindAllIndex(r, -1)

	if len(result) == 0 {
		c.Path = c.Path + ":/var/www/html:rw"
	} else if len(result) == 1 {
		c.Path = c.Path + ":rw"
	}

	c.Env = append(c.Env, "VIRTUAL_HOST="+c.Host)
	c.Env = append(c.Env, fmt.Sprintf("VIRTUAL_PORT=%d", c.Port))

	if len(c.Links) == 0 {
		c.Links = []string{}
	}

	for i, f := range c.Files {
		if !strings.HasPrefix(f, "/") && !strings.HasPrefix(f, "./") {
			c.Files[i] = "./" + f
		}
	}

	return nil
}

func path(p string) string {
	if strings.HasPrefix(p, "/") {
		return p
	}

	path, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	if strings.HasPrefix(p, "./") {
		p = strings.Replace(p, "./", "", -1)
	}

	return filepath.Join(path, p)
}

// ReadConfig tries to reads the given path or create a default config.
func ReadConfig(path string) (*Config, error) {
	c := &Config{}
	b, err := ioutil.ReadFile(path)

	if !os.IsNotExist(err) {
		if err := json.Unmarshal(b, c); err != nil {
			return nil, errors.Wrap(err, "Parsing json")
		}
	}

	if err := c.Default(); err != nil {
		return nil, errors.Wrap(err, "Default config")
	}

	return c, nil
}

// SetGlobal sets the global config.
func SetGlobal(g *GlobalConfig) {
	globalConfig = g
}

// Global returns the global config.
func Global() *GlobalConfig {
	return globalConfig
}
<|endoftext|>


<commit_before>package config

import (
	"encoding/json"
	"fmt"
	"os"
)

var Settings *Config

type Config struct {
	General struct {
		// Settings for daemon
		Address string
		Port    uint

		// Default name if none specified
		DefaultName string

		// Storage directory for images
		ImageDir     string
		ThumbnailDir string
	}

	// sites for CORS
	CORS struct {
		Sites []string
	}

	Database struct {
		// Database connection settings
		User           string
		Password       string
		Proto          string
		Host           string
		Database       string
		MaxIdle        int
		MaxConnections int
	}
	Redis struct {
		// Redis address and max pool connections
		Protocol       string
		Address        string
		MaxIdle        int
		MaxConnections int
	}

	Google struct {
		Auth   string
		Bucket string
		Key    string
	}

	Akismet struct {
		// Akismet settings
		Key  string
		Host string
	}

	Antispam struct {
		// Antispam Key from Prim
		AntispamKey string

		// Antispam cookie
		CookieName  string
		CookieValue string
	}

	Session struct {
		Secret string
	}

	StopForumSpam struct {
		// Stop Forum Spam settings
		Confidence float64
	}

	Limits struct {
		// Image settings
		ImageMinWidth  int
		ImageMinHeight int
		ImageMaxWidth  int
		ImageMaxHeight int
		ImageMaxSize   int
		WebmMaxLength  int

		// Max posts in a thread
		PostsMax uint

		// Lengths for posting
		CommentMaxLength int
		CommentMinLength int
		TitleMaxLength   int
		TitleMinLength   int
		NameMaxLength    int
		NameMinLength    int
		TagMaxLength     int
		TagMinLength     int

		// Max thumbnail sizes
		ThumbnailMaxWidth  int
		ThumbnailMaxHeight int

		// Max request parameter input size
		ParamMaxSize uint
	}
}

func Print() {

	// Marshal the structs into JSON
	output, err := json.MarshalIndent(Settings, "", "  ")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Printf("%s", output)

}

func init() {
	file, err := os.Open("/etc/pram/post.conf")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	Settings = &Config{}

	decoder := json.NewDecoder(file)

	err = decoder.Decode(&Settings)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

}
<commit_msg>add newline to config print<commit_after>package config

import (
	"encoding/json"
	"fmt"
	"os"
)

var Settings *Config

type Config struct {
	General struct {
		// Settings for daemon
		Address string
		Port    uint

		// Default name if none specified
		DefaultName string

		// Storage directory for images
		ImageDir     string
		ThumbnailDir string
	}

	// sites for CORS
	CORS struct {
		Sites []string
	}

	Database struct {
		// Database connection settings
		User           string
		Password       string
		Proto          string
		Host           string
		Database       string
		MaxIdle        int
		MaxConnections int
	}
	Redis struct {
		// Redis address and max pool connections
		Protocol       string
		Address        string
		MaxIdle        int
		MaxConnections int
	}

	Google struct {
		Auth   string
		Bucket string
		Key    string
	}

	Akismet struct {
		// Akismet settings
		Key  string
		Host string
	}

	Antispam struct {
		// Antispam Key from Prim
		AntispamKey string

		// Antispam cookie
		CookieName  string
		CookieValue string
	}

	Session struct {
		Secret string
	}

	StopForumSpam struct {
		// Stop Forum Spam settings
		Confidence float64
	}

	Limits struct {
		// Image settings
		ImageMinWidth  int
		ImageMinHeight int
		ImageMaxWidth  int
		ImageMaxHeight int
		ImageMaxSize   int
		WebmMaxLength  int

		// Max posts in a thread
		PostsMax uint

		// Lengths for posting
		CommentMaxLength int
		CommentMinLength int
		TitleMaxLength   int
		TitleMinLength   int
		NameMaxLength    int
		NameMinLength    int
		TagMaxLength     int
		TagMinLength     int

		// Max thumbnail sizes
		ThumbnailMaxWidth  int
		ThumbnailMaxHeight int

		// Max request parameter input size
		ParamMaxSize uint
	}
}

func Print() {

	// Marshal the structs into JSON
	output, err := json.MarshalIndent(Settings, "", "  ")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Printf("%s\n", output)

}

func init() {
	file, err := os.Open("/etc/pram/post.conf")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	Settings = &Config{}

	decoder := json.NewDecoder(file)

	err = decoder.Decode(&Settings)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

}
<|endoftext|>


<commit_before>package config

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v2"
)

// Configuration holds the map of all repository informations parsed from all config files
type Configuration struct {
	Source       string
	Repositories map[string]map[string]string `yaml:"repositories"`
}

var (
	search = []func() string{
		func() string { return ".doget.yml" },
		func() string { return filepath.Join(filepath.Dir(os.Args[0]), ".doget.yml") },
		func() string { return filepath.Join(os.Getenv("HOME"), ".doget.yml") },
		func() string { return filepath.Join(os.Getenv("APPDATA"), "Doget", "config.yml") },
	}
)

// Empty configuration
func Empty() *Configuration {
	return &Configuration{Source: "", Repositories: make(map[string]map[string]string)}
}

// Default configuration loaded from search path
func Default() *Configuration {
	return &Configuration{Source: "<default>", Repositories: map[string]map[string]string{
		"github.com": map[string]string{
			"url": "https://github.com/{{.Vendor}}/{{.Name}}/archive/{{.Version}}.zip",
		},
		"bitbucket.org": map[string]string{
			"url": "https://bitbucket.org/{{.Vendor}}/{{.Name}}/get/{{.Version}}.zip",
		},
	}}
}

// SearchPath Returns search path
func SearchPath() []string {
	result := make([]string, len(search))
	for i, path := range search {
		result[i] = path()
	}

	return result
}

// Merge Reads configuration from given sources
func (c *Configuration) Merge(sources ...string) (*Configuration, error) {
	parsed := make(map[string]bool)
	for _, file := range sources {
		if _, err := os.Stat(file); err != nil {
			continue
		}

		info, err := filepath.Abs(file)
		if err != nil {
			continue
		}

		if _, ok := parsed[info]; ok {
			continue
		}

		parsed[info] = true
		parsedFile, err := FromFile(file)
		if err != nil {
			return nil, err
		}

		// Merge
		c.Source += ";" + parsedFile.Source
		for host, config := range parsedFile.Repositories {
			c.Repositories[host] = config
		}
	}

	if 0 == len(parsed) {
		return nil, fmt.Errorf("None of the given config files exist: %q", sources)
	}

	c.Source = strings.TrimLeft(c.Source, ";")
	return c, nil
}

// FromFile Reads configuration from a given file
func FromFile(filename string) (result *Configuration, err error) {
	result = &Configuration{Source: "", Repositories: make(map[string]map[string]string)}

	source, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	err = yaml.Unmarshal(source, &result)
	if err != nil {
		return nil, err
	}

	result.Source = filename
	return result, nil
}
<commit_msg>QA: API Docs<commit_after>package config

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v2"
)

// Configuration holds the map of all repository informations parsed from all config files
type Configuration struct {
	Source       string
	Repositories map[string]map[string]string `yaml:"repositories"`
}

var (
	search = []func() string{
		func() string { return ".doget.yml" },
		func() string { return filepath.Join(filepath.Dir(os.Args[0]), ".doget.yml") },
		func() string { return filepath.Join(os.Getenv("HOME"), ".doget.yml") },
		func() string { return filepath.Join(os.Getenv("APPDATA"), "Doget", "config.yml") },
	}
)

// Empty configuration
func Empty() *Configuration {
	return &Configuration{Source: "", Repositories: make(map[string]map[string]string)}
}

// Default configuration supports github.com and bitbucket.org
func Default() *Configuration {
	return &Configuration{Source: "<default>", Repositories: map[string]map[string]string{
		"github.com": map[string]string{
			"url": "https://github.com/{{.Vendor}}/{{.Name}}/archive/{{.Version}}.zip",
		},
		"bitbucket.org": map[string]string{
			"url": "https://bitbucket.org/{{.Vendor}}/{{.Name}}/get/{{.Version}}.zip",
		},
	}}
}

// SearchPath Returns search path
func SearchPath() []string {
	result := make([]string, len(search))
	for i, path := range search {
		result[i] = path()
	}

	return result
}

// Merge Reads configuration from given sources
func (c *Configuration) Merge(sources ...string) (*Configuration, error) {
	parsed := make(map[string]bool)
	for _, file := range sources {
		if _, err := os.Stat(file); err != nil {
			continue
		}

		info, err := filepath.Abs(file)
		if err != nil {
			continue
		}

		if _, ok := parsed[info]; ok {
			continue
		}

		parsed[info] = true
		parsedFile, err := FromFile(file)
		if err != nil {
			return nil, err
		}

		// Merge
		c.Source += ";" + parsedFile.Source
		for host, config := range parsedFile.Repositories {
			c.Repositories[host] = config
		}
	}

	if 0 == len(parsed) {
		return nil, fmt.Errorf("None of the given config files exist: %q", sources)
	}

	c.Source = strings.TrimLeft(c.Source, ";")
	return c, nil
}

// FromFile Reads configuration from a given file
func FromFile(filename string) (result *Configuration, err error) {
	result = &Configuration{Source: "", Repositories: make(map[string]map[string]string)}

	source, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	err = yaml.Unmarshal(source, &result)
	if err != nil {
		return nil, err
	}

	result.Source = filename
	return result, nil
}
<|endoftext|>