<commit_before>/*
Copyright 2019 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"

	"k8s.io/minikube/pkg/minikube/cluster"
	"k8s.io/minikube/pkg/minikube/config"
	"k8s.io/minikube/pkg/minikube/exit"
	"k8s.io/minikube/pkg/minikube/machine"
	"k8s.io/minikube/pkg/minikube/out"

	"github.com/golang/glog"
	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
)

var (
	output string
)

var profileListCmd = &cobra.Command{
	Use:   "list",
	Short: "Lists all minikube profiles.",
	Long:  "Lists all valid minikube profiles and detects all possible invalid profiles.",
	Run: func(cmd *cobra.Command, args []string) {

		switch strings.ToLower(output) {
		case "json":
			printProfilesJSON()
		case "table":
			printProfilesTable()
		default:
			exit.WithCodeT(exit.BadUsage, fmt.Sprintf("invalid output format: %s. Valid values: 'table', 'json'", output))
		}

	},
}

var printProfilesTable = func() {

	var validData [][]string
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Profile", "VM Driver", "NodeIP", "Node Port", "Kubernetes Version", "Status"})
	table.SetAutoFormatHeaders(false)
	table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
	table.SetCenterSeparator("|")
	validProfiles, invalidProfiles, err := config.ListProfiles()

	if len(validProfiles) == 0 || err != nil {
		exit.UsageT("No minikube profile was found. You can create one using `minikube start`.")
	}
	api, err := machine.NewAPIClient()
	if err != nil {
		glog.Infof("failed to get machine api client %v", err)
	}
	defer api.Close()

	for _, p := range validProfiles {
		p.Status, err = cluster.GetHostStatus(api, p.Name)
		if err != nil {
			glog.Infof("error getting host status for %v", err)
		}
		cp, err := config.PrimaryControlPlane(*p.Config)
		if err != nil {
			exit.WithError("profile has no control plane", err)
		}
		validData = append(validData, []string{p.Name, p.Config.VMDriver, cp.IP, strconv.Itoa(cp.Port), p.Config.KubernetesConfig.KubernetesVersion, p.Status})
	}

	table.AppendBulk(validData)
	table.Render()

	if invalidProfiles != nil {
		out.T(out.WarningType, "Found {{.number}} invalid profile(s) ! ", out.V{"number": len(invalidProfiles)})
		for _, p := range invalidProfiles {
			out.T(out.Empty, "\t "+p.Name)
		}
		out.T(out.Tip, "You can delete them using the following command(s): ")
		for _, p := range invalidProfiles {
			out.String(fmt.Sprintf("\t $ minikube delete -p %s \n", p.Name))
		}

	}

	if err != nil {
		exit.WithCodeT(exit.Config, fmt.Sprintf("error loading profiles: %v", err))
	}

}

var printProfilesJSON = func() {
	api, err := machine.NewAPIClient()
	if err != nil {
		glog.Infof("failed to get machine api client %v", err)
	}
	defer api.Close()

	validProfiles, invalidProfiles, err := config.ListProfiles()
	for _, v := range validProfiles {
		status, err := cluster.GetHostStatus(api, v.Name)
		if err != nil {
			glog.Infof("error getting host status for  %v", err)
		}
		v.Status = status
	}

	var valid []*config.Profile
	var invalid []*config.Profile

	if validProfiles != nil {
		valid = validProfiles
	} else {
		valid = []*config.Profile{}
	}

	if invalidProfiles != nil {
		invalid = invalidProfiles
	} else {
		invalid = []*config.Profile{}
	}

	var body = map[string]interface{}{}

	if err == nil || os.IsNotExist(err) {
		body["valid"] = valid
		body["invalid"] = invalid
		jsonString, _ := json.Marshal(body)
		out.String(string(jsonString))
	} else {
		body["error"] = err
		jsonString, _ := json.Marshal(body)
		out.String(string(jsonString))
		os.Exit(exit.Failure)
	}
}

func init() {
	profileListCmd.Flags().StringVarP(&output, "output", "o", "table", "The output format. One of 'json', 'table'")
	ProfileCmd.AddCommand(profileListCmd)
}
<commit_msg>Allow 'profiles list' to work even if a profile has no control plane<commit_after>/*
Copyright 2019 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"

	"k8s.io/minikube/pkg/minikube/cluster"
	"k8s.io/minikube/pkg/minikube/config"
	"k8s.io/minikube/pkg/minikube/exit"
	"k8s.io/minikube/pkg/minikube/machine"
	"k8s.io/minikube/pkg/minikube/out"

	"github.com/golang/glog"
	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
)

var (
	output string
)

var profileListCmd = &cobra.Command{
	Use:   "list",
	Short: "Lists all minikube profiles.",
	Long:  "Lists all valid minikube profiles and detects all possible invalid profiles.",
	Run: func(cmd *cobra.Command, args []string) {

		switch strings.ToLower(output) {
		case "json":
			printProfilesJSON()
		case "table":
			printProfilesTable()
		default:
			exit.WithCodeT(exit.BadUsage, fmt.Sprintf("invalid output format: %s. Valid values: 'table', 'json'", output))
		}

	},
}

var printProfilesTable = func() {

	var validData [][]string
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Profile", "VM Driver", "NodeIP", "Node Port", "Kubernetes Version", "Status"})
	table.SetAutoFormatHeaders(false)
	table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
	table.SetCenterSeparator("|")
	validProfiles, invalidProfiles, err := config.ListProfiles()

	if len(validProfiles) == 0 || err != nil {
		exit.UsageT("No minikube profile was found. You can create one using `minikube start`.")
	}
	api, err := machine.NewAPIClient()
	if err != nil {
		glog.Infof("failed to get machine api client %v", err)
	}
	defer api.Close()

	for _, p := range validProfiles {
		p.Status, err = cluster.GetHostStatus(api, p.Name)
		if err != nil {
			glog.Infof("error getting host status for %s: %v", p.Name, err)
		}
		cp, err := config.PrimaryControlPlane(*p.Config)
		if err != nil {
			glog.Errorf("%q has no control plane: %v", p.Name, err)
			// Print the data we know about anyways
		}
		validData = append(validData, []string{p.Name, p.Config.VMDriver, cp.IP, strconv.Itoa(cp.Port), p.Config.KubernetesConfig.KubernetesVersion, p.Status})
	}

	table.AppendBulk(validData)
	table.Render()

	if invalidProfiles != nil {
		out.T(out.WarningType, "Found {{.number}} invalid profile(s) ! ", out.V{"number": len(invalidProfiles)})
		for _, p := range invalidProfiles {
			out.T(out.Empty, "\t "+p.Name)
		}
		out.T(out.Tip, "You can delete them using the following command(s): ")
		for _, p := range invalidProfiles {
			out.String(fmt.Sprintf("\t $ minikube delete -p %s \n", p.Name))
		}

	}

	if err != nil {
		exit.WithCodeT(exit.Config, fmt.Sprintf("error loading profiles: %v", err))
	}

}

var printProfilesJSON = func() {
	api, err := machine.NewAPIClient()
	if err != nil {
		glog.Infof("failed to get machine api client %v", err)
	}
	defer api.Close()

	validProfiles, invalidProfiles, err := config.ListProfiles()
	for _, v := range validProfiles {
		status, err := cluster.GetHostStatus(api, v.Name)
		if err != nil {
			glog.Infof("error getting host status for %s: %v", v.Name, err)
		}
		v.Status = status
	}

	var valid []*config.Profile
	var invalid []*config.Profile

	if validProfiles != nil {
		valid = validProfiles
	} else {
		valid = []*config.Profile{}
	}

	if invalidProfiles != nil {
		invalid = invalidProfiles
	} else {
		invalid = []*config.Profile{}
	}

	var body = map[string]interface{}{}

	if err == nil || os.IsNotExist(err) {
		body["valid"] = valid
		body["invalid"] = invalid
		jsonString, _ := json.Marshal(body)
		out.String(string(jsonString))
	} else {
		body["error"] = err
		jsonString, _ := json.Marshal(body)
		out.String(string(jsonString))
		os.Exit(exit.Failure)
	}
}

func init() {
	profileListCmd.Flags().StringVarP(&output, "output", "o", "table", "The output format. One of 'json', 'table'")
	ProfileCmd.AddCommand(profileListCmd)
}
<|endoftext|>


<commit_before>package module

import (
	"os"
	"path/filepath"
	"strings"
)

// All valid module files must have this extension
const moduleExtension = ".hcl"

// ModuleRegistry type contains discovered modules as returned by the
// DiscoverModules() function.
// Keys of the map are the module names and their values are the
// absolute path to the discovered module files
type ModuleRegistry map[string]string

// NewModuleRegistry creates a new empty module registry
func NewModuleRegistry() ModuleRegistry {
	registry := make(map[string]string)

	return registry
}

// Discover is used to discover valid modules in a given module path
func Discover(root string) (ModuleRegistry, error) {
	registry := NewModuleRegistry()

	// Module walker function
	walker := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// Skip directory entries
		if info.IsDir() {
			return nil
		}

		// Skip files which don't appear to be valid module files
		if filepath.Ext(info.Name()) != moduleExtension {
			return nil
		}

		// Remove the root path portion from the discovered module file,
		// remove the module file extension and register the module
		moduleFileWithExt := strings.TrimPrefix(path, root)
		moduleNameWithExt := strings.TrimSuffix(moduleFileWithExt, moduleExtension)
		moduleName := strings.Trim(moduleNameWithExt, string(os.PathSeparator))
		absPath, err := filepath.Abs(path)
		if err != nil {
			return err
		}

		registry[moduleName] = absPath

		return nil
	}

	err := filepath.Walk(root, walker)
	if err != nil {
		return registry, err
	}

	return registry, nil
}
<commit_msg>module.Discover considers JSON modules as valid ones as well<commit_after>package module

import (
	"os"
	"path/filepath"
	"strings"
)

// Valid module files must have one of these extension
var moduleExtension = []string{".hcl", ".json"}

// ModuleRegistry type contains discovered modules as returned by the
// DiscoverModules() function.
// Keys of the map are the module names and their values are the
// absolute path to the discovered module files
type ModuleRegistry map[string]string

// NewModuleRegistry creates a new empty module registry
func NewModuleRegistry() ModuleRegistry {
	registry := make(map[string]string)

	return registry
}

// Discover is used to discover valid modules in a given module path
func Discover(root string) (ModuleRegistry, error) {
	registry := NewModuleRegistry()

	// Module walker function
	walker := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// Skip directory entries
		if info.IsDir() {
			return nil
		}

		// Skip files which don't appear to be valid module files
		fileExt := filepath.Ext(info.Name())
		validExt := false
		for _, ext := range moduleExtension {
			if fileExt == ext {
				validExt = true
				break
			}
		}

		if !validExt {
			return nil
		}

		// Remove the root path portion from the discovered module file,
		// remove the module file extension and register the module
		moduleFileWithExt := strings.TrimPrefix(path, root)
		moduleNameWithExt := strings.TrimSuffix(moduleFileWithExt, fileExt)
		moduleName := strings.Trim(moduleNameWithExt, string(os.PathSeparator))
		absPath, err := filepath.Abs(path)
		if err != nil {
			return err
		}

		registry[moduleName] = absPath

		return nil
	}

	err := filepath.Walk(root, walker)
	if err != nil {
		return registry, err
	}

	return registry, nil
}
<|endoftext|>


<commit_before>// Package blockfetcher aims to reduce boilerplate code that one needs to write
// over and over again when implementing a program that is processing blocks
// that are being fetched over steemd WebSocket RPC endpoint.
//
// All you need from now in is to import this package and implement BlockProcessor interface,
// then run the block fetcher with your custom BlockProcessor implementation:
//
//     ctx, err := blockfetcher.Run(blockProcessor)
//
// You can wait for the fetcher to be done by calling
//
//     err := ctx.Wait()
//
// In case you want to interrupt the process, just call
//
//     ctx.Interrupt()
//     err := ctx.Wait()
package blockfetcher

import (
	"time"

	"github.com/go-steem/rpc"
	"github.com/pkg/errors"
	"gopkg.in/tomb.v2"
)

// BlockProcessor is the interface that represents the block processing logic.
//
// When an error is returned from any for the following methods,
// the fetching process is interrupted and Finalize() is called.
type BlockProcessor interface {
	// BlockRange is called at the beginning to let the block fetching logic know
	// what blocks to fetch and pass to ProcessBlock.
	//
	// In case blockRangeTo returned is 0, the fetcher will keep fetching new blocks
	// forever as they arrive (until interrupted, of course).
	BlockRange() (blockRangeFrom, blockRangeTo uint32)

	// ProcessBlock is called when a new block is received.
	ProcessBlock(block *rpc.Block) error

	// Finalize is called when the whole block range is fetcher or the process is interrupted.
	Finalize() error
}

// Context represents a running block fetcher that can be interrupted.
type Context struct {
	client *rpc.Client

	processor BlockProcessor

	blockCh chan *rpc.Block

	t tomb.Tomb
}

// Run spawns a new block fetcher using the given BlockProcessor.
//
// The fetcher keeps fetching blocks until the whole block range specified is fetched
// or an error is encountered. It is not trying to be clever about closed connections and such.
//
// client.Close() is not called by this package, it has to be called manually.
func Run(client *rpc.Client, processor BlockProcessor) (*Context, error) {
	// Prepare a new Context object.
	ctx := &Context{
		client:    client,
		processor: processor,
		blockCh:   make(chan *rpc.Block),
	}

	// Start the fetcher and the finalizer.
	ctx.t.Go(ctx.fetcher)
	ctx.t.Go(ctx.finalizer)

	// Return the new context.
	return ctx, nil
}

// Interrupt interrupts the block fetcher and stops the fetching process.
func (ctx *Context) Interrupt() {
	ctx.t.Kill(nil)
}

// Wait blocks until the fetcher is stopped and returns any error encountered.
func (ctx *Context) Wait() error {
	return ctx.t.Wait()
}

func (ctx *Context) fetcher() error {
	// Get the block range to process.
	from, to := ctx.processor.BlockRange()

	// Decide whether to fetch a closed range or watch
	// and enter the right loop accordingly.
	var err error
	if to == 0 {
		err = ctx.blockWatcher(from)
	} else {
		err = ctx.blockFetcher(from, to)
	}
	return err
}

func (ctx *Context) finalizer() error {
	// Wait for the dying signal.
	<-ctx.t.Dying()

	// Run the finalizer.
	if err := ctx.processor.Finalize(); err != nil {
		return errors.Wrap(err, "BlockProcessor.Finalize() failed")
	}
	return nil
}

func (ctx *Context) blockWatcher(from uint32) error {
	next := from

	// Get config.
	config, err := ctx.client.GetConfig()
	if err != nil {
		return errors.Wrap(err, "failed to get steemd config")
	}

	// Fetch and process all blocks matching the given range.
	for {
		// Get current properties.
		props, err := ctx.client.GetDynamicGlobalProperties()
		if err != nil {
			return errors.Wrap(err, "failed to get steemd dynamic global properties")
		}

		// Process new blocks.
		for ; props.LastIrreversibleBlockNum >= next; next++ {
			if err := ctx.fetchAndProcess(next); err != nil {
				return err
			}
		}

		// Wait for STEEMIT_BLOCK_INTERVAL seconds before the next iteration.
		// In case Interrupt() is called, we exit immediately.
		select {
		case <-time.After(time.Duration(config.SteemitBlockInterval) * time.Second):
		case <-ctx.t.Dying():
			return nil
		}
	}
}

func (ctx *Context) blockFetcher(from, to uint32) error {
	next := from

	// Make sure we are not doing bullshit.
	if from > to {
		return errors.Errorf("invalid block range: [%v, %v]", from, to)
	}

	// Fetch and process all blocks matching the given range.
	for ; next <= to; next++ {
		if err := ctx.fetchAndProcess(next); err != nil {
			return err
		}
	}

	// The whole range has been processed, we are done.
	return nil
}

func (ctx *Context) fetchAndProcess(blockNum uint32) (err error) {
	defer handlePanic(&err)

	// Check for the dying signal first.
	select {
	case <-ctx.t.Dying():
		return tomb.ErrDying
	default:
	}

	// Fetch the block.
	block, err := ctx.client.GetBlock(blockNum)
	if err != nil {
		return errors.Wrapf(err, "failed to fetch block %v", blockNum)
	}

	// Process the block.
	if err := ctx.processor.ProcessBlock(block); err != nil {
		return errors.Wrapf(err, "BlockProcessor.ProcessBlock() failed for block %v", blockNum)
	}
	return nil
}

func handlePanic(errPtr *error) {
	if r := recover(); r != nil {
		switch r := r.(type) {
		case error:
			*errPtr = errors.Wrap(r, "panic recovered")
		case string:
			*errPtr = errors.New(r)
		default:
			panic(r)
		}
	}
}
<commit_msg>Update to the latest go-steem/rpc interface<commit_after>// Package blockfetcher aims to reduce boilerplate code that one needs to write
// over and over again when implementing a program that is processing blocks
// that are being fetched over steemd WebSocket RPC endpoint.
//
// All you need from now in is to import this package and implement BlockProcessor interface,
// then run the block fetcher with your custom BlockProcessor implementation:
//
//     ctx, err := blockfetcher.Run(blockProcessor)
//
// You can wait for the fetcher to be done by calling
//
//     err := ctx.Wait()
//
// In case you want to interrupt the process, just call
//
//     ctx.Interrupt()
//     err := ctx.Wait()
package blockfetcher

import (
	"time"

	"github.com/go-steem/rpc"
	"github.com/go-steem/rpc/apis/database"
	"github.com/pkg/errors"
	"gopkg.in/tomb.v2"
)

// BlockProcessor is the interface that represents the block processing logic.
//
// When an error is returned from any for the following methods,
// the fetching process is interrupted and Finalize() is called.
type BlockProcessor interface {
	// BlockRange is called at the beginning to let the block fetching logic know
	// what blocks to fetch and pass to ProcessBlock.
	//
	// In case blockRangeTo returned is 0, the fetcher will keep fetching new blocks
	// forever as they arrive (until interrupted, of course).
	BlockRange() (blockRangeFrom, blockRangeTo uint32)

	// ProcessBlock is called when a new block is received.
	ProcessBlock(block *database.Block) error

	// Finalize is called when the whole block range is fetcher or the process is interrupted.
	Finalize() error
}

// Context represents a running block fetcher that can be interrupted.
type Context struct {
	client *rpc.Client

	processor BlockProcessor

	blockCh chan *database.Block

	t tomb.Tomb
}

// Run spawns a new block fetcher using the given BlockProcessor.
//
// The fetcher keeps fetching blocks until the whole block range specified is fetched
// or an error is encountered. It is not trying to be clever about closed connections and such.
//
// client.Close() is not called by this package, it has to be called manually.
func Run(client *rpc.Client, processor BlockProcessor) (*Context, error) {
	// Prepare a new Context object.
	ctx := &Context{
		client:    client,
		processor: processor,
		blockCh:   make(chan *database.Block),
	}

	// Start the fetcher and the finalizer.
	ctx.t.Go(ctx.fetcher)
	ctx.t.Go(ctx.finalizer)

	// Return the new context.
	return ctx, nil
}

// Interrupt interrupts the block fetcher and stops the fetching process.
func (ctx *Context) Interrupt() {
	ctx.t.Kill(nil)
}

// Wait blocks until the fetcher is stopped and returns any error encountered.
func (ctx *Context) Wait() error {
	return ctx.t.Wait()
}

func (ctx *Context) fetcher() error {
	// Get the block range to process.
	from, to := ctx.processor.BlockRange()

	// Decide whether to fetch a closed range or watch
	// and enter the right loop accordingly.
	var err error
	if to == 0 {
		err = ctx.blockWatcher(from)
	} else {
		err = ctx.blockFetcher(from, to)
	}
	return err
}

func (ctx *Context) finalizer() error {
	// Wait for the dying signal.
	<-ctx.t.Dying()

	// Run the finalizer.
	if err := ctx.processor.Finalize(); err != nil {
		return errors.Wrap(err, "BlockProcessor.Finalize() failed")
	}
	return nil
}

func (ctx *Context) blockWatcher(from uint32) error {
	next := from

	// Get config.
	config, err := ctx.client.Database.GetConfig()
	if err != nil {
		return errors.Wrap(err, "failed to get steemd config")
	}

	// Fetch and process all blocks matching the given range.
	for {
		// Get current properties.
		props, err := ctx.client.Database.GetDynamicGlobalProperties()
		if err != nil {
			return errors.Wrap(err, "failed to get steemd dynamic global properties")
		}

		// Process new blocks.
		for ; props.LastIrreversibleBlockNum >= next; next++ {
			if err := ctx.fetchAndProcess(next); err != nil {
				return err
			}
		}

		// Wait for STEEMIT_BLOCK_INTERVAL seconds before the next iteration.
		// In case Interrupt() is called, we exit immediately.
		select {
		case <-time.After(time.Duration(config.SteemitBlockInterval) * time.Second):
		case <-ctx.t.Dying():
			return nil
		}
	}
}

func (ctx *Context) blockFetcher(from, to uint32) error {
	next := from

	// Make sure we are not doing bullshit.
	if from > to {
		return errors.Errorf("invalid block range: [%v, %v]", from, to)
	}

	// Fetch and process all blocks matching the given range.
	for ; next <= to; next++ {
		if err := ctx.fetchAndProcess(next); err != nil {
			return err
		}
	}

	// The whole range has been processed, we are done.
	return nil
}

func (ctx *Context) fetchAndProcess(blockNum uint32) (err error) {
	defer handlePanic(&err)

	// Check for the dying signal first.
	select {
	case <-ctx.t.Dying():
		return tomb.ErrDying
	default:
	}

	// Fetch the block.
	block, err := ctx.client.Database.GetBlock(blockNum)
	if err != nil {
		return errors.Wrapf(err, "failed to fetch block %v", blockNum)
	}

	// Process the block.
	if err := ctx.processor.ProcessBlock(block); err != nil {
		return errors.Wrapf(err, "BlockProcessor.ProcessBlock() failed for block %v", blockNum)
	}
	return nil
}

func handlePanic(errPtr *error) {
	if r := recover(); r != nil {
		switch r := r.(type) {
		case error:
			*errPtr = errors.Wrap(r, "panic recovered")
		case string:
			*errPtr = errors.New(r)
		default:
			panic(r)
		}
	}
}
<|endoftext|>


<commit_before>package main

import "./cmd"

var commands map[string]*cmd.Command

func init() {
	initCommands()
}

func initCommands() {
	initCommandGgb()
}

func initCommandGgb() {
	cmd := cmd.NewCommand("ggb",
		"ggb [cmd]",
		"builds a go project with git submodule dependencies management",
		`ggb builds,
while ggb deps offers dependency management as git submodules`,
		nil)
	commands["ggb"] = cmd
}
<commit_msg>cmds.go: defines cmdggb, with global flags<commit_after>package main

import "./cmd"

var debug bool
var verbose bool
var help bool
var version bool

func init() {
	initCommands()
}

func initCommands() {
	initCommandGgb()
}

func initCommandGgb() {
	cmdggb := cmd.NewCommand("ggb",
		"ggb [cmd]",
		"builds a go project with git submodule dependencies management",
		`ggb builds,
while ggb deps offers dependency management as git submodules`,
		build, nil)

	gfs := cmdggb.GFS()
	gfs.BoolVarP(&help, "help", "h", false, "ggb usage")
	gfs.BoolVarP(&verbose, "verbose", "v", false, `display a verbose output
		not suited for batch usage`)
	gfs.BoolVarP(&debug, "debug", "d", false, "output debug informations (not for batch usage)")
	gfs.BoolVarP(&version, "version", "V", false, "display ggb version")
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"

	_ "github.com/boot2docker/boot2docker-cli/dummy"
	_ "github.com/boot2docker/boot2docker-cli/virtualbox"

	"github.com/boot2docker/boot2docker-cli/driver"
)

// Initialize the boot2docker VM from scratch.
func cmdInit() int {
	B2D.Init = true
	_, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to initialize machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Bring up the VM from all possible states.
func cmdUp() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Start(); err != nil {
		logf("Failed to start machine %q: %s", B2D.VM, err)
		return 1
	}

	if err := m.Refresh(); err != nil {
		logf("Failed to start machine %q: %s", B2D.VM, err)
		return 1
	}
	if m.GetState() != driver.Running {
		logf("Failed to start machine %q (run again with -v for details)", B2D.VM)
		return 1
	}

	logf("Waiting for VM to be started...")
	//give the VM a little time to start, so we don't kill the Serial Pipe/Socket
	time.Sleep(600 * time.Millisecond)
	natSSH := fmt.Sprintf("localhost:%d", m.GetSSHPort())
	IP := ""
	for i := 1; i < 30; i++ {
		if B2D.Serial && runtime.GOOS != "windows" {
			if IP = RequestIPFromSerialPort(m.GetSerialFile()); IP != "" {
				break
			}
		}
		if err := read(natSSH, 1, 2*time.Second); err == nil {
			IP = RequestIPFromSSH(m)
			break
		}

		print(".")
	}
	print("\n")

	logf("Started.")

	if IP == "" {
		// lets try one more time
		time.Sleep(600 * time.Millisecond)
		logf("  Trying to get IP one more time")

		IP = RequestIPFromSSH(m)
	}
	switch runtime.GOOS {
	case "windows":
		logf("Docker client does not run on Windows for now. Please use")
		logf("    \"%s\" ssh", os.Args[0])
		logf("to SSH into the VM instead.")
	default:
		if IP == "" {
			logf("Auto detection of the VM's IP address failed.")
			logf("Please run `boot2docker -v up` to diagnose.")
		} else {
			// Check if $DOCKER_HOST ENV var is properly configured.
			if os.Getenv("DOCKER_HOST") != fmt.Sprintf("tcp://%s:%d", IP, driver.DockerPort) {
				logf("To connect the Docker client to the Docker daemon, please set:")
				logf("    export DOCKER_HOST=tcp://%s:%d", IP, driver.DockerPort)
			} else {
				logf("Your DOCKER_HOST env variable is already set correctly.")
			}
		}
	}
	return 0
}

// Tell the user the config (and later let them set it?)
func cmdConfig() int {
	dir, err := getCfgDir(".boot2docker")
	if err != nil {
		logf("Error working out Profile file location: %s", err)
		return 1
	}
	filename := getCfgFilename(dir)
	logf("boot2docker profile filename: %s", filename)
	fmt.Println(printConfig())
	return 0
}

// Suspend and save the current state of VM on disk.
func cmdSave() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Save(); err != nil {
		logf("Failed to save machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Gracefully stop the VM by sending ACPI shutdown signal.
func cmdStop() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Stop(); err != nil {
		logf("Failed to stop machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Forcefully power off the VM (equivalent to unplug power). Might corrupt disk
// image.
func cmdPoweroff() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Poweroff(); err != nil {
		logf("Failed to poweroff machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Upgrade the boot2docker iso - preserving server state
func cmdUpgrade() int {
	m, err := vbx.GetMachine(B2D.VM)
	if err == nil && m.State == vbx.Running {
		if cmdDownload() == 0 && cmdStop() == 0 {
			return cmdUp()
		} else {
			return 0
		}
	} else {
		return cmdDownload()
	}
}

// Gracefully stop and then start the VM.
func cmdRestart() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Restart(); err != nil {
		logf("Failed to restart machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Forcefully reset (equivalent to cold boot) the VM. Might corrupt disk image.
func cmdReset() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Reset(); err != nil {
		logf("Failed to reset machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Delete the VM and associated disk image.
func cmdDelete() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		if err == driver.ErrMachineNotExist {
			logf("Machine %q does not exist.", B2D.VM)
			return 0
		}
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Delete(); err != nil {
		logf("Failed to delete machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Show detailed info of the VM.
func cmdInfo() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := json.NewEncoder(os.Stdout).Encode(m); err != nil {
		logf("Failed to encode machine %q info: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Show the current state of the VM.
func cmdStatus() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	fmt.Println(m.GetState())
	return 0
}

// Call the external SSH command to login into boot2docker VM.
func cmdSSH() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}

	if m.GetState() != driver.Running {
		logf("VM %q is not running.", B2D.VM)
		return 1
	}

	// find the ssh cmd string and then pass any remaining strings to ssh
	// TODO: it's a shame to repeat the same code as in config.go, but I
	//       didn't find a way to share the unsharable without more rework
	i := 1
	for i < len(os.Args) && os.Args[i-1] != "ssh" {
		i++
	}

	sshArgs := append([]string{
		"-o", "StrictHostKeyChecking=no",
		"-o", "UserKnownHostsFile=/dev/null",
		"-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts."
		"-p", fmt.Sprintf("%d", m.GetSSHPort()),
		"-i", B2D.SSHKey,
		"docker@localhost",
	}, os.Args[i:]...)

	if err := cmdInteractive(B2D.SSH, sshArgs...); err != nil {
		logf("%s", err)
		return 1
	}
	return 0
}

func cmdIP() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}

	if m.GetState() != driver.Running {
		logf("VM %q is not running.", B2D.VM)
		return 1
	}

	IP := ""
	if B2D.Serial {
		for i := 1; i < 20; i++ {
			if runtime.GOOS != "windows" {
				if IP = RequestIPFromSerialPort(m.GetSerialFile()); IP != "" {
					break
				}
			}
		}
	}

	if IP == "" {
		IP = RequestIPFromSSH(m)
	}
	if IP != "" {
		errf("\nThe VM's Host only interface IP address is: ")
		fmt.Printf("%s", IP)
		errf("\n\n")
	} else {
		errf("\nFailed to get VM Host only IP address.\n")
		errf("\tWas the VM initilized using boot2docker?\n")
	}
	return 0
}

func RequestIPFromSSH(m driver.Machine) string {
	// fall back to using the NAT port forwarded ssh
	out, err := cmd(B2D.SSH,
		"-v", // please leave in - this seems to improve the chance of success
		"-o", "StrictHostKeyChecking=no",
		"-o", "UserKnownHostsFile=/dev/null",
		"-p", fmt.Sprintf("%d", m.GetSSHPort()),
		"-i", B2D.SSHKey,
		"docker@localhost",
		"ip addr show dev eth1",
	)
	IP := ""
	if err != nil {
		logf("%s", err)
	} else {
		if B2D.Verbose {
			logf("SSH returned: %s\nEND SSH\n", out)
		}
		// parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1
		lines := strings.Split(out, "\n")
		for _, line := range lines {
			vals := strings.Split(strings.TrimSpace(line), " ")
			if len(vals) >= 2 && vals[0] == "inet" {
				IP = vals[1][:strings.Index(vals[1], "/")]
				break
			}
		}
	}
	return IP
}

// Download the boot2docker ISO image.
func cmdDownload() int {
	logf("Downloading boot2docker ISO image...")
	url := "https://api.github.com/repos/boot2docker/boot2docker/releases"
	tag, err := getLatestReleaseName(url)
	if err != nil {
		logf("Failed to get latest release: %s", err)
		return 1
	}
	logf("Latest release is %s", tag)

	url = fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag)
	if err := download(B2D.ISO, url); err != nil {
		logf("Failed to download ISO image: %s", err)
		return 1
	}
	logf("Success: downloaded %s\n\tto %s", url, B2D.ISO)
	return 0
}
<commit_msg>Sorry, I didn't test the effects of merging 2 PRs<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"

	_ "github.com/boot2docker/boot2docker-cli/dummy"
	_ "github.com/boot2docker/boot2docker-cli/virtualbox"

	"github.com/boot2docker/boot2docker-cli/driver"
)

// Initialize the boot2docker VM from scratch.
func cmdInit() int {
	B2D.Init = true
	_, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to initialize machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Bring up the VM from all possible states.
func cmdUp() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Start(); err != nil {
		logf("Failed to start machine %q: %s", B2D.VM, err)
		return 1
	}

	if err := m.Refresh(); err != nil {
		logf("Failed to start machine %q: %s", B2D.VM, err)
		return 1
	}
	if m.GetState() != driver.Running {
		logf("Failed to start machine %q (run again with -v for details)", B2D.VM)
		return 1
	}

	logf("Waiting for VM to be started...")
	//give the VM a little time to start, so we don't kill the Serial Pipe/Socket
	time.Sleep(600 * time.Millisecond)
	natSSH := fmt.Sprintf("localhost:%d", m.GetSSHPort())
	IP := ""
	for i := 1; i < 30; i++ {
		if B2D.Serial && runtime.GOOS != "windows" {
			if IP = RequestIPFromSerialPort(m.GetSerialFile()); IP != "" {
				break
			}
		}
		if err := read(natSSH, 1, 2*time.Second); err == nil {
			IP = RequestIPFromSSH(m)
			break
		}

		print(".")
	}
	print("\n")

	logf("Started.")

	if IP == "" {
		// lets try one more time
		time.Sleep(600 * time.Millisecond)
		logf("  Trying to get IP one more time")

		IP = RequestIPFromSSH(m)
	}
	switch runtime.GOOS {
	case "windows":
		logf("Docker client does not run on Windows for now. Please use")
		logf("    \"%s\" ssh", os.Args[0])
		logf("to SSH into the VM instead.")
	default:
		if IP == "" {
			logf("Auto detection of the VM's IP address failed.")
			logf("Please run `boot2docker -v up` to diagnose.")
		} else {
			// Check if $DOCKER_HOST ENV var is properly configured.
			if os.Getenv("DOCKER_HOST") != fmt.Sprintf("tcp://%s:%d", IP, driver.DockerPort) {
				logf("To connect the Docker client to the Docker daemon, please set:")
				logf("    export DOCKER_HOST=tcp://%s:%d", IP, driver.DockerPort)
			} else {
				logf("Your DOCKER_HOST env variable is already set correctly.")
			}
		}
	}
	return 0
}

// Tell the user the config (and later let them set it?)
func cmdConfig() int {
	dir, err := getCfgDir(".boot2docker")
	if err != nil {
		logf("Error working out Profile file location: %s", err)
		return 1
	}
	filename := getCfgFilename(dir)
	logf("boot2docker profile filename: %s", filename)
	fmt.Println(printConfig())
	return 0
}

// Suspend and save the current state of VM on disk.
func cmdSave() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Save(); err != nil {
		logf("Failed to save machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Gracefully stop the VM by sending ACPI shutdown signal.
func cmdStop() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Stop(); err != nil {
		logf("Failed to stop machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Forcefully power off the VM (equivalent to unplug power). Might corrupt disk
// image.
func cmdPoweroff() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Poweroff(); err != nil {
		logf("Failed to poweroff machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Upgrade the boot2docker iso - preserving server state
func cmdUpgrade() int {
	m, err := driver.GetMachine(&B2D)
	if err == nil && m.GetState() == driver.Running {
		if cmdDownload() == 0 && cmdStop() == 0 {
			return cmdUp()
		} else {
			return 0
		}
	} else {
		return cmdDownload()
	}
}

// Gracefully stop and then start the VM.
func cmdRestart() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Restart(); err != nil {
		logf("Failed to restart machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Forcefully reset (equivalent to cold boot) the VM. Might corrupt disk image.
func cmdReset() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Reset(); err != nil {
		logf("Failed to reset machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Delete the VM and associated disk image.
func cmdDelete() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		if err == driver.ErrMachineNotExist {
			logf("Machine %q does not exist.", B2D.VM)
			return 0
		}
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := m.Delete(); err != nil {
		logf("Failed to delete machine %q: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Show detailed info of the VM.
func cmdInfo() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	if err := json.NewEncoder(os.Stdout).Encode(m); err != nil {
		logf("Failed to encode machine %q info: %s", B2D.VM, err)
		return 1
	}
	return 0
}

// Show the current state of the VM.
func cmdStatus() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}
	fmt.Println(m.GetState())
	return 0
}

// Call the external SSH command to login into boot2docker VM.
func cmdSSH() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}

	if m.GetState() != driver.Running {
		logf("VM %q is not running.", B2D.VM)
		return 1
	}

	// find the ssh cmd string and then pass any remaining strings to ssh
	// TODO: it's a shame to repeat the same code as in config.go, but I
	//       didn't find a way to share the unsharable without more rework
	i := 1
	for i < len(os.Args) && os.Args[i-1] != "ssh" {
		i++
	}

	sshArgs := append([]string{
		"-o", "StrictHostKeyChecking=no",
		"-o", "UserKnownHostsFile=/dev/null",
		"-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts."
		"-p", fmt.Sprintf("%d", m.GetSSHPort()),
		"-i", B2D.SSHKey,
		"docker@localhost",
	}, os.Args[i:]...)

	if err := cmdInteractive(B2D.SSH, sshArgs...); err != nil {
		logf("%s", err)
		return 1
	}
	return 0
}

func cmdIP() int {
	m, err := driver.GetMachine(&B2D)
	if err != nil {
		logf("Failed to get machine %q: %s", B2D.VM, err)
		return 2
	}

	if m.GetState() != driver.Running {
		logf("VM %q is not running.", B2D.VM)
		return 1
	}

	IP := ""
	if B2D.Serial {
		for i := 1; i < 20; i++ {
			if runtime.GOOS != "windows" {
				if IP = RequestIPFromSerialPort(m.GetSerialFile()); IP != "" {
					break
				}
			}
		}
	}

	if IP == "" {
		IP = RequestIPFromSSH(m)
	}
	if IP != "" {
		errf("\nThe VM's Host only interface IP address is: ")
		fmt.Printf("%s", IP)
		errf("\n\n")
	} else {
		errf("\nFailed to get VM Host only IP address.\n")
		errf("\tWas the VM initilized using boot2docker?\n")
	}
	return 0
}

func RequestIPFromSSH(m driver.Machine) string {
	// fall back to using the NAT port forwarded ssh
	out, err := cmd(B2D.SSH,
		"-v", // please leave in - this seems to improve the chance of success
		"-o", "StrictHostKeyChecking=no",
		"-o", "UserKnownHostsFile=/dev/null",
		"-p", fmt.Sprintf("%d", m.GetSSHPort()),
		"-i", B2D.SSHKey,
		"docker@localhost",
		"ip addr show dev eth1",
	)
	IP := ""
	if err != nil {
		logf("%s", err)
	} else {
		if B2D.Verbose {
			logf("SSH returned: %s\nEND SSH\n", out)
		}
		// parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1
		lines := strings.Split(out, "\n")
		for _, line := range lines {
			vals := strings.Split(strings.TrimSpace(line), " ")
			if len(vals) >= 2 && vals[0] == "inet" {
				IP = vals[1][:strings.Index(vals[1], "/")]
				break
			}
		}
	}
	return IP
}

// Download the boot2docker ISO image.
func cmdDownload() int {
	logf("Downloading boot2docker ISO image...")
	url := "https://api.github.com/repos/boot2docker/boot2docker/releases"
	tag, err := getLatestReleaseName(url)
	if err != nil {
		logf("Failed to get latest release: %s", err)
		return 1
	}
	logf("Latest release is %s", tag)

	url = fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag)
	if err := download(B2D.ISO, url); err != nil {
		logf("Failed to download ISO image: %s", err)
		return 1
	}
	logf("Success: downloaded %s\n\tto %s", url, B2D.ISO)
	return 0
}
<|endoftext|>


<commit_before>package golang

import (
	"github.com/h2oai/steam/tools/piping/parser"
	"github.com/serenize/snaker"
	"strings"
)

func genParam(p *parser.Param) string {
	return p.Name + " " + p.Type
}

func genMember(p *parser.Param) string {
	return p.Name + " " + p.Type + " `json:\"" + snaker.CamelToSnake(p.Name) + "\"`"
}

func genStruct(s *parser.Struct) string {
	c := "type " + s.Name + " struct {\n"
	for _, p := range s.Params {
		c += "\t" + genMember(p) + "\n"
	}
	return c + "}\n\n"
}

func genFunc(f *parser.Func) string {
	c := "\t" + f.Name + "(principal sec.Principal,"
	l := len(f.Params) - 1
	for i, p := range f.Params {
		c += genParam(p)
		if i < l {
			c += ", "
		}
	}
	c += ") "
	if f.Return != nil {
		c += "(" + f.Return.Type + ", error)\n"
	} else {
		c += "error\n"
	}
	return c
}
func capitalize(s string) string {
	switch len(s) {
	case 0:
		return ""
	case 1:
		return strings.ToUpper(s)
	default:
		return strings.ToUpper(string(s[0])) + s[1:]
	}
}

func genRequest(f *parser.Func) *parser.Struct {
	fs := make([]*parser.Param, len(f.Params))
	for i, p := range f.Params {
		fs[i] = &parser.Param{capitalize(p.Name), p.Type}
	}
	return &parser.Struct{capitalize(f.Name) + "In", fs}
}

func genResponse(f *parser.Func) *parser.Struct {
	var fs []*parser.Param
	if f.Return != nil {
		fs = []*parser.Param{&parser.Param{capitalize(f.Return.Name), f.Return.Type}}
	} else {
		fs = make([]*parser.Param, 0)
	}
	return &parser.Struct{capitalize(f.Name) + "Out", fs}
}

func genClientDefs() string {
	return `type Remote struct {
	Proc Proc
}

type Proc interface {
	Call(name string, in, out interface{}) error
}

`
}

func genServerDefs(i *parser.Interface) string {
	c := "type Impl struct {\n"
	c += "\tService " + i.Name + "\n\tAz az.Az\n}\n\n"
	return c
}

func genClientStub(f *parser.Func) string {
	c := "func (this *Remote) " + f.Name + "("
	args := make([]string, len(f.Params))
	for i, p := range f.Params {
		args[i] = genParam(p)
	}
	c += strings.Join(args, ", ") + ") ("
	if f.Return != nil {
		c += f.Return.Type + ", "
	}
	c += " error) {\n"
	c += "\tin := " + f.Name + "In{"
	params := make([]string, len(f.Params))
	for i, p := range f.Params {
		params[i] = p.Name
	}
	c += strings.Join(params, ", ") + "}\n"
	c += "\tvar out " + f.Name + "Out\n"
	c += "\terr := this.Proc.Call(\"" + f.Name + "\", &in, &out)\n"
	c += "\tif err != nil {\n"
	c += "\t\treturn "
	if f.Return != nil {
		c += defaultOf(f.Return.Type) + ", "
	}
	c += "err\n\t}\n"
	c += "\treturn "
	if f.Return != nil {
		c += "out." + capitalize(f.Return.Name) + ", "
	}
	c += "nil\n}\n\n"
	return c
}

func genServerStub(f *parser.Func) string {
	c := "func (this *Impl) " + f.Name + "(r *http.Request, in *" + f.Name + "In, out *" + f.Name + "Out) error {\n\t"

	c += `
	principal, azerr := this.Az.Identify(r)
	if azerr != nil {
		return azerr
	}
	`
	if f.Return != nil {
		c += "it, "
	}
	c += "err := this.Service." + f.Name + "(principal,"
	if len(f.Params) != 0 {
		params := make([]string, len(f.Params))
		for i, p := range f.Params {
			params[i] = "in." + capitalize(p.Name)
		}
		c += strings.Join(params, ", ")
	}
	c += ")\n\tif err != nil {\n\t\treturn err\n\t}\n"
	if f.Return != nil {
		c += "\tout." + capitalize(f.Return.Name) + " = it\n"
	}
	c += "\treturn nil\n}\n\n"

	return c
}

func defaultOf(t string) string {
	switch t {
	case "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64", "int", "uint":
		return "0"
	case "string":
		return "\"\""
	case "bool":
		return "false"
	default:
		return "nil"
	}
}

func Generate(i *parser.Interface) string {
	c := "// ----------------------------------\n"
	c += "// --- Generated with go:generate ---\n"
	c += "// ---        DO NOT EDIT         ---\n"
	c += "// ----------------------------------\n\n"
	c += "package " + i.Package + "\n\n"

	if len(i.Imports) > 0 {
		c += "import(\n"
		for _, a := range i.Imports {
			c += "\t\"" + a + "\"\n"
		}
		c += ")\n\n"
	}

	if len(i.Aliases) > 0 {
		c += "// --- Aliases ---\n\n"
		for _, a := range i.Aliases {
			c += "type " + a.Name + " " + a.Type + "\n"
		}

		c += "\n"
	}

	if len(i.Consts) > 0 {
		c += "// --- Consts ---\n\n"
		for _, a := range i.Consts {
			c += "const (\n"
			for i, l := range a.Values {
				c += "\t" + a.Prefix + l
				if i == 0 {
					c += " " + a.Type
				}
				c += " = \"" + l + "\"\n"
			}
			c += ")\n\n"
		}
	}

	if len(i.Structs) > 0 {
		c += "// --- Types ---\n\n"
		for _, s := range i.Structs {
			c += genStruct(s)
		}
	}

	if len(i.Funcs) > 0 {
		c += "// --- Interfaces ---\n\n"

		c += `
		type Az interface {
			Identify(r *http.Request) (sec.Principal, error)
		}

		`

		c += "type " + i.Name + " interface {\n"
		for _, f := range i.Funcs {
			c += genFunc(f)
		}
		c += "}\n\n"

		c += "// --- Messages ---\n\n"

		for _, f := range i.Funcs {
			c += genStruct(genRequest(f))
			c += genStruct(genResponse(f))
		}

		c += "// --- Client Stub ---\n\n"

		c += genClientDefs()
		for _, f := range i.Funcs {
			c += genClientStub(f)
		}

		c += "// --- Server Stub ---\n\n"

		c += genServerDefs(i)
		for _, f := range i.Funcs {
			c += genServerStub(f)
		}
	}

	return c
}
<commit_msg>STEAM-138 Remove stale dep<commit_after><|endoftext|>


<commit_before>package oneandone_cloudserver_api

import (
	log "github.com/Sirupsen/logrus"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string `json:"ip"`
	ReverseDns string `json:"reverse_dns"`
	FirewallId string `json:"firewall"`
}

type ServerCreateData struct {
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	Hardware           Hardware `json:"hardware"`
	ApplianceId        string   `json:"appliance_id"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

// GET /servers
func (api *API) GetServers() []Server {
	log.Debug("requesting information about servers")
	session := api.prepareSession()
	res := []Server{}
	resp, _ := session.Get(createUrl(api, "servers"), nil, &res, nil)
	logResult(resp, 200)
	for index, _ := range res {
		res[index].api = api
	}
	return res
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) Server {
	log.Debug("requesting to create a new server")
	s := api.prepareSession()
	res := Server{}
	resp, _ := s.Post(createUrl(api, "servers"), configuration, &res, nil)
	logResult(resp, 201)
	res.api = api
	return res
}

// GET /servers/{id}
func (api *API) GetServer(Id string) Server {
	log.Debug("requesting to about server ", Id)
	session := api.prepareSession()
	res := Server{}
	resp, _ := session.Get(createUrl(api, "servers", Id), nil, &res, nil)
	logResult(resp, 200)
	res.api = api
	return res
}

// DELETE /servers/{id}
func (server *Server) Delete() Server {
	log.Debug("Requested to delete VM ", server.Id)
	session := server.api.prepareSession()
	res := Server{}
	resp, _ := session.Delete(createUrl(server.api, "servers", server.Id), &res, nil)
	logResult(resp, 200)
	res.api = server.api
	return res
}

// PUT /servers/{id}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status

// PUT /servers/{id}/status

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}
<commit_msg>Change methods to use error handling<commit_after>package oneandone_cloudserver_api

import (
	//"fmt"
	log "github.com/Sirupsen/logrus"
	//"github.com/jmcvetta/napping"
	"net/http"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string `json:"ip"`
	ReverseDns string `json:"reverse_dns"`
	FirewallId string `json:"firewall"`
}

type ServerCreateData struct {
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	Hardware           Hardware `json:"hardware"`
	ApplianceId        string   `json:"appliance_id"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

// GET /servers
func (api *API) GetServers() ([]Server, error) {
	log.Debug("requesting information about servers")
	session := api.prepareSession()
	result := []Server{}
	response, err := session.Get(createUrl(api, "servers"), nil, &result, nil)
	if err := isError(response, http.StatusOK, err); err != nil {
		return nil, err
	} else {
		for index, _ := range result {
			result[index].api = api
		}
		return result, nil
	}
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) (*Server, error) {
	log.Debug("requesting to create a new server")
	s := api.prepareSession()
	result := new(Server)
	response, err := s.Post(createUrl(api, "servers"), configuration, &result, nil)
	if err := isError(response, http.StatusOK, err); err != nil {
		return nil, err
	} else {
		result.api = api
		return result, nil
	}
}

// GET /servers/{id}
func (api *API) GetServer(Id string) (*Server, error) {
	log.Debug("requesting to about server ", Id)
	session := api.prepareSession()
	result := new(Server)
	response, err := session.Get(createUrl(api, "servers", Id), nil, &result, nil)
	if err := isError(response, http.StatusOK, err); err != nil {
		return nil, err
	} else {
		result.api = api
		return result, nil
	}
}

// DELETE /servers/{id}
func (server *Server) Delete() (*Server, error) {
	log.Debug("Requested to delete VM ", server.Id)
	session := server.api.prepareSession()
	result := new(Server)
	response, err := session.Delete(createUrl(server.api, "servers", server.Id), &result, nil)
	if err := isError(response, http.StatusOK, err); err != nil {
		return nil, err
	} else {
		result.api = server.api
		return result, nil
	}
}

// PUT /servers/{id}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status

// PUT /servers/{id}/status

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 1&1 Internet AG, http://1und1.de . All rights reserved. Licensed under the Apache v2 License.
 */

package oneandone_cloudserver_api

import (
	"github.com/docker/machine/log"
	"net/http"
	"time"
	"net"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	Ips      []IpInServer  `json:"ips"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string               `json:"ip"`
	ReverseDns string               `json:"reverse_dns"`
	Firewall   FirewallInIpInServer `json:"firewall_policy"`
}

type FirewallInIpInServer struct {
	withId
	withName
}

type ServerCreateData struct {
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	Hardware           Hardware `json:"hardware"`
	ApplianceId        string   `json:"appliance_id"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

type ServerAction struct {
	Action string `json:"action"`
	Method string `json:"method"`
}

type FixedInstanceInformation struct {
	withName
	withId
	Hardware Hardware `json:"hardware"`
	withApi
}

type ServerRenameData struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

// GET /servers
func (api *API) GetServers() ([]Server, error) {
	log.Debug("requesting information about servers")
	result := []Server{}
	err := api.Client.Get(createUrl(api, "servers"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	for index, _ := range result {
		result[index].api = api
	}
	return result, nil
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) (*Server, error) {
	log.Debug("requesting to create a new server")
	result := new(Server)
	err := api.Client.Post(createUrl(api, "servers"), &configuration, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = api
	return result, nil
}

// GET /servers/{id}
func (api *API) GetServer(Id string) (*Server, error) {
	log.Debug("requesting information about server ", Id)
	result := new(Server)
	err := api.Client.Get(createUrl(api, "servers", Id), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	result.api = api
	return result, nil
}

func (api *API) GetFixedInstanceSizes() ([]FixedInstanceInformation, error) {
	log.Debug("requesting information about fixed instance sizes")
	result := []FixedInstanceInformation{}
	err := api.Client.Get(createUrl(api, "servers", "fixed_instance_sizes"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	for index, _ := range result {
		result[index].api = api
	}
	return result, nil
}

// DELETE /servers/{id}
func (s *Server) Delete() (*Server, error) {
	log.Debugf("Requested to delete server '%v' ", s.Id)
	result := new(Server)
	err := s.api.Client.Delete(createUrl(s.api, "servers", s.Id), &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// PUT /servers/{id}
func (s *Server) RenameServer(data ServerRenameData) (*Server, error) {
	log.Debugf("Requested to rename server '%v'", s.Id)
	result := new(Server)
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id), data, &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status
func (s *Server) GetStatus() (*Status, error) {
	log.Debugf("Requesting server status for server: '%s'", s.Id)
	result := new(Status)
	err := s.api.Client.Get(createUrl(s.api, "servers", s.Id, "status"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// PUT /servers/{id}/status/action
func (s *Server) Reboot(hardware bool) (*Server, error) {
	log.Debugf("Requested to reboot Server '%v'. Hardware: '%t'", s.Id, hardware)
	result := new(Server)
	request := ServerAction{}
	request.Action = "REBOOT"
	if hardware {
		request.Method = "HARDWARE"
	} else {
		request.Method = "SOFTWARE"
	}
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

func (s *Server) Shutdown(hardware bool) (*Server, error) {
	log.Debugf("Requested to shutdown Server '%v'. Hardware: '%t'", s.Id, hardware)
	result := new(Server)
	request := ServerAction{}
	request.Action = "POWER_OFF"
	if hardware {
		request.Method = "HARDWARE"
	} else {
		request.Method = "SOFTWARE"
	}
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

func (s *Server) Start() (*Server, error) {
	log.Debugf("Requested to start Server '%v'.", s.Id)
	result := new(Server)
	request := ServerAction{}
	request.Action = "POWER_ON"
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}

func (server *Server) exists() (bool, error) {
	_, err := server.api.GetServer(server.Id)
	if err == nil {
		return true, nil
	} else {
		if apiError, ok := err.(ApiError); ok && apiError.httpStatusCode == http.StatusNotFound {
			return false, nil
		} else {
			return false, err
		}
	}
}

func (server *Server) WaitUntilDeleted() error {
	exists := true
	var err error
	for exists {
		exists, err = server.exists()
		if err != nil {
			return err
		}
		log.Debugf("Wait for server: '%s' to be deleted", server.Id)
		time.Sleep(5 * time.Second)
	}
	log.Debugf("The server: '%s' is now deleted", server.Id)
	return nil
}

// Function to perform busy-wating for a certain server state.
//
// This function queries the server with the given id every 5s until the server's state equals the given state.
func (server *Server) WaitForState(State string) error {
	server, err := server.api.GetServer(server.Id)
	if err != nil {
		return err
	}
	status := server.Status
	log.Debugf("Wait for expected status: '%s' current: '%s' %d%%", State, status.State, status.Percent)
	for status.State != State {
		time.Sleep(5 * time.Second)
		status, err := server.GetStatus()
		if err != nil {
			return err
		}
		if status.State == State {
			log.Debugf("The server is now in the expected state: '%s'", State)
			return nil
		} else {
			log.Debugf("Wait for expected status: '%s' current: '%s' %d%%", State, status.State, status.Percent)
		}
	}
	return nil
}

// Function to check if ssh ready
//
// This function check if the ssh service is ready. Is it not it will loop in an 5 second tact and recheck it.
func (server *Server) WaitForSSH(port int) {
	log.Infof("Waiting for SSH to get ready ...")

	_, err := net.DialTimeout("tcp", server.Ips[0].Ip + ":" + string(port), 5 * time.Second)
	for err != nil {
		log.Debug("Waiting for SSH to get ready. Retry in 5 sec...")
		time.Sleep(5 * time.Second)
		_, err = net.DialTimeout("tcp", server.Ips[0].Ip+":22", 5 * time.Second)
	}
}
<commit_msg>Remove WaitForSSHReady function<commit_after>/*
 * Copyright 2015 1&1 Internet AG, http://1und1.de . All rights reserved. Licensed under the Apache v2 License.
 */

package oneandone_cloudserver_api

import (
	"github.com/docker/machine/log"
	"net/http"
	"time"
	"net"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	Ips      []IpInServer  `json:"ips"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string               `json:"ip"`
	ReverseDns string               `json:"reverse_dns"`
	Firewall   FirewallInIpInServer `json:"firewall_policy"`
}

type FirewallInIpInServer struct {
	withId
	withName
}

type ServerCreateData struct {
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	Hardware           Hardware `json:"hardware"`
	ApplianceId        string   `json:"appliance_id"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

type ServerAction struct {
	Action string `json:"action"`
	Method string `json:"method"`
}

type FixedInstanceInformation struct {
	withName
	withId
	Hardware Hardware `json:"hardware"`
	withApi
}

type ServerRenameData struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

// GET /servers
func (api *API) GetServers() ([]Server, error) {
	log.Debug("requesting information about servers")
	result := []Server{}
	err := api.Client.Get(createUrl(api, "servers"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	for index, _ := range result {
		result[index].api = api
	}
	return result, nil
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) (*Server, error) {
	log.Debug("requesting to create a new server")
	result := new(Server)
	err := api.Client.Post(createUrl(api, "servers"), &configuration, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = api
	return result, nil
}

// GET /servers/{id}
func (api *API) GetServer(Id string) (*Server, error) {
	log.Debug("requesting information about server ", Id)
	result := new(Server)
	err := api.Client.Get(createUrl(api, "servers", Id), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	result.api = api
	return result, nil
}

func (api *API) GetFixedInstanceSizes() ([]FixedInstanceInformation, error) {
	log.Debug("requesting information about fixed instance sizes")
	result := []FixedInstanceInformation{}
	err := api.Client.Get(createUrl(api, "servers", "fixed_instance_sizes"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	for index, _ := range result {
		result[index].api = api
	}
	return result, nil
}

// DELETE /servers/{id}
func (s *Server) Delete() (*Server, error) {
	log.Debugf("Requested to delete server '%v' ", s.Id)
	result := new(Server)
	err := s.api.Client.Delete(createUrl(s.api, "servers", s.Id), &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// PUT /servers/{id}
func (s *Server) RenameServer(data ServerRenameData) (*Server, error) {
	log.Debugf("Requested to rename server '%v'", s.Id)
	result := new(Server)
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id), data, &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status
func (s *Server) GetStatus() (*Status, error) {
	log.Debugf("Requesting server status for server: '%s'", s.Id)
	result := new(Status)
	err := s.api.Client.Get(createUrl(s.api, "servers", s.Id, "status"), &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// PUT /servers/{id}/status/action
func (s *Server) Reboot(hardware bool) (*Server, error) {
	log.Debugf("Requested to reboot Server '%v'. Hardware: '%t'", s.Id, hardware)
	result := new(Server)
	request := ServerAction{}
	request.Action = "REBOOT"
	if hardware {
		request.Method = "HARDWARE"
	} else {
		request.Method = "SOFTWARE"
	}
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

func (s *Server) Shutdown(hardware bool) (*Server, error) {
	log.Debugf("Requested to shutdown Server '%v'. Hardware: '%t'", s.Id, hardware)
	result := new(Server)
	request := ServerAction{}
	request.Action = "POWER_OFF"
	if hardware {
		request.Method = "HARDWARE"
	} else {
		request.Method = "SOFTWARE"
	}
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

func (s *Server) Start() (*Server, error) {
	log.Debugf("Requested to start Server '%v'.", s.Id)
	result := new(Server)
	request := ServerAction{}
	request.Action = "POWER_ON"
	err := s.api.Client.Put(createUrl(s.api, "servers", s.Id, "status", "action"), request, &result, http.StatusAccepted)
	if err != nil {
		return nil, err
	}
	result.api = s.api
	return result, nil
}

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}

func (server *Server) exists() (bool, error) {
	_, err := server.api.GetServer(server.Id)
	if err == nil {
		return true, nil
	} else {
		if apiError, ok := err.(ApiError); ok && apiError.httpStatusCode == http.StatusNotFound {
			return false, nil
		} else {
			return false, err
		}
	}
}

func (server *Server) WaitUntilDeleted() error {
	exists := true
	var err error
	for exists {
		exists, err = server.exists()
		if err != nil {
			return err
		}
		log.Debugf("Wait for server: '%s' to be deleted", server.Id)
		time.Sleep(5 * time.Second)
	}
	log.Debugf("The server: '%s' is now deleted", server.Id)
	return nil
}

// Function to perform busy-wating for a certain server state.
//
// This function queries the server with the given id every 5s until the server's state equals the given state.
func (server *Server) WaitForState(State string) error {
	server, err := server.api.GetServer(server.Id)
	if err != nil {
		return err
	}
	status := server.Status
	log.Debugf("Wait for expected status: '%s' current: '%s' %d%%", State, status.State, status.Percent)
	for status.State != State {
		time.Sleep(5 * time.Second)
		status, err := server.GetStatus()
		if err != nil {
			return err
		}
		if status.State == State {
			log.Debugf("The server is now in the expected state: '%s'", State)
			return nil
		} else {
			log.Debugf("Wait for expected status: '%s' current: '%s' %d%%", State, status.State, status.Percent)
		}
	}
	return nil
}<|endoftext|>


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

package http2amqp

import (
	"errors"
	"log"
	"time"

	"encoding/json"

	"github.com/aleasoluciones/goaleasoluciones/safemap"
	"github.com/aleasoluciones/simpleamqp"
)

const (
	AMQP_RECEIVE_TIMEOUT = 30 * time.Minute
	RESPONSES_QUEUE      = "queries_responses"
	RESPONSE_TOPIC       = "queries.response"
)

func NewHttp2AmqpService(brokerUri, exchange string, timeout time.Duration) *http2amqpService {

	service := http2amqpService{
		amqpConsumer:   simpleamqp.NewAmqpConsumer(brokerUri),
		amqpPublisher:  simpleamqp.NewAmqpPublisher(brokerUri, exchange),
		idsRepository:  NewIdsRepository(),
		exchange:       exchange,
		queryTimeout:   timeout,
		queryResponses: safemap.NewSafeMap(),
	}

	go service.receiveResponses(service.amqpConsumer.Receive(
		service.exchange,
		[]string{RESPONSE_TOPIC},
		RESPONSES_QUEUE,
		simpleamqp.QueueOptions{Durable: false, Delete: true, Exclusive: true},
		AMQP_RECEIVE_TIMEOUT))

	return &service
}

type http2amqpService struct {
	amqpConsumer   simpleamqp.AMQPConsumer
	amqpPublisher  simpleamqp.AMQPPublisher
	idsRepository  IdsRepository
	exchange       string
	queryTimeout   time.Duration
	queryResponses safemap.SafeMap
}

func (service *http2amqpService) receiveResponses(amqpResponses chan simpleamqp.AmqpMessage) {
	var deserialized AmqpResponseMessage
	var value safemap.Value
	var responses chan Response
	var found bool

	for message := range amqpResponses {
		_ = json.Unmarshal([]byte(message.Body), &deserialized)

		value, found = service.queryResponses.Find(deserialized.Id)
		if found {
			responses = value.(chan Response)
			responses <- deserialized.Response
		}
	}
}

func (service *http2amqpService) publishQuery(id string, topic string, request Request) {
	serialized, _ := json.Marshal(AmqpRequestMessage{
		Id:            id,
		Request:       request,
		ResponseTopic: RESPONSE_TOPIC,
	})
	log.Println("[queries_service] Query id:", id, "topic:", topic, "request:", request)
	service.amqpPublisher.Publish(topic, serialized)
}

func (service *http2amqpService) Query(topic string, request Request) (Response, error) {
	id := service.idsRepository.Next()
	responses := make(chan Response)
	service.queryResponses.Insert(id, responses)
	defer service.queryResponses.Delete(id)
	service.publishQuery(id, topic, request)

	timeoutTicker := time.NewTicker(service.queryTimeout)
	defer timeoutTicker.Stop()
	afterTimeout := timeoutTicker.C

	select {
	case response := <-responses:
		return response, nil
	case <-afterTimeout:
		log.Println("[queries_service] Timeout for query id:", id)
		return Response{}, errors.New("Timeout")
	}
}
<commit_msg>Implemented timeout parameter for each request<commit_after>// Copyright 2015 The http2amqp Authors. All rights reserved.  Use of this
// source code is governed by a MIT-style license that can be found in the
// LICENSE file.

package http2amqp

import (
	"errors"
	"log"
	"time"
	"strconv"

	"encoding/json"

	"github.com/aleasoluciones/goaleasoluciones/safemap"
	"github.com/aleasoluciones/simpleamqp"
)

const (
	AMQP_RECEIVE_TIMEOUT = 30 * time.Minute
	RESPONSES_QUEUE      = "queries_responses"
	RESPONSE_TOPIC       = "queries.response"
)

func NewHttp2AmqpService(brokerUri, exchange string, timeout time.Duration) *http2amqpService {

	service := http2amqpService{
		amqpConsumer:   simpleamqp.NewAmqpConsumer(brokerUri),
		amqpPublisher:  simpleamqp.NewAmqpPublisher(brokerUri, exchange),
		idsRepository:  NewIdsRepository(),
		exchange:       exchange,
		queryTimeout:   timeout,
		queryResponses: safemap.NewSafeMap(),
	}

	go service.receiveResponses(service.amqpConsumer.Receive(
		service.exchange,
		[]string{RESPONSE_TOPIC},
		RESPONSES_QUEUE,
		simpleamqp.QueueOptions{Durable: false, Delete: true, Exclusive: true},
		AMQP_RECEIVE_TIMEOUT))

	return &service
}

type http2amqpService struct {
	amqpConsumer   simpleamqp.AMQPConsumer
	amqpPublisher  simpleamqp.AMQPPublisher
	idsRepository  IdsRepository
	exchange       string
	queryTimeout   time.Duration
	queryResponses safemap.SafeMap
}

func (service *http2amqpService) receiveResponses(amqpResponses chan simpleamqp.AmqpMessage) {
	var deserialized AmqpResponseMessage
	var value safemap.Value
	var responses chan Response
	var found bool

	for message := range amqpResponses {
		_ = json.Unmarshal([]byte(message.Body), &deserialized)

		value, found = service.queryResponses.Find(deserialized.Id)
		if found {
			responses = value.(chan Response)
			responses <- deserialized.Response
		}
	}
}

func (service *http2amqpService) publishQuery(id string, topic string, request Request) {
	serialized, _ := json.Marshal(AmqpRequestMessage{
		Id:            id,
		Request:       request,
		ResponseTopic: RESPONSE_TOPIC,
	})
	log.Println("[queries_service] Query id:", id, "topic:", topic, "request:", request)
	service.amqpPublisher.Publish(topic, serialized)
}

func (service *http2amqpService) Query(topic string, request Request) (Response, error) {
	id := service.idsRepository.Next()
	responses := make(chan Response)
	service.queryResponses.Insert(id, responses)
	defer service.queryResponses.Delete(id)

	timeout := service.queryTimeout
	for k, v := range request.URL.Query() {
	    if k == "timeout" {
	       seconds, _ := strconv.Atoi(v[0])
	       timeout = time.Duration(seconds) * time.Second
	    }
	}
	service.publishQuery(id, topic, request)

	timeoutTicker := time.NewTicker(timeout)
	defer timeoutTicker.Stop()
	afterTimeout := timeoutTicker.C

	select {
	case response := <-responses:
		return response, nil
	case <-afterTimeout:
		log.Println("[queries_service] Timeout for query id:", id)
		return Response{}, errors.New("Timeout")
	}
}
<|endoftext|>


<commit_before>package enroll

import (
	"golang.org/x/net/context"
	"io/ioutil"
)

type Service interface {
	Enroll(ctx context.Context) (Profile, error)
}

func NewService(pushCertPath string, pushCertPass string, caCertPath string, scepURL string, scepChallenge string, url string, tlsCertPath string) (Service, error) {
	pushTopic, err := GetPushTopicFromPKCS12(pushCertPath, pushCertPass)
	if err != nil {
		return nil, err
	}

	var caCert, tlsCert []byte

	if caCertPath != "" {
		caCert, err = ioutil.ReadFile(caCertPath)

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

	if tlsCertPath != "" {
		tlsCert, err = ioutil.ReadFile(tlsCertPath)

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

	scepSubject := [][][]string{
		[][]string{
			[]string{"O", "MicroMDM"},
		},
		[][]string{
			[]string{"CN", "MDM Identity Certificate UDID"},
		},
	}

	return &service{
		URL:           url,
		SCEPURL:       scepURL,
		SCEPSubject:   scepSubject,
		SCEPChallenge: scepChallenge,
		Topic:         pushTopic,
		CACert:        caCert,
		TLSCert:       tlsCert,
	}, nil
}

type service struct {
	URL           string
	SCEPURL       string
	SCEPChallenge string
	SCEPSubject   [][][]string
	Topic         string // APNS Topic for MDM notifications
	CACert        []byte
	TLSCert       []byte
}

func (svc service) Enroll(ctx context.Context) (Profile, error) {
	profile := NewProfile()
	profile.PayloadIdentifier = "com.github.micromdm.micromdm.mdm"
	profile.PayloadOrganization = "MicroMDM"
	profile.PayloadDisplayName = "Enrollment Profile"
	profile.PayloadDescription = "The server may alter your settings"
	profile.PayloadScope = "System"

	mdmPayload := NewPayload("com.apple.mdm")
	mdmPayload.PayloadDescription = "Enrolls with the MDM server"
	mdmPayload.PayloadOrganization = "MicroMDM"
	mdmPayload.PayloadIdentifier = "com.github.micromdm.mdm"
	mdmPayload.PayloadScope = "System"

	mdmPayloadContent := MDMPayloadContent{
		Payload:             *mdmPayload,
		AccessRights:        8191,
		CheckInURL:          svc.URL + "/mdm/checkin",
		CheckOutWhenRemoved: true,
		ServerURL:           svc.URL + "/mdm/connect",
		Topic:               svc.Topic,
	}

	payloadContent := []interface{}{}

	if svc.SCEPURL != "" {
		scepContent := SCEPPayloadContent{
			URL:      svc.SCEPURL,
			Keysize:  1024,
			KeyType:  "RSA",
			KeyUsage: 0,
			Name:     "Device Management Identity Certificate",
			Subject:  svc.SCEPSubject,
		}

		if svc.SCEPChallenge != "" {
			scepContent.Challenge = svc.SCEPChallenge
		}

		scepPayload := NewPayload("com.apple.security.scep")
		scepPayload.PayloadDescription = "Configures SCEP"
		scepPayload.PayloadDisplayName = "SCEP"
		scepPayload.PayloadIdentifier = "com.github.micromdm.scep"
		scepPayload.PayloadOrganization = "MicroMDM"
		scepPayload.PayloadContent = scepContent
		scepPayload.PayloadScope = "System"

		payloadContent = append(payloadContent, *scepPayload)
		mdmPayloadContent.IdentityCertificateUUID = scepPayload.PayloadUUID
	}

	payloadContent = append(payloadContent, mdmPayloadContent)

	if len(svc.CACert) > 0 {
		caPayload := NewPayload("com.apple.security.root")
		caPayload.PayloadDisplayName = "Root certificate for MicroMDM"
		caPayload.PayloadDescription = "Installs the root CA certificate for MicroMDM"
		caPayload.PayloadIdentifier = "com.github.micromdm.ssl.ca"
		caPayload.PayloadContent = svc.CACert

		payloadContent = append(payloadContent, *caPayload)
	}

	// Client needs to trust us at this point if we are using a self signed certificate.
	if len(svc.TLSCert) > 0 {
		tlsPayload := NewPayload("com.apple.security.pkcs1")
		tlsPayload.PayloadDisplayName = "Self-signed TLS certificate for MicroMDM"
		tlsPayload.PayloadDescription = "Installs the TLS certificate for MicroMDM"
		tlsPayload.PayloadIdentifier = "com.github.micromdm.tls"
		tlsPayload.PayloadContent = svc.TLSCert

		payloadContent = append(payloadContent, *tlsPayload)
	}

	profile.PayloadContent = payloadContent

	return *profile, nil
}
<commit_msg>SCEP request subject is configurable and you can use it with templated SCEP variables like %SerialNumber% etc. (#45)<commit_after>package enroll

import (
	"golang.org/x/net/context"
	"io/ioutil"
	"strings"
)

type Service interface {
	Enroll(ctx context.Context) (Profile, error)
}

func NewService(pushCertPath, pushCertPass, caCertPath, scepURL, scepChallenge, url, tlsCertPath, scepSubject string) (Service, error) {
	pushTopic, err := GetPushTopicFromPKCS12(pushCertPath, pushCertPass)
	if err != nil {
		return nil, err
	}

	var caCert, tlsCert []byte

	if caCertPath != "" {
		caCert, err = ioutil.ReadFile(caCertPath)

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

	if tlsCertPath != "" {
		tlsCert, err = ioutil.ReadFile(tlsCertPath)

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

	if scepSubject == "" {
		scepSubject = "/O=MicroMDM/CN=MicroMDM Identity (%ComputerName%)"
	}

	subjectElements := strings.Split(scepSubject, "/")
	var subject [][][]string

	for _, element := range subjectElements {
		if element == "" {
			continue
		}
		subjectKeyValue := strings.Split(element, "=")
		subject = append(subject, [][]string{[]string{subjectKeyValue[0], subjectKeyValue[1]}})
	}

	return &service{
		URL:           url,
		SCEPURL:       scepURL,
		SCEPSubject:   subject,
		SCEPChallenge: scepChallenge,
		Topic:         pushTopic,
		CACert:        caCert,
		TLSCert:       tlsCert,
	}, nil
}

type service struct {
	URL           string
	SCEPURL       string
	SCEPChallenge string
	SCEPSubject   [][][]string
	Topic         string // APNS Topic for MDM notifications
	CACert        []byte
	TLSCert       []byte
}

func (svc service) Enroll(ctx context.Context) (Profile, error) {
	profile := NewProfile()
	profile.PayloadIdentifier = "com.github.micromdm.micromdm.mdm"
	profile.PayloadOrganization = "MicroMDM"
	profile.PayloadDisplayName = "Enrollment Profile"
	profile.PayloadDescription = "The server may alter your settings"
	profile.PayloadScope = "System"

	mdmPayload := NewPayload("com.apple.mdm")
	mdmPayload.PayloadDescription = "Enrolls with the MDM server"
	mdmPayload.PayloadOrganization = "MicroMDM"
	mdmPayload.PayloadIdentifier = "com.github.micromdm.mdm"
	mdmPayload.PayloadScope = "System"

	mdmPayloadContent := MDMPayloadContent{
		Payload:             *mdmPayload,
		AccessRights:        8191,
		CheckInURL:          svc.URL + "/mdm/checkin",
		CheckOutWhenRemoved: true,
		ServerURL:           svc.URL + "/mdm/connect",
		Topic:               svc.Topic,
	}

	payloadContent := []interface{}{}

	if svc.SCEPURL != "" {
		scepContent := SCEPPayloadContent{
			URL:      svc.SCEPURL,
			Keysize:  1024,
			KeyType:  "RSA",
			KeyUsage: 0,
			Name:     "Device Management Identity Certificate",
			Subject:  svc.SCEPSubject,
		}

		if svc.SCEPChallenge != "" {
			scepContent.Challenge = svc.SCEPChallenge
		}

		scepPayload := NewPayload("com.apple.security.scep")
		scepPayload.PayloadDescription = "Configures SCEP"
		scepPayload.PayloadDisplayName = "SCEP"
		scepPayload.PayloadIdentifier = "com.github.micromdm.scep"
		scepPayload.PayloadOrganization = "MicroMDM"
		scepPayload.PayloadContent = scepContent
		scepPayload.PayloadScope = "System"

		payloadContent = append(payloadContent, *scepPayload)
		mdmPayloadContent.IdentityCertificateUUID = scepPayload.PayloadUUID
	}

	payloadContent = append(payloadContent, mdmPayloadContent)

	if len(svc.CACert) > 0 {
		caPayload := NewPayload("com.apple.security.root")
		caPayload.PayloadDisplayName = "Root certificate for MicroMDM"
		caPayload.PayloadDescription = "Installs the root CA certificate for MicroMDM"
		caPayload.PayloadIdentifier = "com.github.micromdm.ssl.ca"
		caPayload.PayloadContent = svc.CACert

		payloadContent = append(payloadContent, *caPayload)
	}

	// Client needs to trust us at this point if we are using a self signed certificate.
	if len(svc.TLSCert) > 0 {
		tlsPayload := NewPayload("com.apple.security.pkcs1")
		tlsPayload.PayloadDisplayName = "Self-signed TLS certificate for MicroMDM"
		tlsPayload.PayloadDescription = "Installs the TLS certificate for MicroMDM"
		tlsPayload.PayloadIdentifier = "com.github.micromdm.tls"
		tlsPayload.PayloadContent = svc.TLSCert

		payloadContent = append(payloadContent, *tlsPayload)
	}

	profile.PayloadContent = payloadContent

	return *profile, nil
}
<|endoftext|>