<commit_before>package main

import (
	"context"
	"net/http"
	"strings"
	"time"

	"facette/backend"
	"facette/connector"
	"facette/plot"
	"facette/template"
	"facette/timerange"

	"github.com/facette/httputil"
)

const (
	defaultTimeRange = "-1h"
)

type plotRequest struct {
	plot.Request
	startTime time.Time
	endTime   time.Time
}

type plotQuery struct {
	query     plot.Query
	queryMap  [][2]int
	connector connector.Connector
}

func (w *httpWorker) httpHandlePlots(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
	var err error

	defer r.Body.Close()

	// Check for request content type
	if ct, _ := httputil.GetContentType(r); ct != "application/json" {
		httputil.WriteJSON(rw, httpBuildMessage(ErrUnsupportedType), http.StatusUnsupportedMediaType)
		return
	}

	// Get plot request from received data
	req := &plotRequest{}
	if err := httputil.BindJSON(r, req); err != nil {
		w.log.Error("unable to unmarshal JSON data: %s", err)
		httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
		return
	}

	// Request item from backend
	if req.ID != "" {
		req.Graph = &backend.Graph{}

		if err := w.service.backend.Get(req.ID, req.Graph); err == backend.ErrItemNotExist {
			httputil.WriteJSON(rw, httpBuildMessage(err), http.StatusNotFound)
			return
		} else if err != nil {
			w.log.Error("failed to fetch item: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrUnhandledError), http.StatusInternalServerError)
			return
		} else if req.Graph.Template && len(req.Attributes) == 0 {
			w.log.Debug("requested item %s is a template, skipping", req.ID)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	} else if req.Graph == nil {
		httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
		return
	}

	// Expand graph template if linked
	if req.Graph.LinkID != "" || req.Graph.ID == "" && len(req.Graph.Attributes) > 0 || len(req.Attributes) > 0 {
		// Back up template attributes for later expansion
		attrs := req.Graph.Attributes
		if len(req.Attributes) > 0 {
			attrs.Merge(req.Attributes, true)
		}

		if req.Graph.LinkID != "" {
			if err := w.service.backend.Get(req.Graph.LinkID, req.Graph); err == backend.ErrItemNotExist {
				httputil.WriteJSON(rw, httpBuildMessage(err), http.StatusNotFound)
				return
			} else if err != nil {
				w.log.Error("failed to fetch linked item: %s", err)
				httputil.WriteJSON(rw, httpBuildMessage(ErrUnhandledError), http.StatusInternalServerError)
				return
			}
		}

		if err := req.Graph.Expand(attrs); err != nil {
			w.log.Warning("%s", err)
			httputil.WriteJSON(rw, httpBuildMessage(template.ErrInvalidTemplate), http.StatusBadRequest)
			return
		}
	}

	// Initialize request time boundaries and range
	if req.Time.IsZero() {
		req.Time = time.Now().UTC()
	}

	if req.Range == "" {
		if value, ok := req.Graph.Options["range"].(string); ok {
			req.Range = value
		} else {
			req.Range = defaultTimeRange
		}
	}

	if strings.HasPrefix(req.Range, "-") {
		req.endTime = req.Time
		if req.startTime, err = timerange.Apply(req.Time, req.Range); err != nil {
			w.log.Warning("unable to apply time range: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	} else {
		req.startTime = req.Time
		if req.endTime, err = timerange.Apply(req.Time, req.Range); err != nil {
			w.log.Warning("unable to apply time range: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	}

	// Set default plot sample if none provided
	if req.Sample == 0 {
		req.Sample = plot.DefaultSample
	}

	// Execute plots request
	plots := plot.Response{
		Start:   req.startTime.Format(time.RFC3339),
		End:     req.endTime.Format(time.RFC3339),
		Series:  w.executeRequest(req),
		Options: req.Graph.Options,
	}

	// Set fallback title to graph name if none provided
	if plots.Options == nil {
		plots.Options = make(map[string]interface{})
	}

	if _, ok := plots.Options["title"]; !ok {
		plots.Options["title"] = req.Graph.Name
	}

	httputil.WriteJSON(rw, plots, http.StatusOK)
}

func (w *httpWorker) executeRequest(req *plotRequest) []plot.SeriesResponse {
	// Expand groups series
	for i, group := range req.Graph.Groups {
		for _, series := range group.Series {
			req.Graph.Groups[i].Series = w.expandSeries(series, true)
		}
	}

	// Dispatch plot queries among providers
	data := make([][]plot.Series, len(req.Graph.Groups))
	for i, group := range req.Graph.Groups {
		data[i] = make([]plot.Series, len(group.Series))
	}

	for _, q := range w.dispatchQueries(req) {
		series, err := q.connector.Plots(&q.query)
		if err != nil {
			w.log.Error("unable to fetch plots: %s", err)
			continue
		}

		count := len(series)
		expected := len(q.query.Series)
		if count != expected {
			w.log.Error("unable to fetch plots: expected %d series but got %d", expected, count)
			continue
		}

		// Put back series to its original indexes
		for i, s := range series {
			data[q.queryMap[i][0]][q.queryMap[i][1]] = s
		}
	}

	// Generate plots series
	result := []plot.SeriesResponse{}
	for i, group := range req.Graph.Groups {
		var (
			consolidate int
			err         error
		)

		// Skip processing if no data
		if len(data[i]) == 0 {
			goto finalize
		}

		// Apply series scale if any
		for j, series := range group.Series {
			if v, ok := series.Options["scale"].(float64); ok {
				data[i][j].Scale(plot.Value(v))
			}
		}

		// Skip operations if none requested
		if group.Operator == plot.OperatorNone {
			goto finalize
		}

		// Get group consolidation mode option
		consolidate = plot.ConsolidateAverage
		if v, ok := group.Options["consolidate"].(int); ok {
			consolidate = v
		}

		// Normalize series and apply operations
		data[i], err = plot.Normalize(data[i], req.startTime, req.endTime, req.Sample, consolidate)
		if err != nil {
			w.log.Error("failed to normalize series: %s", err)
			continue
		}

		switch group.Operator {
		case plot.OperatorAverage, plot.OperatorSum:
			var (
				series plot.Series
				err    error
			)

			if group.Operator == plot.OperatorAverage {
				series, err = plot.Average(data[i])
			} else {
				series, err = plot.Sum(data[i])
			}

			if err != nil {
				w.log.Error("failed to apply series operation: %s", err)
				continue
			}

			// Set series name to group name
			req.Graph.Groups[i].Series[0].Name = group.Name

			// Replace group series with operation result
			data[i] = []plot.Series{series}

		case plot.OperatorNormalize:
			// noop

		default:
			w.log.Warning("unknown %d operation type", group.Operator)
			continue
		}

	finalize:
		// Get group scale value
		scale, _ := group.Options["scale"].(float64)

		for j, series := range data[i] {
			// Apply group scale if any
			if scale != 0 {
				series.Scale(plot.Value(scale))
			}

			// Summarize series
			percentiles := []float64{}
			if slice, ok := req.Graph.Options["percentiles"].([]interface{}); ok {
				for _, entry := range slice {
					if val, ok := entry.(float64); ok {
						percentiles = append(percentiles, val)
					}
				}
			}

			series.Summarize(percentiles)

			result = append(result, plot.SeriesResponse{
				Series:  series,
				Name:    group.Series[j].Name,
				Options: group.Series[j].Options,
			})
		}
	}

	return result
}

func (w *httpWorker) dispatchQueries(req *plotRequest) []plotQuery {
	providers := make(map[string]*plotQuery)

	for i, group := range req.Graph.Groups {
		for j, series := range group.Series {
			if !series.IsValid() {
				w.log.Warning("invalid series metric: %s", series)
				continue
			}

			search := w.service.searcher.Metrics(series.Origin, series.Source, series.Metric, 1)
			if len(search) == 0 {
				w.log.Warning("unable to find series metric: %s", series)
				continue
			}

			// Get series connector and provider name
			c := search[0].Connector().(connector.Connector)
			provName := c.Name()

			// Initialize provider-specific plot query
			if _, ok := providers[provName]; !ok {
				providers[provName] = &plotQuery{
					query: plot.Query{
						StartTime: req.startTime,
						EndTime:   req.endTime,
						Sample:    req.Sample,
						Series:    []plot.QuerySeries{},
					},
					queryMap:  [][2]int{},
					connector: c,
				}
			}

			// Append new series to plot query and save series index
			providers[provName].query.Series = append(providers[provName].query.Series, plot.QuerySeries{
				Origin: search[0].Source().Origin().OriginalName,
				Source: search[0].Source().OriginalName,
				Metric: search[0].OriginalName,
			})

			providers[provName].queryMap = append(providers[provName].queryMap, [2]int{i, j})
		}
	}

	result := []plotQuery{}
	for _, q := range providers {
		result = append(result, *q)
	}

	return result
}
<commit_msg>Fix missing series when expanding group<commit_after>package main

import (
	"context"
	"net/http"
	"strings"
	"time"

	"facette/backend"
	"facette/connector"
	"facette/plot"
	"facette/template"
	"facette/timerange"

	"github.com/facette/httputil"
)

const (
	defaultTimeRange = "-1h"
)

type plotRequest struct {
	plot.Request
	startTime time.Time
	endTime   time.Time
}

type plotQuery struct {
	query     plot.Query
	queryMap  [][2]int
	connector connector.Connector
}

func (w *httpWorker) httpHandlePlots(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
	var err error

	defer r.Body.Close()

	// Check for request content type
	if ct, _ := httputil.GetContentType(r); ct != "application/json" {
		httputil.WriteJSON(rw, httpBuildMessage(ErrUnsupportedType), http.StatusUnsupportedMediaType)
		return
	}

	// Get plot request from received data
	req := &plotRequest{}
	if err := httputil.BindJSON(r, req); err != nil {
		w.log.Error("unable to unmarshal JSON data: %s", err)
		httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
		return
	}

	// Request item from backend
	if req.ID != "" {
		req.Graph = &backend.Graph{}

		if err := w.service.backend.Get(req.ID, req.Graph); err == backend.ErrItemNotExist {
			httputil.WriteJSON(rw, httpBuildMessage(err), http.StatusNotFound)
			return
		} else if err != nil {
			w.log.Error("failed to fetch item: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrUnhandledError), http.StatusInternalServerError)
			return
		} else if req.Graph.Template && len(req.Attributes) == 0 {
			w.log.Debug("requested item %s is a template, skipping", req.ID)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	} else if req.Graph == nil {
		httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
		return
	}

	// Expand graph template if linked
	if req.Graph.LinkID != "" || req.Graph.ID == "" && len(req.Graph.Attributes) > 0 || len(req.Attributes) > 0 {
		// Back up template attributes for later expansion
		attrs := req.Graph.Attributes
		if len(req.Attributes) > 0 {
			attrs.Merge(req.Attributes, true)
		}

		if req.Graph.LinkID != "" {
			if err := w.service.backend.Get(req.Graph.LinkID, req.Graph); err == backend.ErrItemNotExist {
				httputil.WriteJSON(rw, httpBuildMessage(err), http.StatusNotFound)
				return
			} else if err != nil {
				w.log.Error("failed to fetch linked item: %s", err)
				httputil.WriteJSON(rw, httpBuildMessage(ErrUnhandledError), http.StatusInternalServerError)
				return
			}
		}

		if err := req.Graph.Expand(attrs); err != nil {
			w.log.Warning("%s", err)
			httputil.WriteJSON(rw, httpBuildMessage(template.ErrInvalidTemplate), http.StatusBadRequest)
			return
		}
	}

	// Initialize request time boundaries and range
	if req.Time.IsZero() {
		req.Time = time.Now().UTC()
	}

	if req.Range == "" {
		if value, ok := req.Graph.Options["range"].(string); ok {
			req.Range = value
		} else {
			req.Range = defaultTimeRange
		}
	}

	if strings.HasPrefix(req.Range, "-") {
		req.endTime = req.Time
		if req.startTime, err = timerange.Apply(req.Time, req.Range); err != nil {
			w.log.Warning("unable to apply time range: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	} else {
		req.startTime = req.Time
		if req.endTime, err = timerange.Apply(req.Time, req.Range); err != nil {
			w.log.Warning("unable to apply time range: %s", err)
			httputil.WriteJSON(rw, httpBuildMessage(ErrInvalidParameter), http.StatusBadRequest)
			return
		}
	}

	// Set default plot sample if none provided
	if req.Sample == 0 {
		req.Sample = plot.DefaultSample
	}

	// Execute plots request
	plots := plot.Response{
		Start:   req.startTime.Format(time.RFC3339),
		End:     req.endTime.Format(time.RFC3339),
		Series:  w.executeRequest(req),
		Options: req.Graph.Options,
	}

	// Set fallback title to graph name if none provided
	if plots.Options == nil {
		plots.Options = make(map[string]interface{})
	}

	if _, ok := plots.Options["title"]; !ok {
		plots.Options["title"] = req.Graph.Name
	}

	httputil.WriteJSON(rw, plots, http.StatusOK)
}

func (w *httpWorker) executeRequest(req *plotRequest) []plot.SeriesResponse {
	// Expand groups series
	for i, group := range req.Graph.Groups {
		expandedSeries := []backend.Series{}
		for _, series := range group.Series {
			expandedSeries = append(expandedSeries, w.expandSeries(series, true)...)
		}
		req.Graph.Groups[i].Series = expandedSeries
	}

	// Dispatch plot queries among providers
	data := make([][]plot.Series, len(req.Graph.Groups))
	for i, group := range req.Graph.Groups {
		data[i] = make([]plot.Series, len(group.Series))
	}

	for _, q := range w.dispatchQueries(req) {
		series, err := q.connector.Plots(&q.query)
		if err != nil {
			w.log.Error("unable to fetch plots: %s", err)
			continue
		}

		count := len(series)
		expected := len(q.query.Series)
		if count != expected {
			w.log.Error("unable to fetch plots: expected %d series but got %d", expected, count)
			continue
		}

		// Put back series to its original indexes
		for i, s := range series {
			data[q.queryMap[i][0]][q.queryMap[i][1]] = s
		}
	}

	// Generate plots series
	result := []plot.SeriesResponse{}
	for i, group := range req.Graph.Groups {
		var (
			consolidate int
			err         error
		)

		// Skip processing if no data
		if len(data[i]) == 0 {
			goto finalize
		}

		// Apply series scale if any
		for j, series := range group.Series {
			if v, ok := series.Options["scale"].(float64); ok {
				data[i][j].Scale(plot.Value(v))
			}
		}

		// Skip operations if none requested
		if group.Operator == plot.OperatorNone {
			goto finalize
		}

		// Get group consolidation mode option
		consolidate = plot.ConsolidateAverage
		if v, ok := group.Options["consolidate"].(int); ok {
			consolidate = v
		}

		// Normalize series and apply operations
		data[i], err = plot.Normalize(data[i], req.startTime, req.endTime, req.Sample, consolidate)
		if err != nil {
			w.log.Error("failed to normalize series: %s", err)
			continue
		}

		switch group.Operator {
		case plot.OperatorAverage, plot.OperatorSum:
			var (
				series plot.Series
				err    error
			)

			if group.Operator == plot.OperatorAverage {
				series, err = plot.Average(data[i])
			} else {
				series, err = plot.Sum(data[i])
			}

			if err != nil {
				w.log.Error("failed to apply series operation: %s", err)
				continue
			}

			// Set series name to group name
			req.Graph.Groups[i].Series[0].Name = group.Name

			// Replace group series with operation result
			data[i] = []plot.Series{series}

		case plot.OperatorNormalize:
			// noop

		default:
			w.log.Warning("unknown %d operation type", group.Operator)
			continue
		}

	finalize:
		// Get group scale value
		scale, _ := group.Options["scale"].(float64)

		for j, series := range data[i] {
			// Apply group scale if any
			if scale != 0 {
				series.Scale(plot.Value(scale))
			}

			// Summarize series
			percentiles := []float64{}
			if slice, ok := req.Graph.Options["percentiles"].([]interface{}); ok {
				for _, entry := range slice {
					if val, ok := entry.(float64); ok {
						percentiles = append(percentiles, val)
					}
				}
			}

			series.Summarize(percentiles)

			result = append(result, plot.SeriesResponse{
				Series:  series,
				Name:    group.Series[j].Name,
				Options: group.Series[j].Options,
			})
		}
	}

	return result
}

func (w *httpWorker) dispatchQueries(req *plotRequest) []plotQuery {
	providers := make(map[string]*plotQuery)

	for i, group := range req.Graph.Groups {
		for j, series := range group.Series {
			if !series.IsValid() {
				w.log.Warning("invalid series metric: %s", series)
				continue
			}

			search := w.service.searcher.Metrics(series.Origin, series.Source, series.Metric, 1)
			if len(search) == 0 {
				w.log.Warning("unable to find series metric: %s", series)
				continue
			}

			// Get series connector and provider name
			c := search[0].Connector().(connector.Connector)
			provName := c.Name()

			// Initialize provider-specific plot query
			if _, ok := providers[provName]; !ok {
				providers[provName] = &plotQuery{
					query: plot.Query{
						StartTime: req.startTime,
						EndTime:   req.endTime,
						Sample:    req.Sample,
						Series:    []plot.QuerySeries{},
					},
					queryMap:  [][2]int{},
					connector: c,
				}
			}

			// Append new series to plot query and save series index
			providers[provName].query.Series = append(providers[provName].query.Series, plot.QuerySeries{
				Origin: search[0].Source().Origin().OriginalName,
				Source: search[0].Source().OriginalName,
				Metric: search[0].OriginalName,
			})

			providers[provName].queryMap = append(providers[provName].queryMap, [2]int{i, j})
		}
	}

	result := []plotQuery{}
	for _, q := range providers {
		result = append(result, *q)
	}

	return result
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/hyperkit/go"
)

// Process the run arguments and execute run
func runHyperKit(args []string) {
	hyperkitCmd := flag.NewFlagSet("hyperkit", flag.ExitOnError)
	hyperkitCmd.Usage = func() {
		fmt.Printf("USAGE: %s run hyperkit [options] [prefix]\n\n", os.Args[0])
		fmt.Printf("'prefix' specifies the path to the VM image.\n")
		fmt.Printf("It defaults to './moby'.\n")
		fmt.Printf("\n")
		fmt.Printf("Options:\n")
		hyperkitCmd.PrintDefaults()
	}
	runHyperKit := hyperkitCmd.String("hyperkit", "", "Path to hyperkit binary (if not in default location)")
	runCPUs := hyperkitCmd.Int("cpus", 1, "Number of CPUs")
	runMem := hyperkitCmd.Int("mem", 1024, "Amount of memory in MB")
	runDiskSz := hyperkitCmd.Int("disk-size", 0, "Size of Disk in MB")
	runDisk := hyperkitCmd.String("disk", "", "Path to disk image to used")

	hyperkitCmd.Parse(args)
	remArgs := hyperkitCmd.Args()

	prefix := "moby"
	if len(remArgs) > 0 {
		prefix = remArgs[0]
	}

	runHyperKitInternal(*runHyperKit, *runCPUs, *runMem, *runDiskSz, *runDisk, prefix)
}

func runHyperKitInternal(hyperkitPath string, cpus, mem, diskSz int, disk, prefix string) {
	cmdline, err := ioutil.ReadFile(prefix + "-cmdline")
	if err != nil {
		log.Fatalf("Cannot open cmdline file: %v", err)
	}

	if diskSz != 0 && disk == "" {
		disk = prefix + "-disk.img"
	}

	h, err := hyperkit.New(hyperkitPath, "", "auto", disk)
	if err != nil {
		log.Fatalln("Error creating hyperkit: ", err)
	}

	h.Kernel = prefix + "-bzImage"
	h.Initrd = prefix + "-initrd.img"
	h.CPUs = cpus
	h.Memory = mem
	h.DiskSize = diskSz

	err = h.Run(string(cmdline))
	if err != nil {
		log.Fatalf("Cannot run hyperkit: %v", err)
	}
}
<commit_msg>cli: Don't default to "moby" for run<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/hyperkit/go"
)

// Process the run arguments and execute run
func runHyperKit(args []string) {
	hyperkitCmd := flag.NewFlagSet("hyperkit", flag.ExitOnError)
	hyperkitCmd.Usage = func() {
		fmt.Printf("USAGE: %s run hyperkit [options] prefix\n\n", os.Args[0])
		fmt.Printf("'prefix' specifies the path to the VM image.\n")
		fmt.Printf("\n")
		fmt.Printf("Options:\n")
		hyperkitCmd.PrintDefaults()
	}
	runHyperKit := hyperkitCmd.String("hyperkit", "", "Path to hyperkit binary (if not in default location)")
	runCPUs := hyperkitCmd.Int("cpus", 1, "Number of CPUs")
	runMem := hyperkitCmd.Int("mem", 1024, "Amount of memory in MB")
	runDiskSz := hyperkitCmd.Int("disk-size", 0, "Size of Disk in MB")
	runDisk := hyperkitCmd.String("disk", "", "Path to disk image to used")

	hyperkitCmd.Parse(args)
	remArgs := hyperkitCmd.Args()
	if len(remArgs) == 0 {
		fmt.Println("Please specify the prefix to the image to boot\n")
		hyperkitCmd.Usage()
		os.Exit(1)
	}
	prefix := remArgs[0]

	runHyperKitInternal(*runHyperKit, *runCPUs, *runMem, *runDiskSz, *runDisk, prefix)
}

func runHyperKitInternal(hyperkitPath string, cpus, mem, diskSz int, disk, prefix string) {
	cmdline, err := ioutil.ReadFile(prefix + "-cmdline")
	if err != nil {
		log.Fatalf("Cannot open cmdline file: %v", err)
	}

	if diskSz != 0 && disk == "" {
		disk = prefix + "-disk.img"
	}

	h, err := hyperkit.New(hyperkitPath, "", "auto", disk)
	if err != nil {
		log.Fatalln("Error creating hyperkit: ", err)
	}

	h.Kernel = prefix + "-bzImage"
	h.Initrd = prefix + "-initrd.img"
	h.CPUs = cpus
	h.Memory = mem
	h.DiskSize = diskSz

	err = h.Run(string(cmdline))
	if err != nil {
		log.Fatalf("Cannot run hyperkit: %v", err)
	}
}
<|endoftext|>


<commit_before>package netutils

import (
	"bytes"
	"net"
	"testing"

	"github.com/docker/libnetwork/ipamutils"
	"github.com/docker/libnetwork/testutils"
	"github.com/docker/libnetwork/types"
	"github.com/vishvananda/netlink"
)

func TestNonOverlapingNameservers(t *testing.T) {
	network := &net.IPNet{
		IP:   []byte{192, 168, 0, 1},
		Mask: []byte{255, 255, 255, 0},
	}
	nameservers := []string{
		"127.0.0.1/32",
	}

	if err := CheckNameserverOverlaps(nameservers, network); err != nil {
		t.Fatal(err)
	}
}

func TestOverlapingNameservers(t *testing.T) {
	network := &net.IPNet{
		IP:   []byte{192, 168, 0, 1},
		Mask: []byte{255, 255, 255, 0},
	}
	nameservers := []string{
		"192.168.0.1/32",
	}

	if err := CheckNameserverOverlaps(nameservers, network); err == nil {
		t.Fatalf("Expected error %s got %s", ErrNetworkOverlapsWithNameservers, err)
	}
}

func TestCheckRouteOverlaps(t *testing.T) {
	networkGetRoutesFct = func(netlink.Link, int) ([]netlink.Route, error) {
		routesData := []string{"10.0.2.0/32", "10.0.3.0/24", "10.0.42.0/24", "172.16.42.0/24", "192.168.142.0/24"}
		routes := []netlink.Route{}
		for _, addr := range routesData {
			_, netX, _ := net.ParseCIDR(addr)
			routes = append(routes, netlink.Route{Dst: netX})
		}
		return routes, nil
	}
	defer func() { networkGetRoutesFct = nil }()

	_, netX, _ := net.ParseCIDR("172.16.0.1/24")
	if err := CheckRouteOverlaps(netX); err != nil {
		t.Fatal(err)
	}

	_, netX, _ = net.ParseCIDR("10.0.2.0/24")
	if err := CheckRouteOverlaps(netX); err == nil {
		t.Fatalf("10.0.2.0/24 and 10.0.2.0 should overlap but it doesn't")
	}
}

func TestCheckNameserverOverlaps(t *testing.T) {
	nameservers := []string{"10.0.2.3/32", "192.168.102.1/32"}

	_, netX, _ := net.ParseCIDR("10.0.2.3/32")

	if err := CheckNameserverOverlaps(nameservers, netX); err == nil {
		t.Fatalf("%s should overlap 10.0.2.3/32 but doesn't", netX)
	}

	_, netX, _ = net.ParseCIDR("192.168.102.2/32")

	if err := CheckNameserverOverlaps(nameservers, netX); err != nil {
		t.Fatalf("%s should not overlap %v but it does", netX, nameservers)
	}
}

func AssertOverlap(CIDRx string, CIDRy string, t *testing.T) {
	_, netX, _ := net.ParseCIDR(CIDRx)
	_, netY, _ := net.ParseCIDR(CIDRy)
	if !NetworkOverlaps(netX, netY) {
		t.Errorf("%v and %v should overlap", netX, netY)
	}
}

func AssertNoOverlap(CIDRx string, CIDRy string, t *testing.T) {
	_, netX, _ := net.ParseCIDR(CIDRx)
	_, netY, _ := net.ParseCIDR(CIDRy)
	if NetworkOverlaps(netX, netY) {
		t.Errorf("%v and %v should not overlap", netX, netY)
	}
}

func TestNetworkOverlaps(t *testing.T) {
	//netY starts at same IP and ends within netX
	AssertOverlap("172.16.0.1/24", "172.16.0.1/25", t)
	//netY starts within netX and ends at same IP
	AssertOverlap("172.16.0.1/24", "172.16.0.128/25", t)
	//netY starts and ends within netX
	AssertOverlap("172.16.0.1/24", "172.16.0.64/25", t)
	//netY starts at same IP and ends outside of netX
	AssertOverlap("172.16.0.1/24", "172.16.0.1/23", t)
	//netY starts before and ends at same IP of netX
	AssertOverlap("172.16.1.1/24", "172.16.0.1/23", t)
	//netY starts before and ends outside of netX
	AssertOverlap("172.16.1.1/24", "172.16.0.1/22", t)
	//netY starts and ends before netX
	AssertNoOverlap("172.16.1.1/25", "172.16.0.1/24", t)
	//netX starts and ends before netY
	AssertNoOverlap("172.16.1.1/25", "172.16.2.1/24", t)
}

func TestNetworkRange(t *testing.T) {
	// Simple class C test
	_, network, _ := net.ParseCIDR("192.168.0.1/24")
	first, last := NetworkRange(network)
	if !first.Equal(net.ParseIP("192.168.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("192.168.0.255")) {
		t.Error(last.String())
	}

	// Class A test
	_, network, _ = net.ParseCIDR("10.0.0.1/8")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.0.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.255.255.255")) {
		t.Error(last.String())
	}

	// Class A, random IP address
	_, network, _ = net.ParseCIDR("10.1.2.3/8")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.0.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.255.255.255")) {
		t.Error(last.String())
	}

	// 32bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/32")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(last.String())
	}

	// 31bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/31")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.2")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(last.String())
	}

	// 26bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/26")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.63")) {
		t.Error(last.String())
	}
}

// Test veth name generation "veth"+rand (e.g.veth0f60e2c)
func TestGenerateRandomName(t *testing.T) {
	name1, err := GenerateRandomName("veth", 7)
	if err != nil {
		t.Fatal(err)
	}
	// veth plus generated append equals a len of 11
	if len(name1) != 11 {
		t.Fatalf("Expected 11 characters, instead received %d characters", len(name1))
	}
	name2, err := GenerateRandomName("veth", 7)
	if err != nil {
		t.Fatal(err)
	}
	// Fail if the random generated names equal one another
	if name1 == name2 {
		t.Fatalf("Expected differing values but received %s and %s", name1, name2)
	}
}

// Test mac generation.
func TestUtilGenerateRandomMAC(t *testing.T) {
	mac1 := GenerateRandomMAC()
	mac2 := GenerateRandomMAC()
	// ensure bytes are unique
	if bytes.Equal(mac1, mac2) {
		t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
	}
	// existing tests check string functionality so keeping the pattern
	if mac1.String() == mac2.String() {
		t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
	}
}

func TestNetworkRequest(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	_, exp, err := net.ParseCIDR("172.17.0.0/16")
	if err != nil {
		t.Fatal(err)
	}

	nw, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}

	_, exp, err = net.ParseCIDR("10.0.0.0/24")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedGranularNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}

	// Add iface and ssert returned address on request
	createInterface(t, "test", "172.17.42.1/16")

	_, exp, err = net.ParseCIDR("172.18.0.0/16")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}
}

func TestElectInterfaceAddress(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	nws := "172.101.202.254/16"
	createInterface(t, "test", nws)

	ipv4Nw, ipv6Nw, err := ElectInterfaceAddresses("test")
	if err != nil {
		t.Fatal(err)
	}

	if ipv4Nw == nil {
		t.Fatalf("unexpected empty ipv4 network addresses")
	}

	if len(ipv6Nw) == 0 {
		t.Fatalf("unexpected empty ipv4 network addresses")
	}

	if nws != ipv4Nw.String() {
		t.Fatalf("expected %s. got %s", nws, ipv4Nw)
	}
}

func createInterface(t *testing.T, name, nw string) {
	// Add interface
	link := &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: "test",
		},
	}
	bip, err := types.ParseCIDR(nw)
	if err != nil {
		t.Fatal(err)
	}
	if err = netlink.LinkAdd(link); err != nil {
		t.Fatalf("Failed to create interface via netlink: %v", err)
	}
	if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil {
		t.Fatal(err)
	}
	if err = netlink.LinkSetUp(link); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Fix CircleCI<commit_after>package netutils

import (
	"bytes"
	"net"
	"testing"

	"github.com/docker/libnetwork/ipamutils"
	"github.com/docker/libnetwork/testutils"
	"github.com/docker/libnetwork/types"
	"github.com/vishvananda/netlink"
)

func TestNonOverlapingNameservers(t *testing.T) {
	network := &net.IPNet{
		IP:   []byte{192, 168, 0, 1},
		Mask: []byte{255, 255, 255, 0},
	}
	nameservers := []string{
		"127.0.0.1/32",
	}

	if err := CheckNameserverOverlaps(nameservers, network); err != nil {
		t.Fatal(err)
	}
}

func TestOverlapingNameservers(t *testing.T) {
	network := &net.IPNet{
		IP:   []byte{192, 168, 0, 1},
		Mask: []byte{255, 255, 255, 0},
	}
	nameservers := []string{
		"192.168.0.1/32",
	}

	if err := CheckNameserverOverlaps(nameservers, network); err == nil {
		t.Fatalf("Expected error %s got %s", ErrNetworkOverlapsWithNameservers, err)
	}
}

func TestCheckRouteOverlaps(t *testing.T) {
	networkGetRoutesFct = func(netlink.Link, int) ([]netlink.Route, error) {
		routesData := []string{"10.0.2.0/32", "10.0.3.0/24", "10.0.42.0/24", "172.16.42.0/24", "192.168.142.0/24"}
		routes := []netlink.Route{}
		for _, addr := range routesData {
			_, netX, _ := net.ParseCIDR(addr)
			routes = append(routes, netlink.Route{Dst: netX})
		}
		return routes, nil
	}
	defer func() { networkGetRoutesFct = nil }()

	_, netX, _ := net.ParseCIDR("172.16.0.1/24")
	if err := CheckRouteOverlaps(netX); err != nil {
		t.Fatal(err)
	}

	_, netX, _ = net.ParseCIDR("10.0.2.0/24")
	if err := CheckRouteOverlaps(netX); err == nil {
		t.Fatalf("10.0.2.0/24 and 10.0.2.0 should overlap but it doesn't")
	}
}

func TestCheckNameserverOverlaps(t *testing.T) {
	nameservers := []string{"10.0.2.3/32", "192.168.102.1/32"}

	_, netX, _ := net.ParseCIDR("10.0.2.3/32")

	if err := CheckNameserverOverlaps(nameservers, netX); err == nil {
		t.Fatalf("%s should overlap 10.0.2.3/32 but doesn't", netX)
	}

	_, netX, _ = net.ParseCIDR("192.168.102.2/32")

	if err := CheckNameserverOverlaps(nameservers, netX); err != nil {
		t.Fatalf("%s should not overlap %v but it does", netX, nameservers)
	}
}

func AssertOverlap(CIDRx string, CIDRy string, t *testing.T) {
	_, netX, _ := net.ParseCIDR(CIDRx)
	_, netY, _ := net.ParseCIDR(CIDRy)
	if !NetworkOverlaps(netX, netY) {
		t.Errorf("%v and %v should overlap", netX, netY)
	}
}

func AssertNoOverlap(CIDRx string, CIDRy string, t *testing.T) {
	_, netX, _ := net.ParseCIDR(CIDRx)
	_, netY, _ := net.ParseCIDR(CIDRy)
	if NetworkOverlaps(netX, netY) {
		t.Errorf("%v and %v should not overlap", netX, netY)
	}
}

func TestNetworkOverlaps(t *testing.T) {
	//netY starts at same IP and ends within netX
	AssertOverlap("172.16.0.1/24", "172.16.0.1/25", t)
	//netY starts within netX and ends at same IP
	AssertOverlap("172.16.0.1/24", "172.16.0.128/25", t)
	//netY starts and ends within netX
	AssertOverlap("172.16.0.1/24", "172.16.0.64/25", t)
	//netY starts at same IP and ends outside of netX
	AssertOverlap("172.16.0.1/24", "172.16.0.1/23", t)
	//netY starts before and ends at same IP of netX
	AssertOverlap("172.16.1.1/24", "172.16.0.1/23", t)
	//netY starts before and ends outside of netX
	AssertOverlap("172.16.1.1/24", "172.16.0.1/22", t)
	//netY starts and ends before netX
	AssertNoOverlap("172.16.1.1/25", "172.16.0.1/24", t)
	//netX starts and ends before netY
	AssertNoOverlap("172.16.1.1/25", "172.16.2.1/24", t)
}

func TestNetworkRange(t *testing.T) {
	// Simple class C test
	_, network, _ := net.ParseCIDR("192.168.0.1/24")
	first, last := NetworkRange(network)
	if !first.Equal(net.ParseIP("192.168.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("192.168.0.255")) {
		t.Error(last.String())
	}

	// Class A test
	_, network, _ = net.ParseCIDR("10.0.0.1/8")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.0.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.255.255.255")) {
		t.Error(last.String())
	}

	// Class A, random IP address
	_, network, _ = net.ParseCIDR("10.1.2.3/8")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.0.0.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.255.255.255")) {
		t.Error(last.String())
	}

	// 32bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/32")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(last.String())
	}

	// 31bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/31")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.2")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.3")) {
		t.Error(last.String())
	}

	// 26bit mask
	_, network, _ = net.ParseCIDR("10.1.2.3/26")
	first, last = NetworkRange(network)
	if !first.Equal(net.ParseIP("10.1.2.0")) {
		t.Error(first.String())
	}
	if !last.Equal(net.ParseIP("10.1.2.63")) {
		t.Error(last.String())
	}
}

// Test veth name generation "veth"+rand (e.g.veth0f60e2c)
func TestGenerateRandomName(t *testing.T) {
	name1, err := GenerateRandomName("veth", 7)
	if err != nil {
		t.Fatal(err)
	}
	// veth plus generated append equals a len of 11
	if len(name1) != 11 {
		t.Fatalf("Expected 11 characters, instead received %d characters", len(name1))
	}
	name2, err := GenerateRandomName("veth", 7)
	if err != nil {
		t.Fatal(err)
	}
	// Fail if the random generated names equal one another
	if name1 == name2 {
		t.Fatalf("Expected differing values but received %s and %s", name1, name2)
	}
}

// Test mac generation.
func TestUtilGenerateRandomMAC(t *testing.T) {
	mac1 := GenerateRandomMAC()
	mac2 := GenerateRandomMAC()
	// ensure bytes are unique
	if bytes.Equal(mac1, mac2) {
		t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
	}
	// existing tests check string functionality so keeping the pattern
	if mac1.String() == mac2.String() {
		t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
	}
}

func TestNetworkRequest(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	nw, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}

	var found bool
	for _, exp := range ipamutils.PredefinedBroadNetworks {
		if types.CompareIPNet(exp, nw) {
			found = true
			break
		}
	}

	if !found {
		t.Fatalf("Found unexpected broad network %s", nw)
	}

	nw, err = FindAvailableNetwork(ipamutils.PredefinedGranularNetworks)
	if err != nil {
		t.Fatal(err)
	}

	found = false
	for _, exp := range ipamutils.PredefinedGranularNetworks {
		if types.CompareIPNet(exp, nw) {
			found = true
			break
		}
	}

	if !found {
		t.Fatalf("Found unexpected granular network %s", nw)
	}

	// Add iface and ssert returned address on request
	createInterface(t, "test", "172.17.42.1/16")

	_, exp, err := net.ParseCIDR("172.18.0.0/16")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}
}

func TestElectInterfaceAddress(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	nws := "172.101.202.254/16"
	createInterface(t, "test", nws)

	ipv4Nw, ipv6Nw, err := ElectInterfaceAddresses("test")
	if err != nil {
		t.Fatal(err)
	}

	if ipv4Nw == nil {
		t.Fatalf("unexpected empty ipv4 network addresses")
	}

	if len(ipv6Nw) == 0 {
		t.Fatalf("unexpected empty ipv4 network addresses")
	}

	if nws != ipv4Nw.String() {
		t.Fatalf("expected %s. got %s", nws, ipv4Nw)
	}
}

func createInterface(t *testing.T, name, nw string) {
	// Add interface
	link := &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: "test",
		},
	}
	bip, err := types.ParseCIDR(nw)
	if err != nil {
		t.Fatal(err)
	}
	if err = netlink.LinkAdd(link); err != nil {
		t.Fatalf("Failed to create interface via netlink: %v", err)
	}
	if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil {
		t.Fatal(err)
	}
	if err = netlink.LinkSetUp(link); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


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

// +build ignore

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
)

func main() {
	flag.Parse()

	args, target := flag.Args(), "peg"
	if len(args) > 0 {
		target = args[0]
	}

	switch target {
	case "peg":
		peg()
	case "clean":
		clean()
	case "test":
		test()
	case "bench":
		bench()
	case "help":
		fmt.Println("go run build.go [target]")
		fmt.Println(" peg - build peg from scratch")
		fmt.Println(" clean - clean up")
		fmt.Println(" test - run full test")
		fmt.Println(" bench - run benchmark")
	}
}

var processed = make(map[string]bool)

func done(file string, deps ...interface{}) bool {
	fini := true
	file = filepath.FromSlash(file)
	info, err := os.Stat(file)
	if err != nil {
		fini = false
	}
	for _, dep := range deps {
		switch dep := dep.(type) {
		case string:
			if info == nil {
				fini = false
				break
			}
			dep = filepath.FromSlash(dep)
			fileInfo, err := os.Stat(dep)
			if err != nil {
				panic(err)
			}

			if fileInfo.ModTime().After(info.ModTime()) {
				fini = false
			}
		case func() bool:
			name := runtime.FuncForPC(reflect.ValueOf(dep).Pointer()).Name()
			if processed[name] {
				fmt.Printf("%s is done\n", name)
				break
			}
			result := dep()
			fini = fini && result
			fmt.Printf("%s\n", name)
			processed[name] = true
		}
	}

	return fini
}

func chdir(dir string) string {
	dir = filepath.FromSlash(dir)
	working, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	err = os.Chdir(dir)
	if err != nil {
		panic(err)
	}
	fmt.Printf("cd %s\n", dir)
	return working
}

func command(name, inputFile, outputFile string, arg ...string) {
	name = filepath.FromSlash(name)
	inputFile = filepath.FromSlash(inputFile)
	outputFile = filepath.FromSlash(outputFile)
	fmt.Print(name)
	for _, a := range arg {
		fmt.Printf(" %s", a)
	}

	cmd := exec.Command(name, arg...)

	if inputFile != "" {
		fmt.Printf(" < %s", inputFile)
		input, err := ioutil.ReadFile(inputFile)
		if err != nil {
			panic(err)
		}
		writer, err := cmd.StdinPipe()
		if err != nil {
			panic(err)
		}
		go func() {
			defer writer.Close()
			_, err := writer.Write([]byte(input))
			if err != nil {
				panic(err)
			}
		}()
	}

	if outputFile != "" {
		fmt.Printf(" > %s\n", outputFile)
		output, err := cmd.Output()
		if err != nil {
			panic(err)
		}
		err = ioutil.WriteFile(outputFile, output, 0600)
		if err != nil {
			panic(err)
		}
	} else {
		output, err := cmd.CombinedOutput()
		if err != nil {
			panic(err)
		}
		fmt.Printf("\n%s", string(output))
	}
}

func delete(file string) {
	file = filepath.FromSlash(file)
	fmt.Printf("rm -f %s\n", file)
	os.Remove(file)
}

func deleteFilesWithSuffix(suffix string) {
	files, err := ioutil.ReadDir(".")
	if err != nil {
		panic(err)
	}
	for _, file := range files {
		if strings.HasSuffix(file.Name(), suffix) {
			delete(file.Name())
		}
	}
}

func bootstrap() bool {
	if done("bootstrap/bootstrap", "bootstrap/main.go", "tree/peg.go") {
		return true
	}

	wd := chdir("bootstrap")
	defer chdir(wd)

	command("go", "", "", "build")

	return false
}

func peg0() bool {
	if done("cmd/peg-bootstrap/peg0", "cmd/peg-bootstrap/main.go", bootstrap) {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("../../bootstrap/bootstrap", "", "")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg0")

	return false
}

func peg1() bool {
	if done("cmd/peg-bootstrap/peg1", peg0, "cmd/peg-bootstrap/bootstrap.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg0", "bootstrap.peg", "peg1.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg1")

	return false
}

func peg2() bool {
	if done("cmd/peg-bootstrap/peg2", peg1, "cmd/peg-bootstrap/peg.bootstrap.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg1", "peg.bootstrap.peg", "peg2.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg2")

	return false
}

func peg3() bool {
	if done("cmd/peg-bootstrap/peg3", peg2, "peg.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg2", "../../peg.peg", "peg3.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg3")

	return false
}

func peg_bootstrap() bool {
	if done("cmd/peg-bootstrap/peg-bootstrap", peg3) {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg3", "../../peg.peg", "peg-bootstrap.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg-bootstrap")

	return false
}

func peg_peg_go() bool {
	if done("peg.peg.go", peg_bootstrap) {
		return true
	}

	command("cmd/peg-bootstrap/peg-bootstrap", "peg.peg", "peg.peg.go")
	command("go", "", "", "build")
	command("./peg", "", "", "-inline", "-switch", "peg.peg")

	return false
}

func peg() bool {
	if done("peg", peg_peg_go, "main.go") {
		return true
	}

	command("go", "", "", "build")

	return false
}

func clean() bool {
	delete("bootstrap/bootstrap")

	delete("grammars/c/c.peg.go")
	delete("grammars/calculator/calculator.peg.go")
	delete("grammars/fexl/fexl.peg.go")
	delete("grammars/java/java_1_7.peg.go")
	delete("grammars/long_test/long.peg.go")

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	delete("peg0")
	delete("peg1")
	delete("peg2")
	delete("peg3")
	delete("peg-bootstrap")

	return false
}

func grammars_c() bool {
	if done("grammars/c/c.peg.go", "grammars/c/c.peg") {
		return true
	}

	wd := chdir("grammars/c/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "c.peg")

	return false
}

func grammars_calculator() bool {
	if done("grammars/calculator/calculator.peg.go", "grammars/calculator/calculator.peg") {
		return true
	}

	wd := chdir("grammars/calculator/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "calculator.peg")

	return false
}

func grammars_fexl() bool {
	if done("grammars/fexl/fexl.peg.go", "grammars/fexl/fexl.peg") {
		return true
	}

	wd := chdir("grammars/fexl/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "fexl.peg")

	return false
}

func grammars_java() bool {
	if done("grammars/java/java_1_7.peg.go", "grammars/java/java_1_7.peg") {
		return true
	}

	wd := chdir("grammars/java/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "java_1_7.peg")

	return false
}

func grammars_long_test() bool {
	if done("grammars/long_test/long.peg.go", "grammars/long_test/long.peg") {
		return true
	}

	wd := chdir("grammars/long_test/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "long.peg")

	return false
}

func test() bool {
	if done("", peg, grammars_c, grammars_calculator, grammars_fexl, grammars_java, grammars_long_test) {
		return true
	}

	command("go", "", "", "test", "-short", "-tags", "grammars", "./...")

	return false
}

func bench() bool {
	peg()

	command("go", "", "", "test", "-benchmem", "-bench", ".")

	return false
}
<commit_msg>Improved build<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
)

func main() {
	flag.Parse()

	args, target := flag.Args(), "peg"
	if len(args) > 0 {
		target = args[0]
	}

	switch target {
	case "peg":
		peg()
	case "clean":
		clean()
	case "test":
		test()
	case "bench":
		bench()
	case "help":
		fmt.Println("go run build.go [target]")
		fmt.Println(" peg - build peg from scratch")
		fmt.Println(" clean - clean up")
		fmt.Println(" test - run full test")
		fmt.Println(" bench - run benchmark")
	}
}

var processed = make(map[string]bool)

func done(file string, deps ...interface{}) bool {
	fini := true
	file = filepath.FromSlash(file)
	info, err := os.Stat(file)
	if err != nil {
		fini = false
	}
	for _, dep := range deps {
		switch dep := dep.(type) {
		case string:
			if info == nil {
				fini = false
				break
			}
			dep = filepath.FromSlash(dep)
			fileInfo, err := os.Stat(dep)
			if err != nil {
				panic(err)
			}

			if fileInfo.ModTime().After(info.ModTime()) {
				fini = false
			}
		case func() bool:
			name := runtime.FuncForPC(reflect.ValueOf(dep).Pointer()).Name()
			if result, ok := processed[name]; ok {
				fini = fini && result
				fmt.Printf("%s is done\n", name)
				break
			}
			result := dep()
			fini = fini && result
			fmt.Printf("%s\n", name)
			processed[name] = result
		}
	}

	return fini
}

func chdir(dir string) string {
	dir = filepath.FromSlash(dir)
	working, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	err = os.Chdir(dir)
	if err != nil {
		panic(err)
	}
	fmt.Printf("cd %s\n", dir)
	return working
}

func command(name, inputFile, outputFile string, arg ...string) {
	name = filepath.FromSlash(name)
	inputFile = filepath.FromSlash(inputFile)
	outputFile = filepath.FromSlash(outputFile)
	fmt.Print(name)
	for _, a := range arg {
		fmt.Printf(" %s", a)
	}

	cmd := exec.Command(name, arg...)

	if inputFile != "" {
		fmt.Printf(" < %s", inputFile)
		input, err := ioutil.ReadFile(inputFile)
		if err != nil {
			panic(err)
		}
		writer, err := cmd.StdinPipe()
		if err != nil {
			panic(err)
		}
		go func() {
			defer writer.Close()
			_, err := writer.Write([]byte(input))
			if err != nil {
				panic(err)
			}
		}()
	}

	if outputFile != "" {
		fmt.Printf(" > %s\n", outputFile)
		output, err := cmd.Output()
		if err != nil {
			panic(err)
		}
		err = ioutil.WriteFile(outputFile, output, 0600)
		if err != nil {
			panic(err)
		}
	} else {
		output, err := cmd.CombinedOutput()
		if err != nil {
			panic(err)
		}
		fmt.Printf("\n%s", string(output))
	}
}

func delete(file string) {
	file = filepath.FromSlash(file)
	fmt.Printf("rm -f %s\n", file)
	os.Remove(file)
}

func deleteFilesWithSuffix(suffix string) {
	files, err := ioutil.ReadDir(".")
	if err != nil {
		panic(err)
	}
	for _, file := range files {
		if strings.HasSuffix(file.Name(), suffix) {
			delete(file.Name())
		}
	}
}

func bootstrap() bool {
	if done("bootstrap/bootstrap", "bootstrap/main.go", "tree/peg.go") {
		return true
	}

	wd := chdir("bootstrap")
	defer chdir(wd)

	command("go", "", "", "build")

	return false
}

func peg0() bool {
	if done("cmd/peg-bootstrap/peg0", "cmd/peg-bootstrap/main.go", bootstrap) {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("../../bootstrap/bootstrap", "", "")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg0")

	return false
}

func peg1() bool {
	if done("cmd/peg-bootstrap/peg1", peg0, "cmd/peg-bootstrap/bootstrap.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg0", "bootstrap.peg", "peg1.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg1")

	return false
}

func peg2() bool {
	if done("cmd/peg-bootstrap/peg2", peg1, "cmd/peg-bootstrap/peg.bootstrap.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg1", "peg.bootstrap.peg", "peg2.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg2")

	return false
}

func peg3() bool {
	if done("cmd/peg-bootstrap/peg3", peg2, "peg.peg") {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg2", "../../peg.peg", "peg3.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg3")

	return false
}

func peg_bootstrap() bool {
	if done("cmd/peg-bootstrap/peg-bootstrap", peg3) {
		return true
	}

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	command("./peg3", "../../peg.peg", "peg-bootstrap.peg.go")
	command("go", "", "", "build", "-tags", "bootstrap", "-o", "peg-bootstrap")

	return false
}

func peg_peg_go() bool {
	if done("peg.peg.go", peg_bootstrap) {
		return true
	}

	command("cmd/peg-bootstrap/peg-bootstrap", "peg.peg", "peg.peg.go")
	command("go", "", "", "build")
	command("./peg", "", "", "-inline", "-switch", "peg.peg")

	return false
}

func peg() bool {
	if done("peg", peg_peg_go, "main.go") {
		return true
	}

	command("go", "", "", "build")

	return false
}

func clean() bool {
	delete("bootstrap/bootstrap")

	delete("grammars/c/c.peg.go")
	delete("grammars/calculator/calculator.peg.go")
	delete("grammars/fexl/fexl.peg.go")
	delete("grammars/java/java_1_7.peg.go")
	delete("grammars/long_test/long.peg.go")

	wd := chdir("cmd/peg-bootstrap/")
	defer chdir(wd)

	deleteFilesWithSuffix(".peg.go")
	delete("peg0")
	delete("peg1")
	delete("peg2")
	delete("peg3")
	delete("peg-bootstrap")

	return false
}

func grammars_c() bool {
	if done("grammars/c/c.peg.go", peg, "grammars/c/c.peg") {
		return true
	}

	wd := chdir("grammars/c/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "c.peg")

	return false
}

func grammars_calculator() bool {
	if done("grammars/calculator/calculator.peg.go", peg, "grammars/calculator/calculator.peg") {
		return true
	}

	wd := chdir("grammars/calculator/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "calculator.peg")

	return false
}

func grammars_fexl() bool {
	if done("grammars/fexl/fexl.peg.go", peg, "grammars/fexl/fexl.peg") {
		return true
	}

	wd := chdir("grammars/fexl/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "fexl.peg")

	return false
}

func grammars_java() bool {
	if done("grammars/java/java_1_7.peg.go", peg, "grammars/java/java_1_7.peg") {
		return true
	}

	wd := chdir("grammars/java/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "java_1_7.peg")

	return false
}

func grammars_long_test() bool {
	if done("grammars/long_test/long.peg.go", peg, "grammars/long_test/long.peg") {
		return true
	}

	wd := chdir("grammars/long_test/")
	defer chdir(wd)

	command("../../peg", "", "", "-switch", "-inline", "long.peg")

	return false
}

func test() bool {
	if done("", grammars_c, grammars_calculator, grammars_fexl, grammars_java, grammars_long_test) {
		return true
	}

	command("go", "", "", "test", "-short", "-tags", "grammars", "./...")

	return false
}

func bench() bool {
	peg()

	command("go", "", "", "test", "-benchmem", "-bench", ".")

	return false
}
<|endoftext|>


<commit_before>package of10

import . "github.com/oshothebig/goflow/openflow"

type ActionType uint16

const (
	OFPAT_OUTPUT ActionType = iota
	OFPAT_SET_VLAN_VID
	OFPAT_SET_VLAN_PCP
	OFPAT_SET_STRIP_VLAN
	OFPAT_SET_DL_SRC
	OFPAT_SET_DL_DST
	OFPAT_SET_NW_SRC
	OFPAT_SET_NW_DST
	OFPAT_SET_NW_TOS
	OFPAT_SET_TP_SRC
	OFPAT_SET_TP_DST
	OFPAT_ENQUEUE
	OFPAT_VENDOR ActionType = 0xffff
)

var ActionTypes = struct {
	Output        ActionType
	SetVlanId     ActionType
	SetVlanPcp    ActionType
	StripVlan     ActionType
	SetEtherSrc   ActionType
	SetEtherDst   ActionType
	SetIpSrc      ActionType
	SetIpDst      ActionType
	SetIpTos      ActionType
	SetNetworkSrc ActionType
	SetNetworkDst ActionType
	Enqueue       ActionType
	Vendor        ActionType
}{
	OFPAT_OUTPUT,
	OFPAT_SET_VLAN_VID,
	OFPAT_SET_VLAN_PCP,
	OFPAT_SET_STRIP_VLAN,
	OFPAT_SET_DL_SRC,
	OFPAT_SET_DL_DST,
	OFPAT_SET_NW_SRC,
	OFPAT_SET_NW_DST,
	OFPAT_SET_NW_TOS,
	OFPAT_SET_TP_SRC,
	OFPAT_SET_TP_DST,
	OFPAT_ENQUEUE,
	OFPAT_VENDOR,
}

type Action interface {
	Packetizable
	GetType() ActionType
}

type ActionHeader struct {
	Type   ActionType
	Length uint16
}

func (header *ActionHeader) GetType() ActionType {
	return header.Type
}

type SendOutPort struct {
	ActionHeader
	Port      PortNumber
	MaxLength uint16
}

type Enqueue struct {
	ActionHeader
	Port    PortNumber
	pad     [6]uint8
	QueueId uint32
}

type SetVlanVid struct {
	ActionHeader
	VlanId VlanId
	pad    [2]uint32
}
<commit_msg>Declare SetVlanPcp struct<commit_after>package of10

import . "github.com/oshothebig/goflow/openflow"

type ActionType uint16

const (
	OFPAT_OUTPUT ActionType = iota
	OFPAT_SET_VLAN_VID
	OFPAT_SET_VLAN_PCP
	OFPAT_SET_STRIP_VLAN
	OFPAT_SET_DL_SRC
	OFPAT_SET_DL_DST
	OFPAT_SET_NW_SRC
	OFPAT_SET_NW_DST
	OFPAT_SET_NW_TOS
	OFPAT_SET_TP_SRC
	OFPAT_SET_TP_DST
	OFPAT_ENQUEUE
	OFPAT_VENDOR ActionType = 0xffff
)

var ActionTypes = struct {
	Output        ActionType
	SetVlanId     ActionType
	SetVlanPcp    ActionType
	StripVlan     ActionType
	SetEtherSrc   ActionType
	SetEtherDst   ActionType
	SetIpSrc      ActionType
	SetIpDst      ActionType
	SetIpTos      ActionType
	SetNetworkSrc ActionType
	SetNetworkDst ActionType
	Enqueue       ActionType
	Vendor        ActionType
}{
	OFPAT_OUTPUT,
	OFPAT_SET_VLAN_VID,
	OFPAT_SET_VLAN_PCP,
	OFPAT_SET_STRIP_VLAN,
	OFPAT_SET_DL_SRC,
	OFPAT_SET_DL_DST,
	OFPAT_SET_NW_SRC,
	OFPAT_SET_NW_DST,
	OFPAT_SET_NW_TOS,
	OFPAT_SET_TP_SRC,
	OFPAT_SET_TP_DST,
	OFPAT_ENQUEUE,
	OFPAT_VENDOR,
}

type Action interface {
	Packetizable
	GetType() ActionType
}

type ActionHeader struct {
	Type   ActionType
	Length uint16
}

func (header *ActionHeader) GetType() ActionType {
	return header.Type
}

type SendOutPort struct {
	ActionHeader
	Port      PortNumber
	MaxLength uint16
}

type Enqueue struct {
	ActionHeader
	Port    PortNumber
	pad     [6]uint8
	QueueId uint32
}

type SetVlanVid struct {
	ActionHeader
	VlanId VlanId
	pad    [2]uint32
}

type SetVlanPcp struct {
	ActionHeader
	VlanPcp VlanPriority
	pad     [3]uint8
}
<|endoftext|>


<commit_before>/*
(c) Copyright [2015] Hewlett Packard Enterprise Development LP

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 ov -
package ov

import (
	"strings"

	"github.com/Pooja-S-Rao/oneview-golang/liboneview"
	"github.com/Pooja-S-Rao/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
)

// introduced in v200 for oneview, new v2 hardware attributes
// such as support for different types of ilo connections

// IsHardwareSchemaV2 - true when we are using v2, false for v1
func (c *OVClient) IsHardwareSchemaV2() bool {
	var currentversion liboneview.Version
	var asc liboneview.APISupport
	currentversion = currentversion.CalculateVersion(c.APIVersion, 108) // force icsp to 108 version since icsp version doesn't matter
	log.Infof("inside server_hardwarev2 :%s",currentversion)
	asc = asc.NewByName("server_hardwarev2.go")
	if asc.IsSupported(currentversion) {
		log.Debugf("IsHardwareSchemaV2 is supported: %+v", currentversion)
		return true
	}
	return false
}

// ServerHardwarev200 get server hardware from ov
// mphostinfo is private to force calls to GetIloIPAddress
type ServerHardwarev200 struct {
	IntelligentProvisioningVersion string              `json:"intelligentProvisioningVersion,omitempty"` // intelligentProvisioningVersion The installed version of the Intelligent Provisioning embedded server provisioning tool. string
	MpHostInfo                     *MpHostInfov200     `json:"mpHostInfo,omitempty"`                     // The host name and IP address information for the Management Processor that resides on this server.
	MpState                        string              `json:"mpState,omitempty"`                        //  Indicates the current state of the management processor.
	PortMap                        *PortMapv200        `json:"portMap,omitempty"`                        //  A list of adapters/slots, their ports and attributes. This information is available for blade servers but not rack servers.
	ServerSettings                 *ServerSettingsv200 `json:"serverSettings,omitempty"`                 //  Indicates the current settings on the server and state of these settings.
	Signature                      *Signaturev200      `json:"signature,omitempty"`                      // Data representing the current configuration or 'signature' of the server.
}

// TODO: needs a type
// PhysicalServerMPState
// Values
//     OK
//     Reset
//     Resetting

// MpHostInfov200 -
type MpHostInfov200 struct {
	MpHostName  string            `json:"mpHostName,omitempty"`    // mpHostName The host name of the Management Processor. string
	MpIPAddress []MpIPAddressv200 `json:"mpIpAddresses,omitempty"` // The list of IP addresses and corresponding type information for the Management Processor.
}

// MpIPAddressv200 -
type MpIPAddressv200 struct {
	Address string `json:"address,omitempty"` // address An IP address for the Management Processor. string
	Type    string `json:"type,omitempty"`    // type The type of IP address. The following are useful values for the IP address type: Static - Static IP address configuration; DHCP - Dynamic host configuration protocol; SLAAC - Stateless address autoconfiguration (IPv6); LinkLocal - Link-local address (IPv6);
}

// MpIPTypev200 Type constant
type MpIPTypev200 int

// const block
const (
	MpDHCP MpIPTypev200 = 1 + iota
	MpLinkLocal
	MpLinkLocalRequired
	MpLookup
	MpSlaaC
	MpStatic
	MpUndefined
)

var mpiptypevlist = [...]string{
	"DHCP",
	"LinkLocal",
	"LinkLocal_Required",
	"Lookup",
	"SLAAC",
	"Static",
	"Undefined",
}

// String helper for MpIPTypev200
func (o MpIPTypev200) String() string { return mpiptypevlist[o-1] }

// Equal helper for MpIPTypev200
func (o MpIPTypev200) Equal(s string) bool {
	return (strings.ToUpper(s) == strings.ToUpper(o.String()))
}

// PortMapv200 -
type PortMapv200 struct {
	DeviceSlots []DeviceSlotsv200 `json:"deviceSlots,omitempty"` //  List of each slot found on the server hardware. read only
}

// DeviceSlotsv200 -
type DeviceSlotsv200 struct {
	DeviceName    string             `json:"deviceName,omitempty"`    // deviceName The name or model of the adapter. string read only
	DeviceNumber  int                `json:"deviceNumber,omitempty"`  // deviceNumber The device number of a blade server in an enclosure. integer read only
	Location      string             `json:"location,omitempty"`      // location The location of the adapter in the server. Lom indicates LAN on motherboard, Flb is for FlexibleLOM for blades and Mezz is for Mezzanine adapters.
	PhysicalPorts []PhysicalPortv200 `json:"physicalPorts,omitempty"` // physicalPorts        //
	SlotNumber    int                `json:"slotNumber,omitempty"`    // slotNumber The slot number of the adapter on the server hardware within its specified location. integer read only
}

// PhysicalPortv200 -
type PhysicalPortv200 struct {
	InterconnectPort         int               `json:"interconnectPort,omitempty"`         // interconnectPort The downlink port number on the interconnect that hosts network connections for this adapter port. If the adapter port is not connected to an interconnect downlink port, the value will be 0. integer read only
	InterconnectURI          utils.Nstring     `json:"interconnectUri,omitempty"`          // interconnectUri The URI of the interconnect that hosts network connections for this adapter port. string read only
	MAC                      string            `json:"mac,omitempty"`                      // mac Physical mac address of this physical port. string read only
	PhysicalInterconnectPort int               `json:"physicalInterconnectPort,omitempty"` // physicalInterconnectPort The downlink port number on the interconnect to which the adapter port is physically connected. If the adapter port is not connected to an interconnect downlink port, the value will be 0. integer read only
	PhysicalInterconnectURI  utils.Nstring     `json:"physicalInterconnectUri,omitempty"`  // physicalInterconnectUri The URI of the interconnect to which the adapter port is physically connected. string read only
	PortNumber               int               `json:"portNumber,omitempty"`               // portNumber Physical port number of the adapter. integer read only
	Type                     string            `json:"type,omitempty"`                     // type Physical port type. Values include Ethernet and FibreChannel. Physical Server Port Type read only
	VirtualPorts             []VirtualPortv200 `json:"virtualPorts,omitempty"`             // For Flex-capable devices, a list of FlexNICs defined on the server. array of Server Fabric Virtual Port read only
	WWN                      string            `json:"wwn,omitempty"`                      // wwn The world wide name of this physical port. string read only
}

// TODO : implement const for type on PhysicalPortv200
// Ethernet Ethernet network
// FibreChannel Fibre Channel network
// InfiniBand

// VirtualPortv200 -
type VirtualPortv200 struct {
	CurrentAllocatedVirtualFunctionCount int    `json:"currentAllocatedVirtualFunctionCount,omitempty"` // currentAllocatedVirtualFunctionCount The number of virtual functions presently allocated to this virtual port. integer read only
	MAC                                  string `json:"mac,omitempty"`                                  // mac The mac address assigned to this virtual port. string read only
	PortFunction                         string `json:"portFunction,omitempty"`                         // portFunction The function identifier for this FlexNIC, such as a, b, c or d. string read only
	PortNumber                           int    `json:"portNumber,omitempty"`                           // portNumber The port number assigned to this virtual port. integer read only
	WWNN                                 string `json:"WWNN,omitempty"`                                 // wwnn The world wide node name assigned to this virtual port. string read only
	WWPN                                 string `json:"WWPN,omitempty"`                                 // wwpn The world wide port name assigned to this virtual port. string read only
}

// ServerSettingsv200 -
type ServerSettingsv200 struct {
	FirmwareAndDriversInstallState *FirmwareAndDriversInstallStatev200 `json:"firmwareAndDriversInstallState,omitempty"` //  firmwareAndDriversInstallState The current installation status details of the firmware and/or OS drivers on the server.
	HPSmartUpdateToolStatus        *HpSmartUpdateToolStatusv200        `json:"hpSmartUpdateToolStatus,omitempty"`        // The status of HP Smart Update Tool installed on the server.
}

// FirmwareAndDriversInstallStatev200 -
type FirmwareAndDriversInstallStatev200 struct {
	InstallState            string `json:"installState,omitempty"`            // installState The installation state information of the firmware and/or OS drivers on the server.
	InstalledStateTimestamp string `json:"installedStateTimestamp,omitempty"` // The timestamp information indicating the time when the install state value got updated. string
}

//TODO: const for FirmwareInstallState
// ActivateFailed Indicates activation of one or more smart components failed on the server.
// Activated Indicates all the smart components from the SPP bundle specified in the firmware and driver baseline settings are installed and activated on the server.
// Activating Indicates HP Smart Update Tool is activating the installed smart components.
// InstallFailed Indicates HP Smart Update Tool has failed installing one or more smart components.
// InstalledPendingReboot Indicates HP Smart Update Tool has completed installing the smart components, however the server needs to be rebooted for the updates to take effect.
// Installing Indicates HP Smart Update Tool is installing the smart components from the staged location.
// Pending Indicates the firmware and/or OS driver baseline settings have been applied to the server hardware and will take effect when HP Smart Update tool updates firmware and/or OS driver components based on these settings.
// StageFailed Indicates HP Smart Update Tool has failed to stage the smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Staged Indicates HP Smart Update Tool has completed staging the smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Staging Indicates HP Smart Update Tool is staging the firmware and/or OS driver smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Uninitialized Indicates the current firmware and/or OS driver settings have been cleared. No components will be updated on the server.
// Unknown Indicates the server failed to return the current settings, therefore, the actual values might not be current.

type HpSmartUpdateToolStatusv200 struct {
	HPSUTInstallState string `json:"hpSUTInstallState,omitempty"` // hpSUTInstallState HpSUT Install State Enum
	InstallState      string `json:"installState,omitempty"`      // installState HP Smart Update Tool's installed state on the server indicating whether it is installed, not installed or unknown.
	LastOperationTime string `json:"lastOperationTime,omitempty"` // lastOperationTime The timestamp indicating when HP Smart Update Tool was active or running a firmware update operation. string
	Mode              string `json:"mode,omitempty"`              // mode The current run mode configured for HP Smart Update Tool installed on the server. string
	ServiceState      string `json:"serviceState,omitempty"`      // serviceState The state of the HP Smart Update Tool Service running on the server operating system. string
	Version           string `json:"version,omitempty"`           // version The current version of the HP Smart Update Tool installed on the server. string
}

// Signaturev200 -
type Signaturev200 struct {
	PersonalityChecksum int `json:"personalityChecksum,omitempty"` // A calculated checksum of the server 'personality,' based on the defined connections and server identifiers. integer read only
	ServerHwChecksum    int `json:"serverHwChecksum,omitempty"`    // A calculated checksum of the server hardware, based on the hardware components installed in the server. integer read only
}
<commit_msg>Update server_hardwarev2.go<commit_after>/*
(c) Copyright [2015] Hewlett Packard Enterprise Development LP

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 ov -
package ov

import (
	"strings"

	"github.com/Pooja-S-Rao/oneview-golang/liboneview"
	"github.com/Pooja-S-Rao/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
)

// introduced in v200 for oneview, new v2 hardware attributes
// such as support for different types of ilo connections

// IsHardwareSchemaV2 - true when we are using v2, false for v1
func (c *OVClient) IsHardwareSchemaV2() bool {
	var currentversion liboneview.Version
	var asc liboneview.APISupport
	currentversion = currentversion.CalculateVersion(c.APIVersion, 108) // force icsp to 108 version since icsp version doesn't matter
	log.Infof("inside server_hardwarev2 :%s",currentversion)
	asc = asc.NewByName("server_hardwarev2.go")
	log.Infof("asc :%s",asc)
	if asc.IsSupported(currentversion) {
		log.Debugf("IsHardwareSchemaV2 is supported: %+v", currentversion)
		return true
	}
	return false
}

// ServerHardwarev200 get server hardware from ov
// mphostinfo is private to force calls to GetIloIPAddress
type ServerHardwarev200 struct {
	IntelligentProvisioningVersion string              `json:"intelligentProvisioningVersion,omitempty"` // intelligentProvisioningVersion The installed version of the Intelligent Provisioning embedded server provisioning tool. string
	MpHostInfo                     *MpHostInfov200     `json:"mpHostInfo,omitempty"`                     // The host name and IP address information for the Management Processor that resides on this server.
	MpState                        string              `json:"mpState,omitempty"`                        //  Indicates the current state of the management processor.
	PortMap                        *PortMapv200        `json:"portMap,omitempty"`                        //  A list of adapters/slots, their ports and attributes. This information is available for blade servers but not rack servers.
	ServerSettings                 *ServerSettingsv200 `json:"serverSettings,omitempty"`                 //  Indicates the current settings on the server and state of these settings.
	Signature                      *Signaturev200      `json:"signature,omitempty"`                      // Data representing the current configuration or 'signature' of the server.
}

// TODO: needs a type
// PhysicalServerMPState
// Values
//     OK
//     Reset
//     Resetting

// MpHostInfov200 -
type MpHostInfov200 struct {
	MpHostName  string            `json:"mpHostName,omitempty"`    // mpHostName The host name of the Management Processor. string
	MpIPAddress []MpIPAddressv200 `json:"mpIpAddresses,omitempty"` // The list of IP addresses and corresponding type information for the Management Processor.
}

// MpIPAddressv200 -
type MpIPAddressv200 struct {
	Address string `json:"address,omitempty"` // address An IP address for the Management Processor. string
	Type    string `json:"type,omitempty"`    // type The type of IP address. The following are useful values for the IP address type: Static - Static IP address configuration; DHCP - Dynamic host configuration protocol; SLAAC - Stateless address autoconfiguration (IPv6); LinkLocal - Link-local address (IPv6);
}

// MpIPTypev200 Type constant
type MpIPTypev200 int

// const block
const (
	MpDHCP MpIPTypev200 = 1 + iota
	MpLinkLocal
	MpLinkLocalRequired
	MpLookup
	MpSlaaC
	MpStatic
	MpUndefined
)

var mpiptypevlist = [...]string{
	"DHCP",
	"LinkLocal",
	"LinkLocal_Required",
	"Lookup",
	"SLAAC",
	"Static",
	"Undefined",
}

// String helper for MpIPTypev200
func (o MpIPTypev200) String() string { return mpiptypevlist[o-1] }

// Equal helper for MpIPTypev200
func (o MpIPTypev200) Equal(s string) bool {
	return (strings.ToUpper(s) == strings.ToUpper(o.String()))
}

// PortMapv200 -
type PortMapv200 struct {
	DeviceSlots []DeviceSlotsv200 `json:"deviceSlots,omitempty"` //  List of each slot found on the server hardware. read only
}

// DeviceSlotsv200 -
type DeviceSlotsv200 struct {
	DeviceName    string             `json:"deviceName,omitempty"`    // deviceName The name or model of the adapter. string read only
	DeviceNumber  int                `json:"deviceNumber,omitempty"`  // deviceNumber The device number of a blade server in an enclosure. integer read only
	Location      string             `json:"location,omitempty"`      // location The location of the adapter in the server. Lom indicates LAN on motherboard, Flb is for FlexibleLOM for blades and Mezz is for Mezzanine adapters.
	PhysicalPorts []PhysicalPortv200 `json:"physicalPorts,omitempty"` // physicalPorts        //
	SlotNumber    int                `json:"slotNumber,omitempty"`    // slotNumber The slot number of the adapter on the server hardware within its specified location. integer read only
}

// PhysicalPortv200 -
type PhysicalPortv200 struct {
	InterconnectPort         int               `json:"interconnectPort,omitempty"`         // interconnectPort The downlink port number on the interconnect that hosts network connections for this adapter port. If the adapter port is not connected to an interconnect downlink port, the value will be 0. integer read only
	InterconnectURI          utils.Nstring     `json:"interconnectUri,omitempty"`          // interconnectUri The URI of the interconnect that hosts network connections for this adapter port. string read only
	MAC                      string            `json:"mac,omitempty"`                      // mac Physical mac address of this physical port. string read only
	PhysicalInterconnectPort int               `json:"physicalInterconnectPort,omitempty"` // physicalInterconnectPort The downlink port number on the interconnect to which the adapter port is physically connected. If the adapter port is not connected to an interconnect downlink port, the value will be 0. integer read only
	PhysicalInterconnectURI  utils.Nstring     `json:"physicalInterconnectUri,omitempty"`  // physicalInterconnectUri The URI of the interconnect to which the adapter port is physically connected. string read only
	PortNumber               int               `json:"portNumber,omitempty"`               // portNumber Physical port number of the adapter. integer read only
	Type                     string            `json:"type,omitempty"`                     // type Physical port type. Values include Ethernet and FibreChannel. Physical Server Port Type read only
	VirtualPorts             []VirtualPortv200 `json:"virtualPorts,omitempty"`             // For Flex-capable devices, a list of FlexNICs defined on the server. array of Server Fabric Virtual Port read only
	WWN                      string            `json:"wwn,omitempty"`                      // wwn The world wide name of this physical port. string read only
}

// TODO : implement const for type on PhysicalPortv200
// Ethernet Ethernet network
// FibreChannel Fibre Channel network
// InfiniBand

// VirtualPortv200 -
type VirtualPortv200 struct {
	CurrentAllocatedVirtualFunctionCount int    `json:"currentAllocatedVirtualFunctionCount,omitempty"` // currentAllocatedVirtualFunctionCount The number of virtual functions presently allocated to this virtual port. integer read only
	MAC                                  string `json:"mac,omitempty"`                                  // mac The mac address assigned to this virtual port. string read only
	PortFunction                         string `json:"portFunction,omitempty"`                         // portFunction The function identifier for this FlexNIC, such as a, b, c or d. string read only
	PortNumber                           int    `json:"portNumber,omitempty"`                           // portNumber The port number assigned to this virtual port. integer read only
	WWNN                                 string `json:"WWNN,omitempty"`                                 // wwnn The world wide node name assigned to this virtual port. string read only
	WWPN                                 string `json:"WWPN,omitempty"`                                 // wwpn The world wide port name assigned to this virtual port. string read only
}

// ServerSettingsv200 -
type ServerSettingsv200 struct {
	FirmwareAndDriversInstallState *FirmwareAndDriversInstallStatev200 `json:"firmwareAndDriversInstallState,omitempty"` //  firmwareAndDriversInstallState The current installation status details of the firmware and/or OS drivers on the server.
	HPSmartUpdateToolStatus        *HpSmartUpdateToolStatusv200        `json:"hpSmartUpdateToolStatus,omitempty"`        // The status of HP Smart Update Tool installed on the server.
}

// FirmwareAndDriversInstallStatev200 -
type FirmwareAndDriversInstallStatev200 struct {
	InstallState            string `json:"installState,omitempty"`            // installState The installation state information of the firmware and/or OS drivers on the server.
	InstalledStateTimestamp string `json:"installedStateTimestamp,omitempty"` // The timestamp information indicating the time when the install state value got updated. string
}

//TODO: const for FirmwareInstallState
// ActivateFailed Indicates activation of one or more smart components failed on the server.
// Activated Indicates all the smart components from the SPP bundle specified in the firmware and driver baseline settings are installed and activated on the server.
// Activating Indicates HP Smart Update Tool is activating the installed smart components.
// InstallFailed Indicates HP Smart Update Tool has failed installing one or more smart components.
// InstalledPendingReboot Indicates HP Smart Update Tool has completed installing the smart components, however the server needs to be rebooted for the updates to take effect.
// Installing Indicates HP Smart Update Tool is installing the smart components from the staged location.
// Pending Indicates the firmware and/or OS driver baseline settings have been applied to the server hardware and will take effect when HP Smart Update tool updates firmware and/or OS driver components based on these settings.
// StageFailed Indicates HP Smart Update Tool has failed to stage the smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Staged Indicates HP Smart Update Tool has completed staging the smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Staging Indicates HP Smart Update Tool is staging the firmware and/or OS driver smart components from the SPP bundle specified in the firmware and/or OS driver baseline settings.
// Uninitialized Indicates the current firmware and/or OS driver settings have been cleared. No components will be updated on the server.
// Unknown Indicates the server failed to return the current settings, therefore, the actual values might not be current.

type HpSmartUpdateToolStatusv200 struct {
	HPSUTInstallState string `json:"hpSUTInstallState,omitempty"` // hpSUTInstallState HpSUT Install State Enum
	InstallState      string `json:"installState,omitempty"`      // installState HP Smart Update Tool's installed state on the server indicating whether it is installed, not installed or unknown.
	LastOperationTime string `json:"lastOperationTime,omitempty"` // lastOperationTime The timestamp indicating when HP Smart Update Tool was active or running a firmware update operation. string
	Mode              string `json:"mode,omitempty"`              // mode The current run mode configured for HP Smart Update Tool installed on the server. string
	ServiceState      string `json:"serviceState,omitempty"`      // serviceState The state of the HP Smart Update Tool Service running on the server operating system. string
	Version           string `json:"version,omitempty"`           // version The current version of the HP Smart Update Tool installed on the server. string
}

// Signaturev200 -
type Signaturev200 struct {
	PersonalityChecksum int `json:"personalityChecksum,omitempty"` // A calculated checksum of the server 'personality,' based on the defined connections and server identifiers. integer read only
	ServerHwChecksum    int `json:"serverHwChecksum,omitempty"`    // A calculated checksum of the server hardware, based on the hardware components installed in the server. integer read only
}
<|endoftext|>


<commit_before>// HackTunnel project
// (C) 2015 DevHQ, http://devhq.io
// License: AGPL 3

package main

import (
	"flag"
	"fmt"
	"hacktunnel/config"
	"hacktunnel/dbcontext"
	"hacktunnel/stat"
	"hacktunnel/tunnel"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"runtime/debug"
	"syscall"
	"time"

	"github.com/devhq-io/ax"
	"github.com/devhq-io/endless"
	"github.com/gorilla/mux"
)

var (
	tlsFilesPath    string = "."
	tlsCertFileName string = "tls-cert.pem"
	tlsKeyFileName  string = "tls.key"
	logFile         *os.File
)

func setupLogger(which string) {
	switch which {
	case "null":
		log.SetOutput(ioutil.Discard)
	case "stdout":
		log.SetOutput(os.Stdout)
	case "file":
		logFile, err := os.OpenFile("log.txt",
			os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			panic(err)
		}
		log.SetOutput(logFile)
	}
}

func startGcLoop(period time.Duration) {
	go func(period time.Duration) {
		for {
			debug.FreeOSMemory()
			time.Sleep(period * time.Second)
		}
	}(period)
}

func indexFileHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if config.C().HttpServerUseTls {
		w.Header().Set("Strict-Transport-Security",
			"max-age=31536000; includeSubDomains")
	}
	http.ServeFile(w, r, "./www/index.html")
}

func redirHandler(w http.ResponseWriter, req *http.Request) {
	http.Redirect(w, req, config.C().RedirTo+req.RequestURI,
		http.StatusMovedPermanently)
}

func setupRoutes(r *ax.Router) {
	r.StrictSlash(true)
	r.HandleFunc("/", indexFileHandler).Methods("GET")
	r.HandleFunc("/{tunnel_name}", indexFileHandler).Methods("GET")

	http.Handle("/", r)
}

func preSigHup() {
	log.Printf("Got SIGHUP signal: hot code reload\n")
}

func preSigInt() {
	log.Printf("Got SIGTERM signal\n")
	// server will be shut down in 10 sec
	endless.DefaultHammerTime = 10 * time.Second
	tunnel.KillAll()
	log.Printf("All clients were shut down\n")
	tunnel.Shutdown()
}

/*
 * Stopping the server:
 * - hot code reloading: kill -SIGHUP `pidof hacktunnel`
 * - shutdown all clients gracefully: kill -SIGINT `pidof hacktunnel`
 */

func redir() {
	port := config.C().RedirFromPort
	if port == 0 {
		port = 80
	}
	log.Printf("Serving %d for redirection\n", port)
	addr := fmt.Sprintf(":%d", port)
	r := mux.NewRouter()
	r.HandleFunc("/hello", redirHandler).Methods("GET")
	srv := endless.NewServer(addr, r)
	log.Println(srv.ListenAndServe())
}

func start(r *ax.Router, port int, usetls bool) {
	log.Printf("Serving %d, use TLS: %v\n", port, usetls)
	addr := fmt.Sprintf(":%d", port)
	srv := endless.NewServer(addr, nil)
	srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGHUP] = append(
		srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGHUP],
		preSigHup)
	srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGINT] = append(
		srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGINT],
		preSigInt)
	endless.DefaultHammerTime = -1 // disable hammering the server
	if usetls {
		certfname := path.Join(tlsFilesPath, tlsCertFileName)
		keyfname := path.Join(tlsFilesPath, tlsKeyFileName)
		if config.C().RedirTo != "" {
			go redir()
		}
		log.Println(srv.ListenAndServeTLS(certfname, keyfname))
	} else {
		log.Println(srv.ListenAndServe())
	}
}

func setMessageHandlers() {
	ax.OnEnter(onEnter)
	ax.OnLeave(onLeave)
	ax.OnJson("query_tunnel", tunnel.OnQueryTunnel)
	ax.OnJson("enter_tunnel", tunnel.OnEnterTunnel)
	ax.OnJson("leave_tunnel", onLeaveTunnel)
	ax.OnJson("simple_send", tunnel.OnSimpleSend)
}

func init() {
	var configName string
	flag.StringVar(&configName, "config", "hacktunnel.conf", "configuration file")
	flag.Parse()
	config.Init(configName)
	dbcontext.Init()
	stat.Init()
	tunnel.Init()
}

func main() {
	port := config.C().HttpServerPort
	connTimeout := config.C().ConnectionTimeout
	logtype := config.C().LogType
	if logtype == "" {
		logtype = "stdout"
	}
	setupLogger(logtype)
	startGcLoop(1000)
	usetls := config.C().HttpServerUseTls
	c := &ax.Config{ConnectionTimeout: connTimeout, UseTls: usetls}
	r := ax.Setup(c)
	setupRoutes(r)
	setMessageHandlers()
	start(r, port, usetls)
}

// *** Message handlers ***

func onEnter(c *ax.Client, r *http.Request) {
	stat.ClientEnter()
}

func onLeave(c *ax.Client) {
	tunnel.DoCleanup(c)
	stat.ClientLeave()
}

func onLeaveTunnel(c *ax.Client, _ interface{}) {
	tunnel.DoCleanup(c)
}
<commit_msg>fix HTTP->HTTPS redirect<commit_after>// HackTunnel project
// (C) 2015 DevHQ, http://devhq.io
// License: AGPL 3

package main

import (
	"flag"
	"fmt"
	"hacktunnel/config"
	"hacktunnel/dbcontext"
	"hacktunnel/stat"
	"hacktunnel/tunnel"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"runtime/debug"
	"syscall"
	"time"

	"github.com/devhq-io/ax"
	"github.com/devhq-io/endless"
	"github.com/gorilla/mux"
)

var (
	tlsFilesPath    string = "."
	tlsCertFileName string = "tls-cert.pem"
	tlsKeyFileName  string = "tls.key"
	logFile         *os.File
)

func setupLogger(which string) {
	switch which {
	case "null":
		log.SetOutput(ioutil.Discard)
	case "stdout":
		log.SetOutput(os.Stdout)
	case "file":
		logFile, err := os.OpenFile("log.txt",
			os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			panic(err)
		}
		log.SetOutput(logFile)
	}
}

func startGcLoop(period time.Duration) {
	go func(period time.Duration) {
		for {
			debug.FreeOSMemory()
			time.Sleep(period * time.Second)
		}
	}(period)
}

func indexFileHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if config.C().HttpServerUseTls {
		w.Header().Set("Strict-Transport-Security",
			"max-age=31536000; includeSubDomains")
	}
	http.ServeFile(w, r, "./www/index.html")
}

func redirHandler(w http.ResponseWriter, req *http.Request) {
	http.Redirect(w, req, config.C().RedirTo, http.StatusMovedPermanently)
}

func setupRoutes(r *ax.Router) {
	r.StrictSlash(true)
	r.HandleFunc("/", indexFileHandler).Methods("GET")
	r.HandleFunc("/{tunnel_name}", indexFileHandler).Methods("GET")

	http.Handle("/", r)
}

func preSigHup() {
	log.Printf("Got SIGHUP signal: hot code reload\n")
}

func preSigInt() {
	log.Printf("Got SIGTERM signal\n")
	// server will be shut down in 10 sec
	endless.DefaultHammerTime = 10 * time.Second
	tunnel.KillAll()
	log.Printf("All clients were shut down\n")
	tunnel.Shutdown()
}

/*
 * Stopping the server:
 * - hot code reloading: kill -SIGHUP `pidof hacktunnel`
 * - shutdown all clients gracefully: kill -SIGINT `pidof hacktunnel`
 */

func redir() {
	port := config.C().RedirFromPort
	if port == 0 {
		port = 80
	}
	log.Printf("Serving %d for redirection\n", port)
	addr := fmt.Sprintf(":%d", port)
	r := mux.NewRouter()
	r.HandleFunc("/", redirHandler).Methods("GET")
	r.HandleFunc("/{tunnel_name}", redirHandler).Methods("GET")
	srv := endless.NewServer(addr, r)
	log.Println(srv.ListenAndServe())
}

func start(r *ax.Router, port int, usetls bool) {
	log.Printf("Serving %d, use TLS: %v\n", port, usetls)
	addr := fmt.Sprintf(":%d", port)
	srv := endless.NewServer(addr, nil)
	srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGHUP] = append(
		srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGHUP],
		preSigHup)
	srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGINT] = append(
		srv.SignalHooks[endless.PRE_SIGNAL][syscall.SIGINT],
		preSigInt)
	endless.DefaultHammerTime = -1 // disable hammering the server
	if usetls {
		certfname := path.Join(tlsFilesPath, tlsCertFileName)
		keyfname := path.Join(tlsFilesPath, tlsKeyFileName)
		if config.C().RedirTo != "" {
			go redir()
		}
		log.Println(srv.ListenAndServeTLS(certfname, keyfname))
	} else {
		log.Println(srv.ListenAndServe())
	}
}

func setMessageHandlers() {
	ax.OnEnter(onEnter)
	ax.OnLeave(onLeave)
	ax.OnJson("query_tunnel", tunnel.OnQueryTunnel)
	ax.OnJson("enter_tunnel", tunnel.OnEnterTunnel)
	ax.OnJson("leave_tunnel", onLeaveTunnel)
	ax.OnJson("simple_send", tunnel.OnSimpleSend)
}

func init() {
	var configName string
	flag.StringVar(&configName, "config", "hacktunnel.conf", "configuration file")
	flag.Parse()
	config.Init(configName)
	dbcontext.Init()
	stat.Init()
	tunnel.Init()
}

func main() {
	port := config.C().HttpServerPort
	connTimeout := config.C().ConnectionTimeout
	logtype := config.C().LogType
	if logtype == "" {
		logtype = "stdout"
	}
	setupLogger(logtype)
	startGcLoop(1000)
	usetls := config.C().HttpServerUseTls
	c := &ax.Config{ConnectionTimeout: connTimeout, UseTls: usetls}
	r := ax.Setup(c)
	setupRoutes(r)
	setMessageHandlers()
	start(r, port, usetls)
}

// *** Message handlers ***

func onEnter(c *ax.Client, r *http.Request) {
	stat.ClientEnter()
}

func onLeave(c *ax.Client) {
	tunnel.DoCleanup(c)
	stat.ClientLeave()
}

func onLeaveTunnel(c *ax.Client, _ interface{}) {
	tunnel.DoCleanup(c)
}
<|endoftext|>


<commit_before>// redis cache backend implementation for persistent storage

package main

import (
	"bytes"
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/boltdb/bolt"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"
const requestsBucketName = "rqbucket"

type Cache struct {
	pool   *redis.Pool
	prefix string

	db             *bolt.DB
	requestsBucket []byte
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		// getting payload for debugging
		var payload string
		switch v := value.(type) {
		case bytes.Buffer: // return as is
			payload = v.String() // Here v is of type bytes.Buffer
		}
		log.WithFields(log.Fields{
			"error":   err.Error(),
			"key":     fmt.Sprintf(c.prefix + key),
			"payload": payload,
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

func (c *Cache) Set(key, value []byte) error {
	err := c.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists(c.requestsBucket)
		if err != nil {
			return err
		}
		err = bucket.Put(key, value)
		if err != nil {
			return err
		}
		return nil
	})

	return err
}
// getAllKeys returns all keys for specified (or default) prefix
func (c *Cache) getAllKeys() ([]string, error) {

	client := c.pool.Get()
	defer client.Close()

	values, err := redis.Strings(client.Do("KEYS", fmt.Sprintf(c.prefix+"*")))

	return values, err
}

// getAllValues returns values for specified keys
func (c *Cache) getAllValues(keys []string) ([]string, error) {

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Getting all supplied values")

	client := c.pool.Get()
	defer client.Close()

	// preparing keys
	var args []interface{}
	for _, k := range keys {
		args = append(args, k)
	}

	jsonStr, err := redis.Strings(client.Do("MGET", args...))

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Returning supplied values")

	return jsonStr, err

}

// get returns key from cache
func (c *Cache) get(key string) ([]byte, error) {

	client := c.pool.Get()
	defer client.Close()

	value, err := redis.Bytes(client.Do("GET", fmt.Sprintf(c.prefix+key)))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Debug("Key found!")
	}

	return value, err
}

// delete removes specified entry from cache
func (c *Cache) delete(key string) error {
	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("DEL", key)

	return err

}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}

	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{
				"Error": err.Error(),
			}).Warn("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Warn("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Debug("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<commit_msg>get key method<commit_after>// redis cache backend implementation for persistent storage

package main

import (
	"bytes"
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/boltdb/bolt"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"
const requestsBucketName = "rqbucket"

type Cache struct {
	pool   *redis.Pool
	prefix string

	db             *bolt.DB
	requestsBucket []byte
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		// getting payload for debugging
		var payload string
		switch v := value.(type) {
		case bytes.Buffer: // return as is
			payload = v.String() // Here v is of type bytes.Buffer
		}
		log.WithFields(log.Fields{
			"error":   err.Error(),
			"key":     fmt.Sprintf(c.prefix + key),
			"payload": payload,
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

func (c *Cache) Set(key, value []byte) error {
	err := c.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists(c.requestsBucket)
		if err != nil {
			return err
		}
		err = bucket.Put(key, value)
		if err != nil {
			return err
		}
		return nil
	})

	return err
}

func (c *Cache) Get(key []byte) (value []byte, err error) {
	err = c.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(c.requestsBucket)
		if bucket == nil {
			return fmt.Errorf("Bucket %q not found!", c.requestsBucket)
		}
		value = bucket.Get(key)
		return nil
	})

	return
}

// getAllKeys returns all keys for specified (or default) prefix
func (c *Cache) getAllKeys() ([]string, error) {

	client := c.pool.Get()
	defer client.Close()

	values, err := redis.Strings(client.Do("KEYS", fmt.Sprintf(c.prefix+"*")))

	return values, err
}

// getAllValues returns values for specified keys
func (c *Cache) getAllValues(keys []string) ([]string, error) {

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Getting all supplied values")

	client := c.pool.Get()
	defer client.Close()

	// preparing keys
	var args []interface{}
	for _, k := range keys {
		args = append(args, k)
	}

	jsonStr, err := redis.Strings(client.Do("MGET", args...))

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Returning supplied values")

	return jsonStr, err

}

// get returns key from cache
func (c *Cache) get(key string) ([]byte, error) {

	client := c.pool.Get()
	defer client.Close()

	value, err := redis.Bytes(client.Do("GET", fmt.Sprintf(c.prefix+key)))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Debug("Key found!")
	}

	return value, err
}

// delete removes specified entry from cache
func (c *Cache) delete(key string) error {
	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("DEL", key)

	return err

}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}

	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{
				"Error": err.Error(),
			}).Warn("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Warn("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Debug("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<|endoftext|>