<commit_before>package kloud

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"koding/kites/kloud/contexthelper/session"
	"koding/kites/kloud/terraformer"
	tf "koding/kites/terraformer"

	"labix.org/v2/mgo/bson"

	"golang.org/x/net/context"

	"github.com/koding/kite"
	"github.com/mitchellh/mapstructure"
)

type AwsBootstrapOutput struct {
	ACL       string `json:"acl" mapstructure:"acl"`
	CidrBlock string `json:"cidr_block" mapstructure:"cidr_block"`
	IGW       string `json:"igw" mapstructure:"igw"`
	KeyPair   string `json:"key_pair" mapstructure:"key_pair"`
	RTB       string `json:"rtb" mapstructure:"rtb"`
	SG        string `json:"sg" mapstructure:"sg"`
	Subnet    string `json:"subnet" mapstructure:"subnet"`
	VPC       string `json:"vpc" mapstructure:"vpc"`
}

type TerraformBootstrapRequest struct {
	// PublicKeys contains publicKeys to be used with terraform
	PublicKeys []string `json:"publicKeys"`

	// Destroy destroys the bootstrap resource associated with the given public
	// keys
	Destroy bool
}

func (k *Kloud) Bootstrap(r *kite.Request) (interface{}, error) {
	if r.Args == nil {
		return nil, NewError(ErrNoArguments)
	}

	var args *TerraformBootstrapRequest
	if err := r.Args.One().Unmarshal(&args); err != nil {
		return nil, err
	}

	if len(args.PublicKeys) == 0 {
		return nil, errors.New("publicKeys are not passed")
	}

	ctx := k.ContextCreator(context.Background())
	sess, ok := session.FromContext(ctx)
	if !ok {
		return nil, errors.New("session context is not passed")
	}

	creds, err := fetchCredentials(r.Username, sess.DB, args.PublicKeys)
	if err != nil {
		return nil, err
	}

	tfKite, err := terraformer.Connect(sess.Kite)
	if err != nil {
		return nil, err
	}
	defer tfKite.Close()

	for _, cred := range creds.Creds {
		// We are going to support more providers in the future, for now only allow aws
		if cred.Provider != "aws" {
			return nil, fmt.Errorf("Bootstrap is only supported for 'aws' provider. Got: '%s'", cred.Provider)
		}

		finalBootstrap, err := cred.appendAWSVariable(fmt.Sprintf(awsBootstrap, k.PublicKeys.PublicKey))
		if err != nil {
			return nil, err
		}

		keyName := "kloud-deployment-" + r.Username
		finalBootstrap, err = appendKeyName(finalBootstrap, keyName)
		if err != nil {
			return nil, err
		}

		k.Log.Debug("[%s] Final bootstrap:", cred.PublicKey)
		k.Log.Debug(finalBootstrap)

		// Important so bootstraping is distributed amongs multiple users. If I
		// use these keys to bootstrap, any other user should be not create
		// again, instead they should be fetch and use the existing bootstrap
		// data.

		// TODO(arslan): change this once we have group context name
		groupName := "koding"
		awsOutput := &AwsBootstrapOutput{}

		if args.Destroy {
			k.Log.Info("Destroying bootstrap resources belonging to public key '%s'", cred.PublicKey)
			_, err := tfKite.Destroy(&tf.TerraformRequest{
				Content:   finalBootstrap,
				ContentID: groupName + "-" + cred.PublicKey,
			})
			if err != nil {
				return nil, err
			}
		} else {
			k.Log.Info("Creating bootstrap resources belonging to public key '%s'", cred.PublicKey)
			state, err := tfKite.Apply(&tf.TerraformRequest{
				Content:   finalBootstrap,
				ContentID: groupName + "-" + cred.PublicKey,
			})
			if err != nil {
				return nil, err
			}

			k.Log.Debug("[%s] state.RootModule().Outputs = %+v\n", cred.PublicKey, state.RootModule().Outputs)
			if err := mapstructure.Decode(state.RootModule().Outputs, &awsOutput); err != nil {
				return nil, err
			}
		}

		k.Log.Debug("[%s] Aws Output: %+v", cred.PublicKey, awsOutput)
		if err := modelhelper.UpdateCredentialData(cred.PublicKey, bson.M{
			"$set": bson.M{
				"meta.acl":        awsOutput.ACL,
				"meta.cidr_block": awsOutput.CidrBlock,
				"meta.igw":        awsOutput.IGW,
				"meta.key_pair":   awsOutput.KeyPair,
				"meta.rtb":        awsOutput.RTB,
				"meta.sg":         awsOutput.SG,
				"meta.subnet":     awsOutput.Subnet,
				"meta.vpc":        awsOutput.VPC,
			},
		}); err != nil {
			return nil, err
		}
	}

	return true, nil
}

func appendKeyName(template, keyName string) (string, error) {
	var data struct {
		Output   map[string]map[string]interface{} `json:"output,omitempty"`
		Resource map[string]map[string]interface{} `json:"resource,omitempty"`
		Provider map[string]map[string]interface{} `json:"provider,omitempty"`
		Variable map[string]map[string]interface{} `json:"variable,omitempty"`
	}

	if err := json.Unmarshal([]byte(template), &data); err != nil {
		return "", err
	}

	data.Variable["key_name"] = map[string]interface{}{
		"default": keyName,
	}

	out, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return "", err
	}

	return string(out), nil
}

var awsBootstrap = `{
    "provider": {
        "aws": {
            "access_key": "${var.access_key}",
            "secret_key": "${var.secret_key}",
            "region": "${var.region}"
        }
    },
    "output": {
        "vpc": {
            "value": "${aws_vpc.vpc.id}"
        },
        "cidr_block": {
            "value": "${aws_vpc.vpc.cidr_block}"
        },
        "rtb": {
            "value": "${aws_vpc.vpc.main_route_table_id}"
        },
        "acl": {
            "value": "${aws_vpc.vpc.default_network_acl_id}"
        },
        "igw": {
            "value": "${aws_internet_gateway.main_vpc_igw.id}"
        },
        "subnet": {
            "value": "${aws_subnet.main_koding_subnet.id}"
        },
        "sg": {
            "value": "${aws_security_group.allow_all.id}"
        },
        "key_pair": {
            "value": "${aws_key_pair.koding_key_pair.key_name}"
        }
    },
    "resource": {
        "aws_vpc": {
            "vpc": {
                "cidr_block": "${var.cidr_block}",
                "tags": {
                    "Name": "${var.environment_name}"
                }
            }
        },
        "aws_internet_gateway": {
            "main_vpc_igw": {
                "tags": {
                    "Name": "${var.environment_name}"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_subnet": {
            "main_koding_subnet": {
                "availability_zone": "${lookup(var.aws_availability_zones, var.region)}",
                "cidr_block": "${var.cidr_block}",
                "map_public_ip_on_launch": true,
                "tags": {
                    "Name": "${var.environment_name}",
                    "subnet": "public"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_route_table": {
            "public": {
                "route": {
                    "cidr_block": "0.0.0.0/0",
                    "gateway_id": "${aws_internet_gateway.main_vpc_igw.id}"
                },
                "tags": {
                    "Name": "${var.environment_name}",
                    "routeTable": "koding",
                    "subnet": "public"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_route_table_association": {
            "public-1": {
                "route_table_id": "${aws_route_table.public.id}",
                "subnet_id": "${aws_subnet.main_koding_subnet.id}"
            }
        },
        "aws_security_group": {
            "allow_all": {
                "description": "Allow all inbound and outbound traffic",
                "ingress": {
                    "from_port": 0,
                    "to_port": 0,
                    "protocol": "-1",
                    "cidr_blocks": ["0.0.0.0/0"],
                    "self": true
                },
                "egress": {
                    "from_port": 0,
                    "to_port": 0,
                    "protocol": "-1",
                    "self": true,
                    "cidr_blocks": ["0.0.0.0/0"]
                },
                "name": "allow_all",
                "tags": {
                    "Name": "${var.environment_name}"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_key_pair": {
            "koding_key_pair": {
                "key_name": "${var.key_name}",
                "public_key": "%s"
            }
        }
    },
    "variable": {
        "cidr_block": {
            "default": "10.0.0.0/16"
        },
        "environment_name": {
            "default": "Koding-Bootstrap"
        },
        "aws_availability_zones": {
            "default": {
                "ap-northeast-1": "ap-northeast-1b",
                "ap-southeast-1": "ap-southeast-1b",
                "ap-southeast-2": "ap-southeast-2b",
                "eu-central-1": "eu-central-1b",
                "eu-west-1": "eu-west-1b",
                "sa-east-1": "sa-east-1b",
                "us-east-1": "us-east-1b",
                "us-west-1": "us-west-1b",
                "us-west-2": "us-west-2b"
            }
        }
    }
}`
<commit_msg>bootstrap: remove the fields after we are done<commit_after>package kloud

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"koding/kites/kloud/contexthelper/session"
	"koding/kites/kloud/terraformer"
	tf "koding/kites/terraformer"

	"labix.org/v2/mgo/bson"

	"golang.org/x/net/context"

	"github.com/koding/kite"
	"github.com/mitchellh/mapstructure"
)

type AwsBootstrapOutput struct {
	ACL       string `json:"acl" mapstructure:"acl"`
	CidrBlock string `json:"cidr_block" mapstructure:"cidr_block"`
	IGW       string `json:"igw" mapstructure:"igw"`
	KeyPair   string `json:"key_pair" mapstructure:"key_pair"`
	RTB       string `json:"rtb" mapstructure:"rtb"`
	SG        string `json:"sg" mapstructure:"sg"`
	Subnet    string `json:"subnet" mapstructure:"subnet"`
	VPC       string `json:"vpc" mapstructure:"vpc"`
}

type TerraformBootstrapRequest struct {
	// PublicKeys contains publicKeys to be used with terraform
	PublicKeys []string `json:"publicKeys"`

	// Destroy destroys the bootstrap resource associated with the given public
	// keys
	Destroy bool
}

func (k *Kloud) Bootstrap(r *kite.Request) (interface{}, error) {
	if r.Args == nil {
		return nil, NewError(ErrNoArguments)
	}

	var args *TerraformBootstrapRequest
	if err := r.Args.One().Unmarshal(&args); err != nil {
		return nil, err
	}

	if len(args.PublicKeys) == 0 {
		return nil, errors.New("publicKeys are not passed")
	}

	ctx := k.ContextCreator(context.Background())
	sess, ok := session.FromContext(ctx)
	if !ok {
		return nil, errors.New("session context is not passed")
	}

	creds, err := fetchCredentials(r.Username, sess.DB, args.PublicKeys)
	if err != nil {
		return nil, err
	}

	tfKite, err := terraformer.Connect(sess.Kite)
	if err != nil {
		return nil, err
	}
	defer tfKite.Close()

	for _, cred := range creds.Creds {
		// We are going to support more providers in the future, for now only allow aws
		if cred.Provider != "aws" {
			return nil, fmt.Errorf("Bootstrap is only supported for 'aws' provider. Got: '%s'", cred.Provider)
		}

		finalBootstrap, err := cred.appendAWSVariable(fmt.Sprintf(awsBootstrap, k.PublicKeys.PublicKey))
		if err != nil {
			return nil, err
		}

		keyName := "kloud-deployment-" + r.Username
		finalBootstrap, err = appendKeyName(finalBootstrap, keyName)
		if err != nil {
			return nil, err
		}

		k.Log.Debug("[%s] Final bootstrap:", cred.PublicKey)
		k.Log.Debug(finalBootstrap)

		// Important so bootstraping is distributed amongs multiple users. If I
		// use these keys to bootstrap, any other user should be not create
		// again, instead they should be fetch and use the existing bootstrap
		// data.

		// TODO(arslan): change this once we have group context name
		groupName := "koding"
		awsOutput := &AwsBootstrapOutput{}

		// this is custom because we need to remove the fields if we get a
		// destroy. So the operator changes from $set to $unset.
		mongodDBOperator := "$set"

		if args.Destroy {
			mongodDBOperator = "$unset"
			k.Log.Info("Destroying bootstrap resources belonging to public key '%s'", cred.PublicKey)
			_, err := tfKite.Destroy(&tf.TerraformRequest{
				Content:   finalBootstrap,
				ContentID: groupName + "-" + cred.PublicKey,
			})
			if err != nil {
				return nil, err
			}
		} else {
			k.Log.Info("Creating bootstrap resources belonging to public key '%s'", cred.PublicKey)
			state, err := tfKite.Apply(&tf.TerraformRequest{
				Content:   finalBootstrap,
				ContentID: groupName + "-" + cred.PublicKey,
			})
			if err != nil {
				return nil, err
			}

			k.Log.Debug("[%s] state.RootModule().Outputs = %+v\n", cred.PublicKey, state.RootModule().Outputs)
			if err := mapstructure.Decode(state.RootModule().Outputs, &awsOutput); err != nil {
				return nil, err
			}
		}

		k.Log.Debug("[%s] Aws Output: %+v", cred.PublicKey, awsOutput)
		if err := modelhelper.UpdateCredentialData(cred.PublicKey, bson.M{
			mongodDBOperator: bson.M{
				"meta.acl":        awsOutput.ACL,
				"meta.cidr_block": awsOutput.CidrBlock,
				"meta.igw":        awsOutput.IGW,
				"meta.key_pair":   awsOutput.KeyPair,
				"meta.rtb":        awsOutput.RTB,
				"meta.sg":         awsOutput.SG,
				"meta.subnet":     awsOutput.Subnet,
				"meta.vpc":        awsOutput.VPC,
			},
		}); err != nil {
			return nil, err
		}
	}

	return true, nil
}

func appendKeyName(template, keyName string) (string, error) {
	var data struct {
		Output   map[string]map[string]interface{} `json:"output,omitempty"`
		Resource map[string]map[string]interface{} `json:"resource,omitempty"`
		Provider map[string]map[string]interface{} `json:"provider,omitempty"`
		Variable map[string]map[string]interface{} `json:"variable,omitempty"`
	}

	if err := json.Unmarshal([]byte(template), &data); err != nil {
		return "", err
	}

	data.Variable["key_name"] = map[string]interface{}{
		"default": keyName,
	}

	out, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return "", err
	}

	return string(out), nil
}

var awsBootstrap = `{
    "provider": {
        "aws": {
            "access_key": "${var.access_key}",
            "secret_key": "${var.secret_key}",
            "region": "${var.region}"
        }
    },
    "output": {
        "vpc": {
            "value": "${aws_vpc.vpc.id}"
        },
        "cidr_block": {
            "value": "${aws_vpc.vpc.cidr_block}"
        },
        "rtb": {
            "value": "${aws_vpc.vpc.main_route_table_id}"
        },
        "acl": {
            "value": "${aws_vpc.vpc.default_network_acl_id}"
        },
        "igw": {
            "value": "${aws_internet_gateway.main_vpc_igw.id}"
        },
        "subnet": {
            "value": "${aws_subnet.main_koding_subnet.id}"
        },
        "sg": {
            "value": "${aws_security_group.allow_all.id}"
        },
        "key_pair": {
            "value": "${aws_key_pair.koding_key_pair.key_name}"
        }
    },
    "resource": {
        "aws_vpc": {
            "vpc": {
                "cidr_block": "${var.cidr_block}",
                "tags": {
                    "Name": "${var.environment_name}"
                }
            }
        },
        "aws_internet_gateway": {
            "main_vpc_igw": {
                "tags": {
                    "Name": "${var.environment_name}"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_subnet": {
            "main_koding_subnet": {
                "availability_zone": "${lookup(var.aws_availability_zones, var.region)}",
                "cidr_block": "${var.cidr_block}",
                "map_public_ip_on_launch": true,
                "tags": {
                    "Name": "${var.environment_name}",
                    "subnet": "public"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_route_table": {
            "public": {
                "route": {
                    "cidr_block": "0.0.0.0/0",
                    "gateway_id": "${aws_internet_gateway.main_vpc_igw.id}"
                },
                "tags": {
                    "Name": "${var.environment_name}",
                    "routeTable": "koding",
                    "subnet": "public"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_route_table_association": {
            "public-1": {
                "route_table_id": "${aws_route_table.public.id}",
                "subnet_id": "${aws_subnet.main_koding_subnet.id}"
            }
        },
        "aws_security_group": {
            "allow_all": {
                "description": "Allow all inbound and outbound traffic",
                "ingress": {
                    "from_port": 0,
                    "to_port": 0,
                    "protocol": "-1",
                    "cidr_blocks": ["0.0.0.0/0"],
                    "self": true
                },
                "egress": {
                    "from_port": 0,
                    "to_port": 0,
                    "protocol": "-1",
                    "self": true,
                    "cidr_blocks": ["0.0.0.0/0"]
                },
                "name": "allow_all",
                "tags": {
                    "Name": "${var.environment_name}"
                },
                "vpc_id": "${aws_vpc.vpc.id}"
            }
        },
        "aws_key_pair": {
            "koding_key_pair": {
                "key_name": "${var.key_name}",
                "public_key": "%s"
            }
        }
    },
    "variable": {
        "cidr_block": {
            "default": "10.0.0.0/16"
        },
        "environment_name": {
            "default": "Koding-Bootstrap"
        },
        "aws_availability_zones": {
            "default": {
                "ap-northeast-1": "ap-northeast-1b",
                "ap-southeast-1": "ap-southeast-1b",
                "ap-southeast-2": "ap-southeast-2b",
                "eu-central-1": "eu-central-1b",
                "eu-west-1": "eu-west-1b",
                "sa-east-1": "sa-east-1b",
                "us-east-1": "us-east-1b",
                "us-west-1": "us-west-1b",
                "us-west-2": "us-west-2b"
            }
        }
    }
}`
<|endoftext|>


<commit_before>package dc

import (
	"fmt"

	"github.com/CenturyLinkCloud/clc-sdk/api"
)

func New(client api.HTTP) *Service {
	return &Service{
		client: client,
		config: client.Config(),
	}
}

type Service struct {
	client api.HTTP
	config *api.Config
}

func (s *Service) Get(id string) (*Response, error) {
	url := fmt.Sprintf("%s/datacenters/%s/%s?groupLinks=true", s.config.BaseURL, s.config.Alias, id)
	dc := &Response{}
	err := s.client.Get(url, dc)
	return dc, err
}

func (s *Service) GetAll() ([]*Response, error) {
	url := fmt.Sprintf("%s/datacenters/%s", s.config.BaseURL, s.config.Alias)
	dcs := make([]*Response, 0)
	err := s.client.Get(url, &dcs)
	return dcs, err
}

func (s *Service) GetCapabilities(id string) (*CapabilitiesResponse, error) {
	url := fmt.Sprintf("%s/datacenters/%s/%s/deploymentCapabilities", s.config.BaseURL, s.config.Alias, id)
	c := &CapabilitiesResponse{}
	err := s.client.Get(url, c)
	return c, err
}

type Response struct {
	ID    string    `json:"id"`
	Name  string    `json:"name"`
	Links api.Links `json:"links"`
}

type CapabilitiesResponse struct {
	SupportsPremiumStorage     bool `json:"supportsPremiumStorage"`
	SupportsBareMetalServers   bool `json:"supportsBareMetalServers"`
	SupportsSharedLoadBalancer bool `json:"supportsSharedLoadBalancer"`
	Templates                  []struct {
		Name               string   `json:"name"`
		Description        string   `json:"description"`
		StorageSizeGB      string   `json:"storageSizeGB"`
		Capabilities       []string `json:"capabilities"`
		ReservedDrivePaths []string `json:"reservedDrivePaths"`
	} `json:"templates"`
	DeployableNetworks []struct {
		Name      string `json:"name"`
		NetworkId string `json:"networkId"`
		Type      string `json:"type"`
		AccountID string `json:"accountID"`
	} `json:"deployableNetworks"`
}
<commit_msg>Fixed an unmarshalling error and also added baremetal capabilities<commit_after>package dc

import (
	"fmt"

	"github.com/CenturyLinkCloud/clc-sdk/api"
)

func New(client api.HTTP) *Service {
	return &Service{
		client: client,
		config: client.Config(),
	}
}

type Service struct {
	client api.HTTP
	config *api.Config
}

func (s *Service) Get(id string) (*Response, error) {
	url := fmt.Sprintf("%s/datacenters/%s/%s?groupLinks=true", s.config.BaseURL, s.config.Alias, id)
	dc := &Response{}
	err := s.client.Get(url, dc)
	return dc, err
}

func (s *Service) GetAll() ([]*Response, error) {
	url := fmt.Sprintf("%s/datacenters/%s", s.config.BaseURL, s.config.Alias)
	dcs := make([]*Response, 0)
	err := s.client.Get(url, &dcs)
	return dcs, err
}

func (s *Service) GetCapabilities(id string) (*CapabilitiesResponse, error) {
	url := fmt.Sprintf("%s/datacenters/%s/%s/deploymentCapabilities", s.config.BaseURL, s.config.Alias, id)
	c := &CapabilitiesResponse{}
	err := s.client.Get(url, c)
	return c, err
}

func (s *Service) GetBareMetalCapabilities(dataCenterId string) (*BareMetalCapabilitiesResponse, error) {
	url := fmt.Sprintf("%s/datacenters/%s/%s/bareMetalCapabilities", s.config.BaseURL, s.config.Alias, dataCenterId)
	bm := &BareMetalCapabilitiesResponse{}
	err := s.client.Get(url, bm)
	return bm, err
}

type Response struct {
	ID    string    `json:"id"`
	Name  string    `json:"name"`
	Links api.Links `json:"links"`
}

type CapabilitiesResponse struct {
	SupportsPremiumStorage     bool `json:"supportsPremiumStorage"`
	SupportsBareMetalServers   bool `json:"supportsBareMetalServers"`
	SupportsSharedLoadBalancer bool `json:"supportsSharedLoadBalancer"`
	Templates                  []struct {
		Name               string   `json:"name"`
		Description        string   `json:"description"`
		StorageSizeGB      int      `json:"storageSizeGB"`
		Capabilities       []string `json:"capabilities"`
		ReservedDrivePaths []string `json:"reservedDrivePaths"`
	} `json:"templates"`
	DeployableNetworks []struct {
		Name      string `json:"name"`
		NetworkId string `json:"networkId"`
		Type      string `json:"type"`
		AccountID string `json:"accountID"`
	} `json:"deployableNetworks"`
}

type BareMetalCapabilitiesResponse struct {
	SKUs []struct {
		ID           string  `json:"id"`
		HourlyRate   float32 `json:"hourlyRate"`
		Availability string  `json:"availability"`
		Memory       []struct {
			CapacityInGB int `json:"capacityGB"`
		} `json:"memory"`
		Processor struct {
			Sockets        int    `json:"sockets"`
			CoresPerSocket int    `json:"coresPerSocket"`
			Description    string `json:"description"`
		} `json:"processor"`
		Storage []struct {
			Type         string `json:"type"`
			CapacityInGB int    `json:"capacityGB"`
			SpeedInRPM   int    `json:"speedRpm"`
		} `json:"storage"`
	} `json:"skus"`
	OperatingSystems []struct {
		Type                string  `json:"type"`
		Description         string  `json:"description"`
		HourlyRatePerSocket float32 `json:"hourlyRatePerSocket"`
	} `json:"operatingSystems"`
}
<|endoftext|>


<commit_before>package stconverter

import (
	"strings"
)

//verilogTemplate templates make the following assumptions:
//1) All variables are VHDL "Variables", not "signals"
//2) All variables are integer types
//3) Everything completes in a single cycle
//4) loops aren't yet supported
const verilogTemplate = `
{{define "expression"}}{{$value := .HasValue}}{{$operator := .HasOperator}}{{/*
	*/}}{{if $value}}{{/*
		*/}}{{if isKnownVar $value}}{{$value}}{{else}}{{$value}}{{end}}{{/*
	*/}}{{else if $operator}}{{/* //then we need to determine how to print this operator
		*/}}{{if $operator.LeftAssociative}}{{/* //print first argument, operator string, then remaining arguments
			*/}}{{$args := reverseArgs .GetArguments}}{{$a := index $args 0}}{{$b := index $args 1}}{{$curPrec := $operator.GetPrecedence}}{{$aop := $a.HasOperator}}{{$bop := $b.HasOperator}}{{/*
			*/}}{{if $aop}}{{if gte $aop.GetPrecedence $curPrec}}({{end}}{{end}}{{template "expression" $a}}{{if $aop}}{{if gte $aop.GetPrecedence $curPrec}}){{end}}{{end}} {{translateOperatorToken $operator.GetToken}} {{if $bop}}{{if gte $bop.GetPrecedence $curPrec}}({{end}}{{end}}{{template "expression" $b}}{{if $bop}}{{if gte $bop.GetPrecedence $curPrec}}){{end}}{{end}}{{/*
		*/}}{{else}}{{/* //print name, opening bracket, then arguments separated by commas
			*/}}{{translateOperatorToken $operator.GetToken}}{{/*
			*/}}{{range $ind, $arg := reverseArgs .GetArguments}}{{if $ind}}, {{end}}{{template "expression" $arg}}{{end}}{{if tokenIsFunctionCall $operator.GetToken}}){{end}}{{/*
		*/}}{{end}}{{/*
	*/}}{{end}}{{/*}}
*/}}{{end}}

{{define "ifelsifelse"}}{{/*
	*/}}{{range $i, $ifThen := .IfThens}}{{/* //cycle through all the ifThens
		*/}}{{if $i}} else {{end}}if ({{template "expression" $ifThen.IfExpression}}) begin
			{{compileSequence $ifThen.ThenSequence}}
		end
		{{end}}{{/*
	*/}}{{if .ElseSequence}} else begin
		{{compileSequence .ElseSequence}}
	end{{end}}{{/*
*/}}{{end}}

{{define "switchcase"}}{{/*
	*/}}case({{template "expression" .SwitchOn}}) {{range $ci, $case := .Cases}}
	{{range $cii, $casev := $case.CaseValues}}{{if $cii}}, {{end}}{{$casev}}{{end}}: begin
		{{compileSequence $case.Sequence}}
	end{{end}}
	{{if .ElseSequence}}default: begin
		{{compileSequence .ElseSequence}}
	end{{end}}
	endcase {{/*
*/}}{{end}}

{{define "forloop"}} --for loops not supported in VHDL
{{end}}

{{define "whileloop"}} --while loops not supported in VHDL
{{end}}

{{define "repeatloop"}} --repeat loops not supported in VHDL
{{end}}`

func verilogTokenIsFunctionCall(token string) bool {
	if token == "not" {
		return true
	}
	first := strings.Index(token, "<")
	if len(token) > 2 && token[len(token)-1:] == ">" && first != -1 {
		return true
	}
	return false
}

func verilogTranslateOperatorToken(token string) string {
	//is it our function<n> syntax?
	first := strings.Index(token, "<")
	if len(token) > 2 && token[len(token)-1:] == ">" && first != -1 {
		//we on't need the following... we don't need the number of arguments??
		// ops := token[first+1 : len(token)-1]
		// opsInt, err := strconv.Atoi(ops)
		// if err != nil {
		// 	return token[:first-1] + "("
		// }
		return token[:first] + "("
	}
	//TODO: nots should be dealt with a better way
	if token == "not" {
		return "~("
	}
	//ok, not a function, so it's one of the st Operators
	switch token {
	case stExit:
		return "break"
	case stReturn:
		return "return"
	case stNot:
		return "~"
	case stNegative:
		return "-"
	case stExponentiation:
		return "**"
	case stMultiply:
		return "*"
	case stDivide:
		return "/"
	case stModulo:
		return "%"
	case stAdd:
		return "+"
	case stSubtract:
		return "-"
	case stLessThan:
		return "<"
	case stGreaterThan:
		return ">"
	case stLessThanEqualTo:
		return "<="
	case stGreaterThanEqualTo:
		return ">="
	case stEqual:
		return "=="
	case stInequal:
		return "!="
	case stAnd:
		return "&&"
	case stExlusiveOr:
		return "^"
	case stOr:
		return "||"
	case stAssignment:
		return "="
	}
	//still here? panic
	panic("unsupported token " + token)
}
<commit_msg>verilog change not operator to !<commit_after>package stconverter

import (
	"strings"
)

//verilogTemplate templates make the following assumptions:
//1) All variables are VHDL "Variables", not "signals"
//2) All variables are integer types
//3) Everything completes in a single cycle
//4) loops aren't yet supported
const verilogTemplate = `
{{define "expression"}}{{$value := .HasValue}}{{$operator := .HasOperator}}{{/*
	*/}}{{if $value}}{{/*
		*/}}{{if isKnownVar $value}}{{$value}}{{else}}{{$value}}{{end}}{{/*
	*/}}{{else if $operator}}{{/* //then we need to determine how to print this operator
		*/}}{{if $operator.LeftAssociative}}{{/* //print first argument, operator string, then remaining arguments
			*/}}{{$args := reverseArgs .GetArguments}}{{$a := index $args 0}}{{$b := index $args 1}}{{$curPrec := $operator.GetPrecedence}}{{$aop := $a.HasOperator}}{{$bop := $b.HasOperator}}{{/*
			*/}}{{if $aop}}{{if gte $aop.GetPrecedence $curPrec}}({{end}}{{end}}{{template "expression" $a}}{{if $aop}}{{if gte $aop.GetPrecedence $curPrec}}){{end}}{{end}} {{translateOperatorToken $operator.GetToken}} {{if $bop}}{{if gte $bop.GetPrecedence $curPrec}}({{end}}{{end}}{{template "expression" $b}}{{if $bop}}{{if gte $bop.GetPrecedence $curPrec}}){{end}}{{end}}{{/*
		*/}}{{else}}{{/* //print name, opening bracket, then arguments separated by commas
			*/}}{{translateOperatorToken $operator.GetToken}}{{/*
			*/}}{{range $ind, $arg := reverseArgs .GetArguments}}{{if $ind}}, {{end}}{{template "expression" $arg}}{{end}}{{if tokenIsFunctionCall $operator.GetToken}}){{end}}{{/*
		*/}}{{end}}{{/*
	*/}}{{end}}{{/*}}
*/}}{{end}}

{{define "ifelsifelse"}}{{/*
	*/}}{{range $i, $ifThen := .IfThens}}{{/* //cycle through all the ifThens
		*/}}{{if $i}} else {{end}}if ({{template "expression" $ifThen.IfExpression}}) begin
			{{compileSequence $ifThen.ThenSequence}}
		end
		{{end}}{{/*
	*/}}{{if .ElseSequence}} else begin
		{{compileSequence .ElseSequence}}
	end{{end}}{{/*
*/}}{{end}}

{{define "switchcase"}}{{/*
	*/}}case({{template "expression" .SwitchOn}}) {{range $ci, $case := .Cases}}
	{{range $cii, $casev := $case.CaseValues}}{{if $cii}}, {{end}}{{$casev}}{{end}}: begin
		{{compileSequence $case.Sequence}}
	end{{end}}
	{{if .ElseSequence}}default: begin
		{{compileSequence .ElseSequence}}
	end{{end}}
	endcase {{/*
*/}}{{end}}

{{define "forloop"}} --for loops not supported in VHDL
{{end}}

{{define "whileloop"}} --while loops not supported in VHDL
{{end}}

{{define "repeatloop"}} --repeat loops not supported in VHDL
{{end}}`

func verilogTokenIsFunctionCall(token string) bool {
	if token == "not" {
		return true
	}
	first := strings.Index(token, "<")
	if len(token) > 2 && token[len(token)-1:] == ">" && first != -1 {
		return true
	}
	return false
}

func verilogTranslateOperatorToken(token string) string {
	//is it our function<n> syntax?
	first := strings.Index(token, "<")
	if len(token) > 2 && token[len(token)-1:] == ">" && first != -1 {
		//we on't need the following... we don't need the number of arguments??
		// ops := token[first+1 : len(token)-1]
		// opsInt, err := strconv.Atoi(ops)
		// if err != nil {
		// 	return token[:first-1] + "("
		// }
		return token[:first] + "("
	}
	//TODO: nots should be dealt with a better way
	if token == "not" {
		return "!("
	}
	//ok, not a function, so it's one of the st Operators
	switch token {
	case stExit:
		return "break"
	case stReturn:
		return "return"
	case stNot:
		return "!"
	case stNegative:
		return "-"
	case stExponentiation:
		return "**"
	case stMultiply:
		return "*"
	case stDivide:
		return "/"
	case stModulo:
		return "%"
	case stAdd:
		return "+"
	case stSubtract:
		return "-"
	case stLessThan:
		return "<"
	case stGreaterThan:
		return ">"
	case stLessThanEqualTo:
		return "<="
	case stGreaterThanEqualTo:
		return ">="
	case stEqual:
		return "=="
	case stInequal:
		return "!="
	case stAnd:
		return "&&"
	case stExlusiveOr:
		return "^"
	case stOr:
		return "||"
	case stAssignment:
		return "="
	}
	//still here? panic
	panic("unsupported token " + token)
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2017 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 cid

import (
	"crypto/x509"
	"encoding/asn1"
	"encoding/hex"
	"encoding/pem"
	"fmt"

	"github.com/golang/protobuf/proto"
	"github.com/hyperledger/fabric/common/attrmgr"
	"github.com/hyperledger/fabric/protos/msp"
	"github.com/pkg/errors"
)

// GetID returns the ID associated with the invoking identity.  This ID
// is guaranteed to be unique within the MSP.
func GetID(stub ChaincodeStubInterface) (string, error) {
	c, err := New(stub)
	if err != nil {
		return "", err
	}
	return c.GetID()
}

// GetMSPID returns the ID of the MSP associated with the identity that
// submitted the transaction
func GetMSPID(stub ChaincodeStubInterface) (string, error) {
	c, err := New(stub)
	if err != nil {
		return "", err
	}
	return c.GetMSPID()
}

// GetAttributeValue returns value of the specified attribute
func GetAttributeValue(stub ChaincodeStubInterface, attrName string) (value string, found bool, err error) {
	c, err := New(stub)
	if err != nil {
		return "", false, err
	}
	return c.GetAttributeValue(attrName)
}

// AssertAttributeValue checks to see if an attribute value equals the specified value
func AssertAttributeValue(stub ChaincodeStubInterface, attrName, attrValue string) error {
	c, err := New(stub)
	if err != nil {
		return err
	}
	return c.AssertAttributeValue(attrName, attrValue)
}

// GetX509Certificate returns the X509 certificate associated with the client,
// or nil if it was not identified by an X509 certificate.
func GetX509Certificate(stub ChaincodeStubInterface) (*x509.Certificate, error) {
	c, err := New(stub)
	if err != nil {
		return nil, err
	}
	return c.GetX509Certificate()
}

// ClientIdentityImpl implements the ClientIdentity interface
type clientIdentityImpl struct {
	stub  ChaincodeStubInterface
	mspID string
	cert  *x509.Certificate
	attrs *attrmgr.Attributes
}

// New returns an instance of ClientIdentity
func New(stub ChaincodeStubInterface) (ClientIdentity, error) {
	c := &clientIdentityImpl{stub: stub}
	err := c.init()
	if err != nil {
		return nil, err
	}
	return c, nil
}

// GetID returns the ID associated with the invoking identity.  This ID
// is guaranteed to be unique within the MSP.
func (c *clientIdentityImpl) GetID() (string, error) {
	return getDN(c.cert), nil
}

// GetMSPID returns the ID of the MSP associated with the identity that
// submitted the transaction
func (c *clientIdentityImpl) GetMSPID() (string, error) {
	return c.mspID, nil
}

// GetAttributeValue returns value of the specified attribute
func (c *clientIdentityImpl) GetAttributeValue(attrName string) (value string, found bool, err error) {
	if c.attrs == nil {
		return "", false, nil
	}
	return c.attrs.Value(attrName)
}

// AssertAttributeValue checks to see if an attribute value equals the specified value
func (c *clientIdentityImpl) AssertAttributeValue(attrName, attrValue string) error {
	val, ok, err := c.GetAttributeValue(attrName)
	if err != nil {
		return err
	}
	if !ok {
		return errors.Errorf("Attribute '%s' was not found", attrName)
	}
	if val != attrValue {
		return errors.Errorf("Attribute '%s' equals '%s', not '%s'", attrName, val, attrValue)
	}
	return nil
}

// GetX509Certificate returns the X509 certificate associated with the client,
// or nil if it was not identified by an X509 certificate.
func (c *clientIdentityImpl) GetX509Certificate() (*x509.Certificate, error) {
	return c.cert, nil
}

// Initialize the client
func (c *clientIdentityImpl) init() error {
	signingID, err := c.getIdentity()
	if err != nil {
		return err
	}
	c.mspID = signingID.GetMspid()
	idbytes := signingID.GetIdBytes()
	block, _ := pem.Decode(idbytes)
	if block == nil || block.Type != "CERTIFICATE" {
		bt := "none"
		if block != nil {
			bt = block.Type
		}
		return errors.Errorf("unexpected PEM block found. Expected a certificate but found a block of type: %s", bt)
	}
	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		return errors.Wrap(err, "failed to parse certificate")
	}
	c.cert = cert
	attrs, err := attrmgr.New().GetAttributesFromCert(cert)
	if err != nil {
		return errors.WithMessage(err, "failed to get attributes from the transaction invoker's certificate")
	}
	c.attrs = attrs
	return nil
}

// Unmarshals the bytes returned by ChaincodeStubInterface.GetCreator method and
// returns the resulting msp.SerializedIdentity object
func (c *clientIdentityImpl) getIdentity() (*msp.SerializedIdentity, error) {
	sid := &msp.SerializedIdentity{}
	creator, err := c.stub.GetCreator()
	if err != nil || creator == nil {
		return nil, errors.WithMessage(err, "failed to get transaction invoker's identity from the chaincode stub")
	}
	err = proto.Unmarshal(creator, sid)
	if err != nil {
		return nil, errors.Wrap(err, "failed to unmarshal transaction invoker's identity")
	}
	return sid, nil
}

// Get the DN (distinquished name) associated with the subject of the certificate.
// NOTE: This code is almost a direct copy of the String() function in
// https://go-review.googlesource.com/c/go/+/67270/1/src/crypto/x509/pkix/pkix.go#26
// which returns a DN as defined by RFC 2253.
func getDN(cert *x509.Certificate) string {
	r := cert.Subject.ToRDNSequence()
	s := ""
	for i := 0; i < len(r); i++ {
		rdn := r[len(r)-1-i]
		if i > 0 {
			s += ","
		}
		for j, tv := range rdn {
			if j > 0 {
				s += "+"
			}
			typeString := tv.Type.String()
			typeName, ok := attributeTypeNames[typeString]
			if !ok {
				derBytes, err := asn1.Marshal(tv.Value)
				if err == nil {
					s += typeString + "=#" + hex.EncodeToString(derBytes)
					continue // No value escaping necessary.
				}
				typeName = typeString
			}
			valueString := fmt.Sprint(tv.Value)
			escaped := ""
			begin := 0
			for idx, c := range valueString {
				if (idx == 0 && (c == ' ' || c == '#')) ||
					(idx == len(valueString)-1 && c == ' ') {
					escaped += valueString[begin:idx]
					escaped += "\\" + string(c)
					begin = idx + 1
					continue
				}
				switch c {
				case ',', '+', '"', '\\', '<', '>', ';':
					escaped += valueString[begin:idx]
					escaped += "\\" + string(c)
					begin = idx + 1
				}
			}
			escaped += valueString[begin:]
			s += typeName + "=" + escaped
		}
	}
	return s
}

var attributeTypeNames = map[string]string{
	"2.5.4.6":  "C",
	"2.5.4.10": "O",
	"2.5.4.11": "OU",
	"2.5.4.3":  "CN",
	"2.5.4.5":  "SERIALNUMBER",
	"2.5.4.7":  "L",
	"2.5.4.8":  "ST",
	"2.5.4.9":  "STREET",
	"2.5.4.17": "POSTALCODE",
}
<commit_msg>[FAB-6465] Fix client ID library for v1.0<commit_after>/*
Copyright IBM Corp. 2017 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 cid

import (
	"crypto/x509"
	"encoding/asn1"
	"encoding/hex"
	"encoding/pem"
	"fmt"

	"github.com/golang/protobuf/proto"
	"github.com/hyperledger/fabric/common/attrmgr"
	"github.com/hyperledger/fabric/protos/msp"
	"github.com/pkg/errors"
)

// GetID returns the ID associated with the invoking identity.  This ID
// is guaranteed to be unique within the MSP.
func GetID(stub ChaincodeStubInterface) (string, error) {
	c, err := New(stub)
	if err != nil {
		return "", err
	}
	return c.GetID()
}

// GetMSPID returns the ID of the MSP associated with the identity that
// submitted the transaction
func GetMSPID(stub ChaincodeStubInterface) (string, error) {
	c, err := New(stub)
	if err != nil {
		return "", err
	}
	return c.GetMSPID()
}

// GetAttributeValue returns value of the specified attribute
func GetAttributeValue(stub ChaincodeStubInterface, attrName string) (value string, found bool, err error) {
	c, err := New(stub)
	if err != nil {
		return "", false, err
	}
	return c.GetAttributeValue(attrName)
}

// AssertAttributeValue checks to see if an attribute value equals the specified value
func AssertAttributeValue(stub ChaincodeStubInterface, attrName, attrValue string) error {
	c, err := New(stub)
	if err != nil {
		return err
	}
	return c.AssertAttributeValue(attrName, attrValue)
}

// GetX509Certificate returns the X509 certificate associated with the client,
// or nil if it was not identified by an X509 certificate.
func GetX509Certificate(stub ChaincodeStubInterface) (*x509.Certificate, error) {
	c, err := New(stub)
	if err != nil {
		return nil, err
	}
	return c.GetX509Certificate()
}

// ClientIdentityImpl implements the ClientIdentity interface
type clientIdentityImpl struct {
	stub  ChaincodeStubInterface
	mspID string
	cert  *x509.Certificate
	attrs *attrmgr.Attributes
}

// New returns an instance of ClientIdentity
func New(stub ChaincodeStubInterface) (ClientIdentity, error) {
	c := &clientIdentityImpl{stub: stub}
	err := c.init()
	if err != nil {
		return nil, err
	}
	return c, nil
}

// GetID returns the ID associated with the invoking identity.  This ID
// is guaranteed to be unique within the MSP.
func (c *clientIdentityImpl) GetID() (string, error) {
	return getDN(c.cert), nil
}

// GetMSPID returns the ID of the MSP associated with the identity that
// submitted the transaction
func (c *clientIdentityImpl) GetMSPID() (string, error) {
	return c.mspID, nil
}

// GetAttributeValue returns value of the specified attribute
func (c *clientIdentityImpl) GetAttributeValue(attrName string) (value string, found bool, err error) {
	if c.attrs == nil {
		return "", false, nil
	}
	return c.attrs.Value(attrName)
}

// AssertAttributeValue checks to see if an attribute value equals the specified value
func (c *clientIdentityImpl) AssertAttributeValue(attrName, attrValue string) error {
	val, ok, err := c.GetAttributeValue(attrName)
	if err != nil {
		return err
	}
	if !ok {
		return errors.Errorf("Attribute '%s' was not found", attrName)
	}
	if val != attrValue {
		return errors.Errorf("Attribute '%s' equals '%s', not '%s'", attrName, val, attrValue)
	}
	return nil
}

// GetX509Certificate returns the X509 certificate associated with the client,
// or nil if it was not identified by an X509 certificate.
func (c *clientIdentityImpl) GetX509Certificate() (*x509.Certificate, error) {
	return c.cert, nil
}

// Initialize the client
func (c *clientIdentityImpl) init() error {
	signingID, err := c.getIdentity()
	if err != nil {
		return err
	}
	c.mspID = signingID.GetMspid()
	idbytes := signingID.GetIdBytes()
	block, _ := pem.Decode(idbytes)
	if block == nil {
		return errors.New("Expecting a PEM-encoded X509 certificate; PEM block not found")
	}
	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		return errors.Wrap(err, "failed to parse certificate")
	}
	c.cert = cert
	attrs, err := attrmgr.New().GetAttributesFromCert(cert)
	if err != nil {
		return errors.WithMessage(err, "failed to get attributes from the transaction invoker's certificate")
	}
	c.attrs = attrs
	return nil
}

// Unmarshals the bytes returned by ChaincodeStubInterface.GetCreator method and
// returns the resulting msp.SerializedIdentity object
func (c *clientIdentityImpl) getIdentity() (*msp.SerializedIdentity, error) {
	sid := &msp.SerializedIdentity{}
	creator, err := c.stub.GetCreator()
	if err != nil || creator == nil {
		return nil, errors.WithMessage(err, "failed to get transaction invoker's identity from the chaincode stub")
	}
	err = proto.Unmarshal(creator, sid)
	if err != nil {
		return nil, errors.Wrap(err, "failed to unmarshal transaction invoker's identity")
	}
	return sid, nil
}

// Get the DN (distinquished name) associated with the subject of the certificate.
// NOTE: This code is almost a direct copy of the String() function in
// https://go-review.googlesource.com/c/go/+/67270/1/src/crypto/x509/pkix/pkix.go#26
// which returns a DN as defined by RFC 2253.
func getDN(cert *x509.Certificate) string {
	r := cert.Subject.ToRDNSequence()
	s := ""
	for i := 0; i < len(r); i++ {
		rdn := r[len(r)-1-i]
		if i > 0 {
			s += ","
		}
		for j, tv := range rdn {
			if j > 0 {
				s += "+"
			}
			typeString := tv.Type.String()
			typeName, ok := attributeTypeNames[typeString]
			if !ok {
				derBytes, err := asn1.Marshal(tv.Value)
				if err == nil {
					s += typeString + "=#" + hex.EncodeToString(derBytes)
					continue // No value escaping necessary.
				}
				typeName = typeString
			}
			valueString := fmt.Sprint(tv.Value)
			escaped := ""
			begin := 0
			for idx, c := range valueString {
				if (idx == 0 && (c == ' ' || c == '#')) ||
					(idx == len(valueString)-1 && c == ' ') {
					escaped += valueString[begin:idx]
					escaped += "\\" + string(c)
					begin = idx + 1
					continue
				}
				switch c {
				case ',', '+', '"', '\\', '<', '>', ';':
					escaped += valueString[begin:idx]
					escaped += "\\" + string(c)
					begin = idx + 1
				}
			}
			escaped += valueString[begin:]
			s += typeName + "=" + escaped
		}
	}
	return s
}

var attributeTypeNames = map[string]string{
	"2.5.4.6":  "C",
	"2.5.4.10": "O",
	"2.5.4.11": "OU",
	"2.5.4.3":  "CN",
	"2.5.4.5":  "SERIALNUMBER",
	"2.5.4.7":  "L",
	"2.5.4.8":  "ST",
	"2.5.4.9":  "STREET",
	"2.5.4.17": "POSTALCODE",
}
<|endoftext|>


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

// Make the Envelope type JSON-codeable.

package application

import (
	"encoding/base64"
	"encoding/json"
	"fmt"

	"v.io/v23/security"
	"v.io/v23/vom"
)

type jsonType struct {
	Title     string
	Args      []string
	Binary    SignedFile
	Publisher string // base64-vom-encoded security.Blessings
	Env       []string
	Packages  Packages
}

func (env Envelope) MarshalJSON() ([]byte, error) {
	var bytes []byte
	if !env.Publisher.IsZero() {
		var err error
		if bytes, err = vom.Encode(env.Publisher); err != nil {
			return nil, fmt.Errorf("failed to vom-encode Publisher: %v", err)
		}
	}
	return json.Marshal(jsonType{
		Title:     env.Title,
		Args:      env.Args,
		Binary:    env.Binary,
		Publisher: base64.URLEncoding.EncodeToString(bytes),
		Env:       env.Env,
		Packages:  env.Packages,
	})
}

func (env *Envelope) UnmarshalJSON(input []byte) error {
	var jt jsonType
	if err := json.Unmarshal(input, &jt); err != nil {
		return err
	}
	var publisher security.Blessings
	if len(jt.Publisher) > 0 {
		bytes, err := base64.URLEncoding.DecodeString(jt.Publisher)
		if err != nil {
			return fmt.Errorf("failed to base64-decode Publisher: %v", err)
		}
		if err := vom.Decode(bytes, &publisher); err != nil {
			return fmt.Errorf("failed to vom-decode Publisher: %v", err)
		}
	}
	env.Title = jt.Title
	env.Args = jt.Args
	env.Binary = jt.Binary
	env.Publisher = publisher
	env.Env = jt.Env
	env.Packages = jt.Packages
	return nil
}
<commit_msg>v.io/v23/services/mgmt/application: Use verror instead of fmt.Errorf<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Make the Envelope type JSON-codeable.

package application

import (
	"encoding/base64"
	"encoding/json"

	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/v23/vom"
)

const pkgPath = "v.io/v23/services/mgmt/application"

var (
	errCantVOMEncodePublisher    = verror.Register(pkgPath+".errCantVOMEncodePublisher", verror.NoRetry, "{1:}{2:} failed to vom-encode Publisher{:_}")
	errCantBase64DecodePublisher = verror.Register(pkgPath+".errCantBase64DecodePublisher", verror.NoRetry, "{1:}{2:} failed to base64-decode Publisher{:_}")
	errCantVOMDecodePublisher    = verror.Register(pkgPath+".errCantVOMDecodePublisher", verror.NoRetry, "{1:}{2:} failed to vom-decode Publisher{:_}")
)

type jsonType struct {
	Title     string
	Args      []string
	Binary    SignedFile
	Publisher string // base64-vom-encoded security.Blessings
	Env       []string
	Packages  Packages
}

func (env Envelope) MarshalJSON() ([]byte, error) {
	var bytes []byte
	if !env.Publisher.IsZero() {
		var err error
		if bytes, err = vom.Encode(env.Publisher); err != nil {
			return nil, verror.New(errCantVOMEncodePublisher, nil, err)
		}
	}
	return json.Marshal(jsonType{
		Title:     env.Title,
		Args:      env.Args,
		Binary:    env.Binary,
		Publisher: base64.URLEncoding.EncodeToString(bytes),
		Env:       env.Env,
		Packages:  env.Packages,
	})
}

func (env *Envelope) UnmarshalJSON(input []byte) error {
	var jt jsonType
	if err := json.Unmarshal(input, &jt); err != nil {
		return err
	}
	var publisher security.Blessings
	if len(jt.Publisher) > 0 {
		bytes, err := base64.URLEncoding.DecodeString(jt.Publisher)
		if err != nil {
			return verror.New(errCantBase64DecodePublisher, nil, err)
		}
		if err := vom.Decode(bytes, &publisher); err != nil {
			return verror.New(errCantVOMDecodePublisher, nil, err)
		}
	}
	env.Title = jt.Title
	env.Args = jt.Args
	env.Binary = jt.Binary
	env.Publisher = publisher
	env.Env = jt.Env
	env.Packages = jt.Packages
	return nil
}
<|endoftext|>


<commit_before>package w32uiautomation

import (
	"fmt"
	"syscall"
	"unsafe"

	"github.com/mattn/go-ole"
)

type StructureChangeType uintptr

const (
	StructureChangeType_ChildAdded = iota
	StructureChangeType_ChildRemoved
	StructureChangeType_ChildrenInvalidated
	StructureChangeType_ChildrenBulkAdded
	StructureChangeType_ChildrenBulkRemoved
	StructureChangeType_ChildrenReordered
)

func (t StructureChangeType) ToString() string {
	switch t {
	case StructureChangeType_ChildAdded:
		return "StructureChangeType_ChildAdded"
	case StructureChangeType_ChildRemoved:
		return "StructureChangeType_ChildRemoved"
	case StructureChangeType_ChildrenInvalidated:
		return "StructureChangeType_ChildrenInvalidated"
	case StructureChangeType_ChildrenBulkAdded:
		return "StructureChangeType_ChildrenBulkAdded"
	case StructureChangeType_ChildrenBulkRemoved:
		return "StructureChangeType_ChildrenBulkRemoved"
	case StructureChangeType_ChildrenReordered:
		return "StructureChangeType_ChildrenReordered"
	default:
		panic(fmt.Errorf("Unknown StructureChangeType: %d", t))
	}
}

type IUIAutomationStructureChangedEventHandler struct {
	ole.IUnknown
	Ref int32
}

type IUIAutomationStructureChangedEventHandlerVtbl struct {
	ole.IUnknownVtbl
	HandleStructureChangedEvent uintptr
}

var IID_IUIAutomationStructureChangedEventHandler = &ole.GUID{0xe81d1b4e, 0x11c5, 0x42f8, [8]byte{0x97, 0x54, 0xe7, 0x03, 0x6c, 0x79, 0xf0, 0x54}}

func (h *IUIAutomationStructureChangedEventHandler) VTable() *IUIAutomationStructureChangedEventHandlerVtbl {
	return (*IUIAutomationStructureChangedEventHandlerVtbl)(unsafe.Pointer(h.RawVTable))
}

func structureChangedEventHandler_queryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 {
	*punk = nil
	if ole.IsEqualGUID(iid, ole.IID_IUnknown) ||
		ole.IsEqualGUID(iid, ole.IID_IDispatch) {
		structureChangedEventHandler_addRef(this)
		*punk = this
		return ole.S_OK
	}
	if ole.IsEqualGUID(iid, IID_IUIAutomationStructureChangedEventHandler) {
		structureChangedEventHandler_addRef(this)
		*punk = this
		return ole.S_OK
	}
	return ole.E_NOINTERFACE
}

func structureChangedEventHandler_addRef(this *ole.IUnknown) int32 {
	pthis := (*IUIAutomationStructureChangedEventHandler)(unsafe.Pointer(this))
	pthis.Ref++
	return pthis.Ref
}

func structureChangedEventHandler_release(this *ole.IUnknown) int32 {
	pthis := (*IUIAutomationStructureChangedEventHandler)(unsafe.Pointer(this))
	pthis.Ref--
	return pthis.Ref
}

func NewStructureChangedEventHandler(handlerFunc func(this *IUIAutomationStructureChangedEventHandler, sender *IUIAutomationElement, changeType StructureChangeType, runtimeId *ole.SAFEARRAY) syscall.Handle) IUIAutomationStructureChangedEventHandler {
	lpVtbl := &IUIAutomationStructureChangedEventHandlerVtbl{
		IUnknownVtbl: ole.IUnknownVtbl{
			QueryInterface: syscall.NewCallback(structureChangedEventHandler_queryInterface),
			AddRef:         syscall.NewCallback(structureChangedEventHandler_addRef),
			Release:        syscall.NewCallback(structureChangedEventHandler_release),
		},
		HandleStructureChangedEvent: syscall.NewCallback(handlerFunc),
	}
	return IUIAutomationStructureChangedEventHandler{
		IUnknown: ole.IUnknown{RawVTable: (*interface{})(unsafe.Pointer(lpVtbl))},
	}
}
<commit_msg>Make IUIAutomationStructureChangedEventHandler.ref to be private<commit_after>package w32uiautomation

import (
	"fmt"
	"syscall"
	"unsafe"

	"github.com/mattn/go-ole"
)

type StructureChangeType uintptr

const (
	StructureChangeType_ChildAdded = iota
	StructureChangeType_ChildRemoved
	StructureChangeType_ChildrenInvalidated
	StructureChangeType_ChildrenBulkAdded
	StructureChangeType_ChildrenBulkRemoved
	StructureChangeType_ChildrenReordered
)

func (t StructureChangeType) ToString() string {
	switch t {
	case StructureChangeType_ChildAdded:
		return "StructureChangeType_ChildAdded"
	case StructureChangeType_ChildRemoved:
		return "StructureChangeType_ChildRemoved"
	case StructureChangeType_ChildrenInvalidated:
		return "StructureChangeType_ChildrenInvalidated"
	case StructureChangeType_ChildrenBulkAdded:
		return "StructureChangeType_ChildrenBulkAdded"
	case StructureChangeType_ChildrenBulkRemoved:
		return "StructureChangeType_ChildrenBulkRemoved"
	case StructureChangeType_ChildrenReordered:
		return "StructureChangeType_ChildrenReordered"
	default:
		panic(fmt.Errorf("Unknown StructureChangeType: %d", t))
	}
}

type IUIAutomationStructureChangedEventHandler struct {
	ole.IUnknown
	ref int32
}

type IUIAutomationStructureChangedEventHandlerVtbl struct {
	ole.IUnknownVtbl
	HandleStructureChangedEvent uintptr
}

var IID_IUIAutomationStructureChangedEventHandler = &ole.GUID{0xe81d1b4e, 0x11c5, 0x42f8, [8]byte{0x97, 0x54, 0xe7, 0x03, 0x6c, 0x79, 0xf0, 0x54}}

func (h *IUIAutomationStructureChangedEventHandler) VTable() *IUIAutomationStructureChangedEventHandlerVtbl {
	return (*IUIAutomationStructureChangedEventHandlerVtbl)(unsafe.Pointer(h.RawVTable))
}

func structureChangedEventHandler_queryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 {
	*punk = nil
	if ole.IsEqualGUID(iid, ole.IID_IUnknown) ||
		ole.IsEqualGUID(iid, ole.IID_IDispatch) {
		structureChangedEventHandler_addRef(this)
		*punk = this
		return ole.S_OK
	}
	if ole.IsEqualGUID(iid, IID_IUIAutomationStructureChangedEventHandler) {
		structureChangedEventHandler_addRef(this)
		*punk = this
		return ole.S_OK
	}
	return ole.E_NOINTERFACE
}

func structureChangedEventHandler_addRef(this *ole.IUnknown) int32 {
	pthis := (*IUIAutomationStructureChangedEventHandler)(unsafe.Pointer(this))
	pthis.ref++
	return pthis.ref
}

func structureChangedEventHandler_release(this *ole.IUnknown) int32 {
	pthis := (*IUIAutomationStructureChangedEventHandler)(unsafe.Pointer(this))
	pthis.ref--
	return pthis.ref
}

func NewStructureChangedEventHandler(handlerFunc func(this *IUIAutomationStructureChangedEventHandler, sender *IUIAutomationElement, changeType StructureChangeType, runtimeId *ole.SAFEARRAY) syscall.Handle) IUIAutomationStructureChangedEventHandler {
	lpVtbl := &IUIAutomationStructureChangedEventHandlerVtbl{
		IUnknownVtbl: ole.IUnknownVtbl{
			QueryInterface: syscall.NewCallback(structureChangedEventHandler_queryInterface),
			AddRef:         syscall.NewCallback(structureChangedEventHandler_addRef),
			Release:        syscall.NewCallback(structureChangedEventHandler_release),
		},
		HandleStructureChangedEvent: syscall.NewCallback(handlerFunc),
	}
	return IUIAutomationStructureChangedEventHandler{
		IUnknown: ole.IUnknown{RawVTable: (*interface{})(unsafe.Pointer(lpVtbl))},
	}
}
<|endoftext|>


<commit_before>package qingcloud

import (
	"fmt"

	"github.com/hashicorp/terraform/helper/schema"

	qc "github.com/yunify/qingcloud-sdk-go/service"
)

func resourceQingcloudInstance() *schema.Resource {
	return &schema.Resource{
		Create: resourceQingcloudInstanceCreate,
		Read:   resourceQingcloudInstanceRead,
		Update: resourceQingcloudInstanceUpdate,
		Delete: resourceQingcloudInstanceDelete,
		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"image_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"instance_class": &schema.Schema{
				Type:         schema.TypeInt,
				Default:      0,
				Optional:     true,
				ForceNew:     true,
				ValidateFunc: withinArrayInt(0, 1),
			},
			"instance_state": &schema.Schema{
				Type:         schema.TypeString,
				Optional:     true,
				Default:      "running",
				ValidateFunc: withinArrayString("pending", "running", "stopped", "suspended", "terminated", "ceased"),
			},
			"cpu": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
			},
			"memory": &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				ValidateFunc: withinArrayInt(1024, 2048, 4096, 6144, 8192, 12288, 16384, 24576, 32768),
			},
			"vxnet_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"static_ip": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"hostname": &schema.Schema{
				Type:     schema.TypeString,
				ForceNew: true,
				Optional: true,
			},
			"keypair_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Required: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"security_group_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"eip_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"volume_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"volume_device_name": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_ip": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_ip": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"tag_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
		},
	}
}

func resourceQingcloudInstanceCreate(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	input := new(qc.RunInstancesInput)
	input.Count = qc.Int(1)
	input.InstanceName = qc.String(d.Get("name").(string))
	input.ImageID = qc.String(d.Get("image_id").(string))
	input.InstanceClass = qc.Int(d.Get("instance_class").(int))
	// input.InstanceType = qc.String(d.Get("instance_type").(string))
	if d.Get("cpu").(int) != 0 && d.Get("memory").(int) != 0 {
		input.CPU = qc.Int(d.Get("cpu").(int))
		input.Memory = qc.Int(d.Get("memory").(int))
	}
	var vxnet string
	if d.Get("static_ip").(string) != "" {
		vxnet = fmt.Sprintf("%s|%s", d.Get("vxnet_id").(string), d.Get("static_ip").(string))
	} else {
		vxnet = d.Get("vxnet_id").(string)
	}
	input.VxNets = []*string{qc.String(vxnet)}
	if d.Get("security_group_id").(string) != "" {
		input.SecurityGroup = qc.String(d.Get("security_group_id").(string))
	}
	input.LoginMode = qc.String("keypair")
	kps := d.Get("keypair_ids").(*schema.Set).List()
	if len(kps) > 0 {
		kp := kps[0].(string)
		input.LoginKeyPair = qc.String(kp)
	}
	output, err := clt.RunInstances(input)
	if err != nil {
		return err
	}
	d.SetId(qc.StringValue(output.Instances[0]))
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	err = modifyInstanceAttributes(d, meta, true)
	if err != nil {
		return err
	}
	// associate eip to instance
	if eipID := d.Get("eip_id").(string); eipID != "" {
		eipClt := meta.(*QingCloudClient).eip
		if _, err := EIPTransitionStateRefresh(eipClt, eipID); err != nil {
			return err
		}
		associateEIPInput := new(qc.AssociateEIPInput)
		associateEIPInput.EIP = qc.String(eipID)
		associateEIPInput.Instance = qc.String(d.Id())
		associateEIPoutput, err := eipClt.AssociateEIP(associateEIPInput)
		if err != nil {
			return fmt.Errorf("Error associate eip: %s", err)
		}
		if associateEIPoutput.RetCode != nil && qc.IntValue(associateEIPoutput.RetCode) != 0 {
			return fmt.Errorf("Error associate eip: %s", *associateEIPoutput.Message)
		}
		if _, err := EIPTransitionStateRefresh(eipClt, eipID); err != nil {
			return err
		}
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeInstance); err != nil {
		return err
	}

	// update volume
	// volumeDS :=
	return resourceQingcloudInstanceRead(d, meta)
}

func resourceQingcloudInstanceRead(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	input := new(qc.DescribeInstancesInput)
	input.Instances = []*string{qc.String(d.Id())}
	input.Verbose = qc.Int(1)
	output, err := clt.DescribeInstances(input)
	if err != nil {
		return fmt.Errorf("Error describe instance: %s", err)
	}
	if output.RetCode != nil && qc.IntValue(output.RetCode) != 0 {
		return fmt.Errorf("Error describe instance: %s", *output.Message)
	}

	instance := output.InstanceSet[0]
	d.Set("name", qc.StringValue(instance.InstanceName))
	d.Set("image_id", qc.StringValue(instance.Image.ImageID))
	d.Set("description", qc.StringValue(instance.Description))
	d.Set("instance_class", qc.IntValue(instance.InstanceClass))
	d.Set("instance_state", qc.StringValue(instance.Status))
	d.Set("cpu", qc.IntValue(instance.VCPUsCurrent))
	d.Set("memory", qc.IntValue(instance.MemoryCurrent))
	if instance.VxNets != nil && len(instance.VxNets) > 0 {
		vxnet := instance.VxNets[0]
		d.Set("vxnet_id", qc.StringValue(vxnet.VxNetID))
		d.Set("private_ip", qc.StringValue(vxnet.PrivateIP))
		if d.Get("static_ip") != "" {
			d.Set("static_ip", qc.StringValue(vxnet.PrivateIP))
		}
	} else {
		d.Set("vxnet_id", "")
		d.Set("private_ip", "")
	}
	if instance.EIP != nil {
		d.Set("eip_id", qc.StringValue(instance.EIP.EIPID))
		d.Set("public_ip", qc.StringValue(instance.EIP.EIPAddr))
	}
	if instance.SecurityGroup != nil {
		d.Set("security_group_id", qc.StringValue(instance.SecurityGroup.SecurityGroupID))
	}
	if instance.KeyPairIDs != nil {
		keypairIDs := make([]string, 0, len(instance.KeyPairIDs))
		for _, kp := range instance.KeyPairIDs {
			keypairIDs = append(keypairIDs, qc.StringValue(kp))
		}
		d.Set("keypair_ids", keypairIDs)
	}
	resourceSetTag(d, instance.Tags)
	return nil
}

func resourceQingcloudInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
	// clt := meta.(*QingCloudClient).instance
	err := modifyInstanceAttributes(d, meta, false)
	if err != nil {
		return err
	}
	// change vxnet
	err = instanceUpdateChangeVxNet(d, meta)
	if err != nil {
		return err
	}
	// change security_group
	err = instanceUpdateChangeSecurityGroup(d, meta)
	if err != nil {
		return err
	}
	// change eip
	err = instanceUpdateChangeEip(d, meta)
	if err != nil {
		return err
	}
	// change keypair
	err = instanceUpdateChangeKeyPairs(d, meta)
	if err != nil {
		return err
	}
	// resize instance
	err = instanceUpdateResize(d, meta)
	if err != nil {
		return err
	}
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeInstance); err != nil {
		return err
	}
	return resourceQingcloudInstanceRead(d, meta)
}

func resourceQingcloudInstanceDelete(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	// dissociate eip before leave vxnet
	if _, err := deleteInstanceDissociateEip(d, meta); err != nil {
		return err
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	_, err := deleteInstanceLeaveVxnet(d, meta)
	if err != nil {
		return err
	}
	if _, err := InstanceNetworkTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	input := new(qc.TerminateInstancesInput)
	input.Instances = []*string{qc.String(d.Id())}
	output, err := clt.TerminateInstances(input)
	if err != nil {
		return fmt.Errorf("Error terminate instance: %s", err)
	}
	if output.RetCode != nil && qc.IntValue(output.RetCode) != 0 {
		return fmt.Errorf("Error terminate instance: %s", *output.Message)
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	d.SetId("")
	return nil
}
<commit_msg>vxnet-0 support<commit_after>package qingcloud

import (
	"fmt"

	"github.com/hashicorp/terraform/helper/schema"

	qc "github.com/yunify/qingcloud-sdk-go/service"
)

func resourceQingcloudInstance() *schema.Resource {
	return &schema.Resource{
		Create: resourceQingcloudInstanceCreate,
		Read:   resourceQingcloudInstanceRead,
		Update: resourceQingcloudInstanceUpdate,
		Delete: resourceQingcloudInstanceDelete,
		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"image_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"instance_class": &schema.Schema{
				Type:         schema.TypeInt,
				Default:      0,
				Optional:     true,
				ForceNew:     true,
				ValidateFunc: withinArrayInt(0, 1),
			},
			"instance_state": &schema.Schema{
				Type:         schema.TypeString,
				Optional:     true,
				Default:      "running",
				ValidateFunc: withinArrayString("pending", "running", "stopped", "suspended", "terminated", "ceased"),
			},
			"cpu": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
			},
			"memory": &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				ValidateFunc: withinArrayInt(1024, 2048, 4096, 6144, 8192, 12288, 16384, 24576, 32768),
			},
			"vxnet_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"static_ip": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"hostname": &schema.Schema{
				Type:     schema.TypeString,
				ForceNew: true,
				Optional: true,
			},
			"keypair_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Required: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"security_group_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"eip_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"volume_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"volume_device_name": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_ip": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_ip": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"tag_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
		},
	}
}

func resourceQingcloudInstanceCreate(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	input := new(qc.RunInstancesInput)
	input.Count = qc.Int(1)
	input.InstanceName = qc.String(d.Get("name").(string))
	input.ImageID = qc.String(d.Get("image_id").(string))
	input.InstanceClass = qc.Int(d.Get("instance_class").(int))
	// input.InstanceType = qc.String(d.Get("instance_type").(string))
	if d.Get("cpu").(int) != 0 && d.Get("memory").(int) != 0 {
		input.CPU = qc.Int(d.Get("cpu").(int))
		input.Memory = qc.Int(d.Get("memory").(int))
	}
	var vxnet string
	if d.Get("static_ip").(string) != "" {
		vxnet = fmt.Sprintf("%s|%s", d.Get("vxnet_id").(string), d.Get("static_ip").(string))
	} else {
		vxnet = d.Get("vxnet_id").(string)
	}
	input.VxNets = []*string{qc.String(vxnet)}
	if d.Get("security_group_id").(string) != "" {
		input.SecurityGroup = qc.String(d.Get("security_group_id").(string))
	}
	input.LoginMode = qc.String("keypair")
	kps := d.Get("keypair_ids").(*schema.Set).List()
	if len(kps) > 0 {
		kp := kps[0].(string)
		input.LoginKeyPair = qc.String(kp)
	}
	output, err := clt.RunInstances(input)
	if err != nil {
		return err
	}
	d.SetId(qc.StringValue(output.Instances[0]))
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	err = modifyInstanceAttributes(d, meta, true)
	if err != nil {
		return err
	}
	// associate eip to instance
	if eipID := d.Get("eip_id").(string); eipID != "" {
		eipClt := meta.(*QingCloudClient).eip
		if _, err := EIPTransitionStateRefresh(eipClt, eipID); err != nil {
			return err
		}
		associateEIPInput := new(qc.AssociateEIPInput)
		associateEIPInput.EIP = qc.String(eipID)
		associateEIPInput.Instance = qc.String(d.Id())
		associateEIPoutput, err := eipClt.AssociateEIP(associateEIPInput)
		if err != nil {
			return fmt.Errorf("Error associate eip: %s", err)
		}
		if associateEIPoutput.RetCode != nil && qc.IntValue(associateEIPoutput.RetCode) != 0 {
			return fmt.Errorf("Error associate eip: %s", *associateEIPoutput.Message)
		}
		if _, err := EIPTransitionStateRefresh(eipClt, eipID); err != nil {
			return err
		}
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeInstance); err != nil {
		return err
	}

	// update volume
	// volumeDS :=
	return resourceQingcloudInstanceRead(d, meta)
}

func resourceQingcloudInstanceRead(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	input := new(qc.DescribeInstancesInput)
	input.Instances = []*string{qc.String(d.Id())}
	input.Verbose = qc.Int(1)
	output, err := clt.DescribeInstances(input)
	if err != nil {
		return fmt.Errorf("Error describe instance: %s", err)
	}
	if output.RetCode != nil && qc.IntValue(output.RetCode) != 0 {
		return fmt.Errorf("Error describe instance: %s", *output.Message)
	}

	instance := output.InstanceSet[0]
	d.Set("name", qc.StringValue(instance.InstanceName))
	d.Set("image_id", qc.StringValue(instance.Image.ImageID))
	d.Set("description", qc.StringValue(instance.Description))
	d.Set("instance_class", qc.IntValue(instance.InstanceClass))
	d.Set("instance_state", qc.StringValue(instance.Status))
	d.Set("cpu", qc.IntValue(instance.VCPUsCurrent))
	d.Set("memory", qc.IntValue(instance.MemoryCurrent))
	if instance.VxNets != nil && len(instance.VxNets) > 0 {
		vxnet := instance.VxNets[0]
		if qc.IntValue(vxnet.VxNetType) == 2 {
			d.Set("vxnet_id", "vxnet-0")
		} else {
			d.Set("vxnet_id", qc.StringValue(vxnet.VxNetID))
		}
		d.Set("private_ip", qc.StringValue(vxnet.PrivateIP))
		if d.Get("static_ip") != "" {
			d.Set("static_ip", qc.StringValue(vxnet.PrivateIP))
		}
	} else {
		d.Set("vxnet_id", "")
		d.Set("private_ip", "")
	}
	if instance.EIP != nil {
		d.Set("eip_id", qc.StringValue(instance.EIP.EIPID))
		d.Set("public_ip", qc.StringValue(instance.EIP.EIPAddr))
	}
	if instance.SecurityGroup != nil {
		d.Set("security_group_id", qc.StringValue(instance.SecurityGroup.SecurityGroupID))
	}
	if instance.KeyPairIDs != nil {
		keypairIDs := make([]string, 0, len(instance.KeyPairIDs))
		for _, kp := range instance.KeyPairIDs {
			keypairIDs = append(keypairIDs, qc.StringValue(kp))
		}
		d.Set("keypair_ids", keypairIDs)
	}
	resourceSetTag(d, instance.Tags)
	return nil
}

func resourceQingcloudInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
	// clt := meta.(*QingCloudClient).instance
	err := modifyInstanceAttributes(d, meta, false)
	if err != nil {
		return err
	}
	// change vxnet
	err = instanceUpdateChangeVxNet(d, meta)
	if err != nil {
		return err
	}
	// change security_group
	err = instanceUpdateChangeSecurityGroup(d, meta)
	if err != nil {
		return err
	}
	// change eip
	err = instanceUpdateChangeEip(d, meta)
	if err != nil {
		return err
	}
	// change keypair
	err = instanceUpdateChangeKeyPairs(d, meta)
	if err != nil {
		return err
	}
	// resize instance
	err = instanceUpdateResize(d, meta)
	if err != nil {
		return err
	}
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeInstance); err != nil {
		return err
	}
	return resourceQingcloudInstanceRead(d, meta)
}

func resourceQingcloudInstanceDelete(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).instance
	// dissociate eip before leave vxnet
	if _, err := deleteInstanceDissociateEip(d, meta); err != nil {
		return err
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	_, err := deleteInstanceLeaveVxnet(d, meta)
	if err != nil {
		return err
	}
	if _, err := InstanceNetworkTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	input := new(qc.TerminateInstancesInput)
	input.Instances = []*string{qc.String(d.Id())}
	output, err := clt.TerminateInstances(input)
	if err != nil {
		return fmt.Errorf("Error terminate instance: %s", err)
	}
	if output.RetCode != nil && qc.IntValue(output.RetCode) != 0 {
		return fmt.Errorf("Error terminate instance: %s", *output.Message)
	}
	if _, err := InstanceTransitionStateRefresh(clt, d.Id()); err != nil {
		return err
	}
	d.SetId("")
	return nil
}
<|endoftext|>


<commit_before>package config

import (
	"bytes"
	"fmt"
	"os"

	"github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	"github.com/sirupsen/logrus"
)

var (
	// Formatter is the format configuration to write logs into text
	Formatter = logrus.TextFormatter{
		DisableTimestamp: false,
	}

	// TestLogWriter is a buffer in which all logs generated by a test are
	// stored
	TestLogWriter bytes.Buffer
	// TestLogFileName is the file name to dump `TestLogWriter` content when
	// test finish
	TestLogFileName = "logs"
)

// TestLogWriterReset resets the current buffer
func TestLogWriterReset() {
	TestLogWriter.Reset()
}

// LogHook to send logs via `ginkgo.GinkgoWriter`.
type LogHook struct{}

// Levels defined levels to send logs to FireAction
func (h *LogHook) Levels() []logrus.Level {
	if config.DefaultReporterConfig.Verbose {
		return logrus.AllLevels
	}

	return []logrus.Level{
		logrus.WarnLevel,
		logrus.ErrorLevel,
		logrus.FatalLevel,
		logrus.PanicLevel,
	}
}

// Fire is a callback function used by logrus to write logs that match in
// the given by `Levels` method
func (h *LogHook) Fire(entry *logrus.Entry) (err error) {
	line, err := Formatter.Format(entry)
	if err == nil {
		fmt.Fprintf(ginkgo.GinkgoWriter, string(line))
	} else {
		fmt.Fprintf(os.Stderr, "LogHook.Fire: unable to format log entry (%v)", err)
	}
	return
}
<commit_msg>test/config: rename file to which test output is saved<commit_after>package config

import (
	"bytes"
	"fmt"
	"os"

	"github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	"github.com/sirupsen/logrus"
)

var (
	// Formatter is the format configuration to write logs into text
	Formatter = logrus.TextFormatter{
		DisableTimestamp: false,
	}

	// TestLogWriter is a buffer in which all logs generated by a test are
	// stored
	TestLogWriter bytes.Buffer
	// TestLogFileName is the file name to dump `TestLogWriter` content when
	// test finish
	TestLogFileName = "test-output.log"
)

// TestLogWriterReset resets the current buffer
func TestLogWriterReset() {
	TestLogWriter.Reset()
}

// LogHook to send logs via `ginkgo.GinkgoWriter`.
type LogHook struct{}

// Levels defined levels to send logs to FireAction
func (h *LogHook) Levels() []logrus.Level {
	if config.DefaultReporterConfig.Verbose {
		return logrus.AllLevels
	}

	return []logrus.Level{
		logrus.WarnLevel,
		logrus.ErrorLevel,
		logrus.FatalLevel,
		logrus.PanicLevel,
	}
}

// Fire is a callback function used by logrus to write logs that match in
// the given by `Levels` method
func (h *LogHook) Fire(entry *logrus.Entry) (err error) {
	line, err := Formatter.Format(entry)
	if err == nil {
		fmt.Fprintf(ginkgo.GinkgoWriter, string(line))
	} else {
		fmt.Fprintf(os.Stderr, "LogHook.Fire: unable to format log entry (%v)", err)
	}
	return
}
<|endoftext|>


<commit_before>package net

import (
	"net"
	"testing"
)

func TestListen(t *testing.T) {
	fn := func(addr string) (net.Listener, error) {
		return net.Listen("tcp", addr)
	}

	// try to create a number of listeners
	for i := 0; i < 10; i++ {
		l, err := Listen("localhost:10000-11000", fn)
		if err != nil {
			t.Fatal(err)
		}
		defer l.Close()
	}

	// TODO nats case test
	// natsAddr := "_INBOX.bID2CMRvlNp0vt4tgNBHWf"
	// Expect addr DO NOT has extra ":" at the end!

}
<commit_msg>Add proxy env test (#1569)<commit_after>package net

import (
	"net"
	"os"
	"testing"
)

func TestListen(t *testing.T) {
	fn := func(addr string) (net.Listener, error) {
		return net.Listen("tcp", addr)
	}

	// try to create a number of listeners
	for i := 0; i < 10; i++ {
		l, err := Listen("localhost:10000-11000", fn)
		if err != nil {
			t.Fatal(err)
		}
		defer l.Close()
	}

	// TODO nats case test
	// natsAddr := "_INBOX.bID2CMRvlNp0vt4tgNBHWf"
	// Expect addr DO NOT has extra ":" at the end!

}

// TestProxyEnv checks whether we have proxy/network settings in env
func TestProxyEnv(t *testing.T) {
	service := "foo"
	address := []string{"bar"}

	s, a, ok := Proxy(service, address)
	if ok {
		t.Fatal("Should not have proxy", s, a, ok)
	}

	test := func(key, val, expectSrv, expectAddr string) {
		// set env
		os.Setenv(key, val)

		s, a, ok := Proxy(service, address)
		if !ok {
			t.Fatal("Expected proxy")
		}
		if len(expectSrv) > 0 && s != expectSrv {
			t.Fatal("Expected proxy service", expectSrv, "got", s)
		}
		if len(expectAddr) > 0 {
			if len(a) == 0 || a[0] != expectAddr {
				t.Fatal("Expected proxy address", expectAddr, "got", a)
			}
		}

		os.Unsetenv(key)
	}

	test("MICRO_PROXY", "service", "go.micro.proxy", "")
	test("MICRO_PROXY_ADDRESS", "10.0.0.1:8080", "", "10.0.0.1:8080")
	test("MICRO_NETWORK", "service", "go.micro.network", "")
	test("MICRO_NETWORK_ADDRESS", "10.0.0.1:8081", "", "10.0.0.1:8081")
}
<|endoftext|>


<commit_before>package isolated

import (
	"fmt"
	"net/http"
	"os/exec"
	"strings"

	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("Logs Command", func() {
	Describe("help", func() {
		It("displays command usage to output", func() {
			session := helpers.CF("logs", "--help")
			Eventually(session).Should(Say("NAME:"))
			Eventually(session).Should(Say("logs - Tail or show recent logs for an app"))
			Eventually(session).Should(Say("USAGE:"))
			Eventually(session).Should(Say("cf logs APP_NAME"))
			Eventually(session).Should(Say("OPTIONS:"))
			Eventually(session).Should(Say(`--recent\s+Dump recent logs instead of tailing`))
			Eventually(session).Should(Say("SEE ALSO:"))
			Eventually(session).Should(Say("app, apps, ssh"))
			Eventually(session).Should(Exit(0))
		})
	})

	When("not authenticated and not targeting an org or space", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "logs", "app-name")
		})
	})

	When("authenticated and targeting an org and space", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()
			helpers.SetupCF(orgName, spaceName)
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		When("input is invalid", func() {
			Context("because no app name is provided", func() {
				It("gives an incorrect usage message", func() {
					session := helpers.CF("logs")
					Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
					Eventually(session).Should(Say("NAME:"))
					Eventually(session).Should(Say("logs - Tail or show recent logs for an app"))
					Eventually(session).Should(Say("USAGE:"))
					Eventually(session).Should(Say("cf logs APP_NAME"))
					Eventually(session).Should(Say("OPTIONS:"))
					Eventually(session).Should(Say(`--recent\s+Dump recent logs instead of tailing`))
					Eventually(session).Should(Say("SEE ALSO:"))
					Eventually(session).Should(Say("app, apps, ssh"))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("because the app does not exist", func() {
				It("fails with an app not found message", func() {
					session := helpers.CF("logs", "dora")
					Eventually(session).Should(Say("FAILED"))
					Eventually(session.Err).Should(Say("App 'dora' not found"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		When("the specified app exists", func() {
			var appName string

			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				helpers.WithHelloWorldApp(func(appDir string) {
					Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-u", "http")).Should(Exit(0))
				})
			})

			Context("without the --recent flag", func() {
				It("streams logs out to the screen", func() {
					session := helpers.CF("logs", appName)
					defer session.Terminate()

					userName, _ := helpers.GetCredentials()
					Eventually(session).Should(Say("Retrieving logs for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName))

					response, err := http.Get(fmt.Sprintf("http://%s.%s", appName, helpers.DefaultSharedDomain()))
					Expect(err).NotTo(HaveOccurred())
					Expect(response.StatusCode).To(Equal(http.StatusOK))
					Eventually(session).Should(Say(`%s \[APP/PROC/WEB/0\]\s+OUT .*? \"GET / HTTP/1.1\" 200 \d+`, helpers.ISO8601Regex))
				})
			})

			Context("with the --recent flag", func() {
				It("displays the most recent logs and closes the stream", func() {
					session := helpers.CF("logs", appName, "--recent")
					userName, _ := helpers.GetCredentials()
					Eventually(session).Should(Say("Retrieving logs for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName))
					Eventually(session).Should(Say(`%s \[API/\d+\]\s+OUT Created app with guid %s`, helpers.ISO8601Regex, helpers.GUIDRegex))
					Eventually(session).Should(Exit(0))
				})

				It("it can get at least 1000 recent log messages", func() {
					route := fmt.Sprintf("%s.%s", appName, helpers.DefaultSharedDomain())
					// 3 lines of logs for each call to curl + a few lines during the push
					for i := 0; i < 333; i += 1 {
						command := exec.Command("curl", "--fail", route)
						session, err := Start(command, GinkgoWriter, GinkgoWriter)
						Expect(err).NotTo(HaveOccurred())
						Eventually(session).Should(Exit(0))
					}

					session := helpers.CF("logs", appName, "--recent")
					Eventually(session).Should(Exit(0))
					output := session.Out.Contents()
					numLinesRead := strings.Count(string(output), "\n")
					Expect(numLinesRead).To(BeNumerically(">=", 1000))
				})
			})
		})
	})
})
<commit_msg>Sleep for 2 seconds before testing recent logs<commit_after>package isolated

import (
	"fmt"
	"net/http"
	"os/exec"
	"strings"
	"time"

	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("Logs Command", func() {
	Describe("help", func() {
		It("displays command usage to output", func() {
			session := helpers.CF("logs", "--help")
			Eventually(session).Should(Say("NAME:"))
			Eventually(session).Should(Say("logs - Tail or show recent logs for an app"))
			Eventually(session).Should(Say("USAGE:"))
			Eventually(session).Should(Say("cf logs APP_NAME"))
			Eventually(session).Should(Say("OPTIONS:"))
			Eventually(session).Should(Say(`--recent\s+Dump recent logs instead of tailing`))
			Eventually(session).Should(Say("SEE ALSO:"))
			Eventually(session).Should(Say("app, apps, ssh"))
			Eventually(session).Should(Exit(0))
		})
	})

	When("not authenticated and not targeting an org or space", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "logs", "app-name")
		})
	})

	When("authenticated and targeting an org and space", func() {
		var (
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()
			helpers.SetupCF(orgName, spaceName)
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		When("input is invalid", func() {
			Context("because no app name is provided", func() {
				It("gives an incorrect usage message", func() {
					session := helpers.CF("logs")
					Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
					Eventually(session).Should(Say("NAME:"))
					Eventually(session).Should(Say("logs - Tail or show recent logs for an app"))
					Eventually(session).Should(Say("USAGE:"))
					Eventually(session).Should(Say("cf logs APP_NAME"))
					Eventually(session).Should(Say("OPTIONS:"))
					Eventually(session).Should(Say(`--recent\s+Dump recent logs instead of tailing`))
					Eventually(session).Should(Say("SEE ALSO:"))
					Eventually(session).Should(Say("app, apps, ssh"))
					Eventually(session).Should(Exit(1))
				})
			})

			Context("because the app does not exist", func() {
				It("fails with an app not found message", func() {
					session := helpers.CF("logs", "dora")
					Eventually(session).Should(Say("FAILED"))
					Eventually(session.Err).Should(Say("App 'dora' not found"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		When("the specified app exists", func() {
			var appName string

			BeforeEach(func() {
				appName = helpers.PrefixedRandomName("app")
				helpers.WithHelloWorldApp(func(appDir string) {
					Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-u", "http")).Should(Exit(0))
				})
			})

			Context("without the --recent flag", func() {
				It("streams logs out to the screen", func() {
					session := helpers.CF("logs", appName)
					defer session.Terminate()

					userName, _ := helpers.GetCredentials()
					Eventually(session).Should(Say("Retrieving logs for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName))

					response, err := http.Get(fmt.Sprintf("http://%s.%s", appName, helpers.DefaultSharedDomain()))
					Expect(err).NotTo(HaveOccurred())
					Expect(response.StatusCode).To(Equal(http.StatusOK))
					Eventually(session).Should(Say(`%s \[APP/PROC/WEB/0\]\s+OUT .*? \"GET / HTTP/1.1\" 200 \d+`, helpers.ISO8601Regex))
				})
			})

			Context("with the --recent flag", func() {
				It("displays the most recent logs and closes the stream", func() {
					session := helpers.CF("logs", appName, "--recent")
					userName, _ := helpers.GetCredentials()
					Eventually(session).Should(Say("Retrieving logs for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName))
					Eventually(session).Should(Say(`%s \[API/\d+\]\s+OUT Created app with guid %s`, helpers.ISO8601Regex, helpers.GUIDRegex))
					Eventually(session).Should(Exit(0))
				})

				It("it can get at least 1000 recent log messages", func() {
					route := fmt.Sprintf("%s.%s", appName, helpers.DefaultSharedDomain())

					// 3 lines of logs for each call to curl + a few lines during the push
					for i := 0; i < 333; i += 1 {
						command := exec.Command("curl", "--fail", route)
						session, err := Start(command, GinkgoWriter, GinkgoWriter)
						Expect(err).NotTo(HaveOccurred())
						Eventually(session).Should(Exit(0))
					}

					// allow multiple log cache nodes time to sychronize
					// otherwise the most recent logs may be missing or out of order
					time.Sleep(2 * time.Second)

					session := helpers.CF("logs", appName, "--recent")
					Eventually(session).Should(Exit(0))
					output := session.Out.Contents()
					numLinesRead := strings.Count(string(output), "\n")
					Expect(numLinesRead).To(BeNumerically(">=", 1000))
				})
			})
		})
	})
})
<|endoftext|>