<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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 top

import (
	"context"
	"errors"

	"github.com/spf13/cobra"
	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/discovery"
	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
	cmdutil "k8s.io/kubectl/pkg/cmd/util"
	"k8s.io/kubectl/pkg/metricsutil"
	"k8s.io/kubectl/pkg/util"
	"k8s.io/kubectl/pkg/util/i18n"
	"k8s.io/kubectl/pkg/util/templates"
	metricsapi "k8s.io/metrics/pkg/apis/metrics"
	metricsV1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
	metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
)

// TopNodeOptions contains all the options for running the top-node cli command.
type TopNodeOptions struct {
	ResourceName       string
	Selector           string
	SortBy             string
	NoHeaders          bool
	UseProtocolBuffers bool

	NodeClient      corev1client.CoreV1Interface
	Printer         *metricsutil.TopCmdPrinter
	DiscoveryClient discovery.DiscoveryInterface
	MetricsClient   metricsclientset.Interface

	genericclioptions.IOStreams
}

var (
	topNodeLong = templates.LongDesc(i18n.T(`
		Display resource (CPU/memory) usage of nodes.

		The top-node command allows you to see the resource consumption of nodes.`))

	topNodeExample = templates.Examples(i18n.T(`
		  # Show metrics for all nodes
		  kubectl top node

		  # Show metrics for a given node
		  kubectl top node NODE_NAME`))
)

func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptions.IOStreams) *cobra.Command {
	if o == nil {
		o = &TopNodeOptions{
			IOStreams:          streams,
			UseProtocolBuffers: true,
		}
	}

	cmd := &cobra.Command{
		Use:                   "node [NAME | -l label]",
		DisableFlagsInUseLine: true,
		Short:                 i18n.T("Display resource (CPU/memory) usage of nodes"),
		Long:                  topNodeLong,
		Example:               topNodeExample,
		ValidArgsFunction:     util.ResourceNameCompletionFunc(f, "node"),
		Run: func(cmd *cobra.Command, args []string) {
			cmdutil.CheckErr(o.Complete(f, cmd, args))
			cmdutil.CheckErr(o.Validate())
			cmdutil.CheckErr(o.RunTopNode())
		},
		Aliases: []string{"nodes", "no"},
	}
	cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
	cmd.Flags().StringVar(&o.SortBy, "sort-by", o.SortBy, "If non-empty, sort nodes list using specified field. The field can be either 'cpu' or 'memory'.")
	cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "If present, print output without headers")
	cmd.Flags().BoolVar(&o.UseProtocolBuffers, "use-protocol-buffers", o.UseProtocolBuffers, "Enables using protocol-buffers to access Metrics API.")

	return cmd
}

func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
	if len(args) == 1 {
		o.ResourceName = args[0]
	} else if len(args) > 1 {
		return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
	}

	clientset, err := f.KubernetesClientSet()
	if err != nil {
		return err
	}

	o.DiscoveryClient = clientset.DiscoveryClient

	config, err := f.ToRESTConfig()
	if err != nil {
		return err
	}
	if o.UseProtocolBuffers {
		config.ContentType = "application/vnd.kubernetes.protobuf"
	}
	o.MetricsClient, err = metricsclientset.NewForConfig(config)
	if err != nil {
		return err
	}

	o.NodeClient = clientset.CoreV1()

	o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
	return nil
}

func (o *TopNodeOptions) Validate() error {
	if len(o.SortBy) > 0 {
		if o.SortBy != sortByCPU && o.SortBy != sortByMemory {
			return errors.New("--sort-by accepts only cpu or memory")
		}
	}
	if len(o.ResourceName) > 0 && len(o.Selector) > 0 {
		return errors.New("only one of NAME or --selector can be provided")
	}
	return nil
}

func (o TopNodeOptions) RunTopNode() error {
	var err error
	selector := labels.Everything()
	if len(o.Selector) > 0 {
		selector, err = labels.Parse(o.Selector)
		if err != nil {
			return err
		}
	}

	apiGroups, err := o.DiscoveryClient.ServerGroups()
	if err != nil {
		return err
	}

	metricsAPIAvailable := SupportedMetricsAPIVersionAvailable(apiGroups)

	if !metricsAPIAvailable {
		return errors.New("Metrics API not available")
	}

	metrics, err := getNodeMetricsFromMetricsAPI(o.MetricsClient, o.ResourceName, selector)
	if err != nil {
		return err
	}

	if len(metrics.Items) == 0 {
		return errors.New("metrics not available yet")
	}

	var nodes []v1.Node
	if len(o.ResourceName) > 0 {
		node, err := o.NodeClient.Nodes().Get(context.TODO(), o.ResourceName, metav1.GetOptions{})
		if err != nil {
			return err
		}
		nodes = append(nodes, *node)
	} else {
		nodeList, err := o.NodeClient.Nodes().List(context.TODO(), metav1.ListOptions{
			LabelSelector: selector.String(),
		})
		if err != nil {
			return err
		}
		nodes = append(nodes, nodeList.Items...)
	}

	allocatable := make(map[string]v1.ResourceList)

	for _, n := range nodes {
		allocatable[n.Name] = n.Status.Allocatable
	}

	return o.Printer.PrintNodeMetrics(metrics.Items, allocatable, o.NoHeaders, o.SortBy)
}

func getNodeMetricsFromMetricsAPI(metricsClient metricsclientset.Interface, resourceName string, selector labels.Selector) (*metricsapi.NodeMetricsList, error) {
	var err error
	versionedMetrics := &metricsV1beta1api.NodeMetricsList{}
	mc := metricsClient.MetricsV1beta1()
	nm := mc.NodeMetricses()
	if resourceName != "" {
		m, err := nm.Get(context.TODO(), resourceName, metav1.GetOptions{})
		if err != nil {
			return nil, err
		}
		versionedMetrics.Items = []metricsV1beta1api.NodeMetrics{*m}
	} else {
		versionedMetrics, err = nm.List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
		if err != nil {
			return nil, err
		}
	}
	metrics := &metricsapi.NodeMetricsList{}
	err = metricsV1beta1api.Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(versionedMetrics, metrics, nil)
	if err != nil {
		return nil, err
	}
	return metrics, nil
}
<commit_msg>Add a flag to enable "Capacity" instead of "Allocatable" for an actual node memory total usage.<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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 top

import (
	"context"
	"errors"

	"github.com/spf13/cobra"
	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/discovery"
	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
	cmdutil "k8s.io/kubectl/pkg/cmd/util"
	"k8s.io/kubectl/pkg/metricsutil"
	"k8s.io/kubectl/pkg/util"
	"k8s.io/kubectl/pkg/util/i18n"
	"k8s.io/kubectl/pkg/util/templates"
	metricsapi "k8s.io/metrics/pkg/apis/metrics"
	metricsV1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
	metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
)

// TopNodeOptions contains all the options for running the top-node cli command.
type TopNodeOptions struct {
	ResourceName       string
	Selector           string
	SortBy             string
	NoHeaders          bool
	UseProtocolBuffers bool
	ShowCapacity       bool

	NodeClient      corev1client.CoreV1Interface
	Printer         *metricsutil.TopCmdPrinter
	DiscoveryClient discovery.DiscoveryInterface
	MetricsClient   metricsclientset.Interface

	genericclioptions.IOStreams
}

var (
	topNodeLong = templates.LongDesc(i18n.T(`
		Display resource (CPU/memory) usage of nodes.

		The top-node command allows you to see the resource consumption of nodes.`))

	topNodeExample = templates.Examples(i18n.T(`
		  # Show metrics for all nodes
		  kubectl top node

		  # Show metrics for a given node
		  kubectl top node NODE_NAME`))
)

func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptions.IOStreams) *cobra.Command {
	if o == nil {
		o = &TopNodeOptions{
			IOStreams:          streams,
			UseProtocolBuffers: true,
		}
	}

	cmd := &cobra.Command{
		Use:                   "node [NAME | -l label]",
		DisableFlagsInUseLine: true,
		Short:                 i18n.T("Display resource (CPU/memory) usage of nodes"),
		Long:                  topNodeLong,
		Example:               topNodeExample,
		ValidArgsFunction:     util.ResourceNameCompletionFunc(f, "node"),
		Run: func(cmd *cobra.Command, args []string) {
			cmdutil.CheckErr(o.Complete(f, cmd, args))
			cmdutil.CheckErr(o.Validate())
			cmdutil.CheckErr(o.RunTopNode())
		},
		Aliases: []string{"nodes", "no"},
	}
	cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
	cmd.Flags().StringVar(&o.SortBy, "sort-by", o.SortBy, "If non-empty, sort nodes list using specified field. The field can be either 'cpu' or 'memory'.")
	cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "If present, print output without headers")
	cmd.Flags().BoolVar(&o.UseProtocolBuffers, "use-protocol-buffers", o.UseProtocolBuffers, "Enables using protocol-buffers to access Metrics API.")
	cmd.Flags().BoolVar(&o.ShowCapacity, "show-capacity", o.ShowCapacity, "Print node resources based on Capacity instead of Allocatable(default) of the nodes.")

	return cmd
}

func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
	if len(args) == 1 {
		o.ResourceName = args[0]
	} else if len(args) > 1 {
		return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
	}

	clientset, err := f.KubernetesClientSet()
	if err != nil {
		return err
	}

	o.DiscoveryClient = clientset.DiscoveryClient

	config, err := f.ToRESTConfig()
	if err != nil {
		return err
	}
	if o.UseProtocolBuffers {
		config.ContentType = "application/vnd.kubernetes.protobuf"
	}
	o.MetricsClient, err = metricsclientset.NewForConfig(config)
	if err != nil {
		return err
	}

	o.NodeClient = clientset.CoreV1()

	o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
	return nil
}

func (o *TopNodeOptions) Validate() error {
	if len(o.SortBy) > 0 {
		if o.SortBy != sortByCPU && o.SortBy != sortByMemory {
			return errors.New("--sort-by accepts only cpu or memory")
		}
	}
	if len(o.ResourceName) > 0 && len(o.Selector) > 0 {
		return errors.New("only one of NAME or --selector can be provided")
	}
	return nil
}

func (o TopNodeOptions) RunTopNode() error {
	var err error
	selector := labels.Everything()
	if len(o.Selector) > 0 {
		selector, err = labels.Parse(o.Selector)
		if err != nil {
			return err
		}
	}

	apiGroups, err := o.DiscoveryClient.ServerGroups()
	if err != nil {
		return err
	}

	metricsAPIAvailable := SupportedMetricsAPIVersionAvailable(apiGroups)

	if !metricsAPIAvailable {
		return errors.New("Metrics API not available")
	}

	metrics, err := getNodeMetricsFromMetricsAPI(o.MetricsClient, o.ResourceName, selector)
	if err != nil {
		return err
	}

	if len(metrics.Items) == 0 {
		return errors.New("metrics not available yet")
	}

	var nodes []v1.Node
	if len(o.ResourceName) > 0 {
		node, err := o.NodeClient.Nodes().Get(context.TODO(), o.ResourceName, metav1.GetOptions{})
		if err != nil {
			return err
		}
		nodes = append(nodes, *node)
	} else {
		nodeList, err := o.NodeClient.Nodes().List(context.TODO(), metav1.ListOptions{
			LabelSelector: selector.String(),
		})
		if err != nil {
			return err
		}
		nodes = append(nodes, nodeList.Items...)
	}

	availableResources := make(map[string]v1.ResourceList)

	for _, n := range nodes {
		if !o.ShowCapacity {
			availableResources[n.Name] = n.Status.Allocatable
		} else {
			availableResources[n.Name] = n.Status.Capacity
		}
	}

	return o.Printer.PrintNodeMetrics(metrics.Items, availableResources, o.NoHeaders, o.SortBy)
}

func getNodeMetricsFromMetricsAPI(metricsClient metricsclientset.Interface, resourceName string, selector labels.Selector) (*metricsapi.NodeMetricsList, error) {
	var err error
	versionedMetrics := &metricsV1beta1api.NodeMetricsList{}
	mc := metricsClient.MetricsV1beta1()
	nm := mc.NodeMetricses()
	if resourceName != "" {
		m, err := nm.Get(context.TODO(), resourceName, metav1.GetOptions{})
		if err != nil {
			return nil, err
		}
		versionedMetrics.Items = []metricsV1beta1api.NodeMetrics{*m}
	} else {
		versionedMetrics, err = nm.List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
		if err != nil {
			return nil, err
		}
	}
	metrics := &metricsapi.NodeMetricsList{}
	err = metricsV1beta1api.Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(versionedMetrics, metrics, nil)
	if err != nil {
		return nil, err
	}
	return metrics, nil
}
<|endoftext|>


<commit_before>package object

import (
	"fmt"
	"reflect"
)

type (
	// TypeHint are the hints of a member's type
	TypeHint string
)

// String implements the Stringer interface
func (t TypeHint) String() string {
	return string(t)
}

const (
	HintUndefined TypeHint = ""
	HintObject    TypeHint = "o"
	HintArray     TypeHint = "a"
	HintBool      TypeHint = "b"
	HintData      TypeHint = "d"
	HintFloat     TypeHint = "f"
	HintInt       TypeHint = "i"
	HintNil       TypeHint = "n"
	HintString    TypeHint = "s"
	HintUint      TypeHint = "u"
)

var (
	hints = map[string]TypeHint{
		"":  HintUndefined,
		"o": HintObject,
		"a": HintArray,
		"b": HintBool,
		"d": HintData,
		"f": HintFloat,
		"i": HintInt,
		"n": HintNil,
		"s": HintString,
		"u": HintUint,
	}
)

// GetTypeHint returns a TypeHint from a string
func GetTypeHint(t string) TypeHint {
	if t, ok := hints[t]; ok {
		return t
	}
	return HintUndefined
}

// DeduceTypeHint returns a TypeHint from a given value
func DeduceTypeHint(o interface{}) TypeHint {
	t := reflect.TypeOf(o)

	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	switch t.Kind() {
	case reflect.Slice, reflect.Array:
		if t.Elem() == reflect.TypeOf(byte(0)) {
			return HintData
		}
		// TODO(geoah) add support for A<A<*>>
		// eg {"foo:A<A<i>>:" [["1", "2"], ["3", "4"]]} should be A<A<i>>
		sv := reflect.New(t.Elem()).Elem().Interface()
		if sv == nil {
			oo := o.([]interface{})
			if len(oo) > 0 {
				sv = oo[0]
			}
		}
		if sv != nil {
			subType := DeduceTypeHint(sv)
			return HintArray + "<" + subType + ">"
		}
		return HintArray + "<?>" // TODO(geoah) should this return "" or panic maybe?

	case reflect.String:
		return HintString

	case reflect.Map,
		reflect.Struct:
		return HintObject

	case reflect.Float32, reflect.Float64:
		return HintFloat

	case reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64:
		return HintInt

	case reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64:
		return HintUint

	case reflect.Bool:
		return HintBool
	}

	fmt.Println("___________ COULD NOT DEDUCE", o) // TODO LOG

	return HintUndefined
}
<commit_msg>Remove debug fmt<commit_after>package object

import (
	"reflect"
)

type (
	// TypeHint are the hints of a member's type
	TypeHint string
)

// String implements the Stringer interface
func (t TypeHint) String() string {
	return string(t)
}

const (
	HintUndefined TypeHint = ""
	HintObject    TypeHint = "o"
	HintArray     TypeHint = "a"
	HintBool      TypeHint = "b"
	HintData      TypeHint = "d"
	HintFloat     TypeHint = "f"
	HintInt       TypeHint = "i"
	HintNil       TypeHint = "n"
	HintString    TypeHint = "s"
	HintUint      TypeHint = "u"
)

var (
	hints = map[string]TypeHint{
		"":  HintUndefined,
		"o": HintObject,
		"a": HintArray,
		"b": HintBool,
		"d": HintData,
		"f": HintFloat,
		"i": HintInt,
		"n": HintNil,
		"s": HintString,
		"u": HintUint,
	}
)

// GetTypeHint returns a TypeHint from a string
func GetTypeHint(t string) TypeHint {
	if t, ok := hints[t]; ok {
		return t
	}
	return HintUndefined
}

// DeduceTypeHint returns a TypeHint from a given value
func DeduceTypeHint(o interface{}) TypeHint {
	t := reflect.TypeOf(o)

	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	switch t.Kind() {
	case reflect.Slice, reflect.Array:
		if t.Elem() == reflect.TypeOf(byte(0)) {
			return HintData
		}
		// TODO(geoah) add support for A<A<*>>
		// eg {"foo:A<A<i>>:" [["1", "2"], ["3", "4"]]} should be A<A<i>>
		sv := reflect.New(t.Elem()).Elem().Interface()
		if sv == nil {
			oo := o.([]interface{})
			if len(oo) > 0 {
				sv = oo[0]
			}
		}
		if sv != nil {
			subType := DeduceTypeHint(sv)
			return HintArray + "<" + subType + ">"
		}
		return HintArray + "<?>" // TODO(geoah) should this return "" or panic maybe?

	case reflect.String:
		return HintString

	case reflect.Map,
		reflect.Struct:
		return HintObject

	case reflect.Float32, reflect.Float64:
		return HintFloat

	case reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64:
		return HintInt

	case reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64:
		return HintUint

	case reflect.Bool:
		return HintBool
	}

	return HintUndefined
}
<|endoftext|>


<commit_before>package peer

import (
	"time"

	"nimona.io/pkg/crypto"
	"nimona.io/pkg/object"
)

func NewCertificate(
	subject crypto.PublicKey,
	issuer crypto.PrivateKey,
) Certificate {
	c := Certificate{
		Created: time.Now().Format(time.RFC3339),
		Expires: time.Now().Add(time.Hour * 24 * 365).Format(time.RFC3339),
	}
	s, _ := object.NewSignature(issuer, c.ToObject())
	c.Signatures = append(c.Signatures, s)
	return c
}

func NewSelfSignedCertificate(k crypto.PrivateKey) Certificate {
	return NewCertificate(k.PublicKey(), k)
}
<commit_msg>fix(peer): certificate missing policy<commit_after>package peer

import (
	"time"

	"nimona.io/pkg/crypto"
	"nimona.io/pkg/object"
)

func NewCertificate(
	subject crypto.PublicKey,
	issuer crypto.PrivateKey,
) Certificate {
	c := Certificate{
		Policy: object.Policy{
			Subjects: []string{
				subject.String(),
			},
		},
		Created: time.Now().Format(time.RFC3339),
		Expires: time.Now().Add(time.Hour * 24 * 365).Format(time.RFC3339),
	}
	s, _ := object.NewSignature(issuer, c.ToObject())
	c.Signatures = append(c.Signatures, s)
	return c
}

func NewSelfSignedCertificate(k crypto.PrivateKey) Certificate {
	return NewCertificate(k.PublicKey(), k)
}
<|endoftext|>


<commit_before>package settings

import (
	"encoding/json"

	"github.com/rancher/types/apis/management.cattle.io/v3"
)

var (
	settings = map[string]Setting{}
	provider Provider

	AgentImage                      = newSetting("agent-image", "rancher/rancher-agent:master")
	CACerts                         = newSetting("cacerts", "")
	CLIURLDarwin                    = newSetting("cli-url-darwin", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-darwin-amd64-v1.0.0-alpha8.tar.gz")
	CLIURLLinux                     = newSetting("cli-url-linux", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-linux-amd64-v1.0.0-alpha8.tar.gz")
	CLIURLWindows                   = newSetting("cli-url-windows", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-windows-386-v1.0.0-alpha8.zip")
	EngineInstallURL                = newSetting("engine-install-url", "https://releases.rancher.com/install-docker/17.03.sh")
	EngineISOURL                    = newSetting("engine-iso-url", "https://github.com/boot2docker/boot2docker/releases/download/v17.03.2-ce/boot2docker.iso")
	EngineNewestVersion             = newSetting("engine-newest-version", "v17.12.0")
	EngineSupportedRange            = newSetting("engine-supported-range", "~v1.11.2 || ~v1.12.0 || ~v1.13.0 || ~v17.03.0")
	FirstLogin                      = newSetting("first-login", "true")
	HelmVersion                     = newSetting("helm-version", "dev")
	IngressIPDomain                 = newSetting("ingress-ip-domain", "xip.io")
	InstallUUID                     = newSetting("install-uuid", "")
	KubernetesVersion               = newSetting("k8s-version", v3.DefaultK8s)
	KubernetesVersionToSystemImages = newSetting("k8s-version-to-images", getSystemImages())
	MachineVersion                  = newSetting("machine-version", "dev")
	ServerImage                     = newSetting("server-image", "rancher/rancher")
	ServerURL                       = newSetting("server-url", "")
	ServerVersion                   = newSetting("server-version", "dev")
	SystemDefaultRegistry           = newSetting("system-default-registry", "")
	SystemNamespaces                = newSetting("system-namespaces", "kube-system,kube-public,cattle-system,cattle-alerting,cattle-logging,cattle-pipeline")
	TelemetryOpt                    = newSetting("telemetry-opt", "")
	UIFeedBackForm                  = newSetting("ui-feedback-form", "")
	UIIndex                         = newSetting("ui-index", "https://releases.rancher.com/ui/latest2/index.html")
	UIPath                          = newSetting("ui-path", "")
	UIPL                            = newSetting("ui-pl", "rancher")
	WhitelistDomain                 = newSetting("whitelist-domain", "forums.rancher.com")
	RDNSServerBaseURL               = newSetting("rdns-base-url", "https://api.lb.rancher.cloud/v1")
)

type Provider interface {
	Get(name string) string
	Set(name, value string) error
	SetIfUnset(name, value string) error
	SetAll(settings map[string]Setting) error
}

type Setting struct {
	Name     string
	Default  string
	ReadOnly bool
}

func (s Setting) SetIfUnset(value string) error {
	if provider == nil {
		return s.Set(value)
	}
	return provider.SetIfUnset(s.Name, value)
}

func (s Setting) Set(value string) error {
	if provider == nil {
		s, ok := settings[s.Name]
		if ok {
			s.Default = value
			settings[s.Name] = s
		}
	} else {
		return provider.Set(s.Name, value)
	}
	return nil
}

func (s Setting) Get() string {
	if provider == nil {
		s := settings[s.Name]
		return s.Default
	}
	return provider.Get(s.Name)
}

func SetProvider(p Provider) error {
	if err := p.SetAll(settings); err != nil {
		return err
	}
	provider = p
	return nil
}

func newSetting(name, def string) Setting {
	s := Setting{
		Name:    name,
		Default: def,
	}
	settings[s.Name] = s
	return s
}

func getSystemImages() string {
	versionToSystemImages := v3.K8sVersionToRKESystemImages

	data, err := json.Marshal(versionToSystemImages)
	if err != nil {
		return ""
	}
	return string(data)
}
<commit_msg>vSphere, using RancherOS as default instead of boot2docker<commit_after>package settings

import (
	"encoding/json"

	"github.com/rancher/types/apis/management.cattle.io/v3"
)

var (
	settings = map[string]Setting{}
	provider Provider

	AgentImage                      = newSetting("agent-image", "rancher/rancher-agent:master")
	CACerts                         = newSetting("cacerts", "")
	CLIURLDarwin                    = newSetting("cli-url-darwin", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-darwin-amd64-v1.0.0-alpha8.tar.gz")
	CLIURLLinux                     = newSetting("cli-url-linux", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-linux-amd64-v1.0.0-alpha8.tar.gz")
	CLIURLWindows                   = newSetting("cli-url-windows", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-windows-386-v1.0.0-alpha8.zip")
	EngineInstallURL                = newSetting("engine-install-url", "https://releases.rancher.com/install-docker/17.03.sh")
	EngineISOURL                    = newSetting("engine-iso-url", "https://releases.rancher.com/os/latest/rancheros-vmware.iso")
	EngineNewestVersion             = newSetting("engine-newest-version", "v17.12.0")
	EngineSupportedRange            = newSetting("engine-supported-range", "~v1.11.2 || ~v1.12.0 || ~v1.13.0 || ~v17.03.0")
	FirstLogin                      = newSetting("first-login", "true")
	HelmVersion                     = newSetting("helm-version", "dev")
	IngressIPDomain                 = newSetting("ingress-ip-domain", "xip.io")
	InstallUUID                     = newSetting("install-uuid", "")
	KubernetesVersion               = newSetting("k8s-version", v3.DefaultK8s)
	KubernetesVersionToSystemImages = newSetting("k8s-version-to-images", getSystemImages())
	MachineVersion                  = newSetting("machine-version", "dev")
	ServerImage                     = newSetting("server-image", "rancher/rancher")
	ServerURL                       = newSetting("server-url", "")
	ServerVersion                   = newSetting("server-version", "dev")
	SystemDefaultRegistry           = newSetting("system-default-registry", "")
	SystemNamespaces                = newSetting("system-namespaces", "kube-system,kube-public,cattle-system,cattle-alerting,cattle-logging,cattle-pipeline")
	TelemetryOpt                    = newSetting("telemetry-opt", "")
	UIFeedBackForm                  = newSetting("ui-feedback-form", "")
	UIIndex                         = newSetting("ui-index", "https://releases.rancher.com/ui/latest2/index.html")
	UIPath                          = newSetting("ui-path", "")
	UIPL                            = newSetting("ui-pl", "rancher")
	WhitelistDomain                 = newSetting("whitelist-domain", "forums.rancher.com")
	RDNSServerBaseURL               = newSetting("rdns-base-url", "https://api.lb.rancher.cloud/v1")
)

type Provider interface {
	Get(name string) string
	Set(name, value string) error
	SetIfUnset(name, value string) error
	SetAll(settings map[string]Setting) error
}

type Setting struct {
	Name     string
	Default  string
	ReadOnly bool
}

func (s Setting) SetIfUnset(value string) error {
	if provider == nil {
		return s.Set(value)
	}
	return provider.SetIfUnset(s.Name, value)
}

func (s Setting) Set(value string) error {
	if provider == nil {
		s, ok := settings[s.Name]
		if ok {
			s.Default = value
			settings[s.Name] = s
		}
	} else {
		return provider.Set(s.Name, value)
	}
	return nil
}

func (s Setting) Get() string {
	if provider == nil {
		s := settings[s.Name]
		return s.Default
	}
	return provider.Get(s.Name)
}

func SetProvider(p Provider) error {
	if err := p.SetAll(settings); err != nil {
		return err
	}
	provider = p
	return nil
}

func newSetting(name, def string) Setting {
	s := Setting{
		Name:    name,
		Default: def,
	}
	settings[s.Name] = s
	return s
}

func getSystemImages() string {
	versionToSystemImages := v3.K8sVersionToRKESystemImages

	data, err := json.Marshal(versionToSystemImages)
	if err != nil {
		return ""
	}
	return string(data)
}
<|endoftext|>


<commit_before>package dcpu

import (
	"fmt"
	"unsafe"
)

type Word uint16

type ProtectionError struct {
	Address            Word
	Opcode             Word
	OperandA, OperandB Word
}

func (err *ProtectionError) Error() string {
	return fmt.Sprintf("protection violation at address %#x (instruction %#04x, operands %#x, %#x)",
		err.Address, err.Opcode, err.OperandA, err.OperandB)
}

type OpcodeError struct {
	Opcode Word
}

func (err *OpcodeError) Error() string {
	return fmt.Sprintf("invalid opcode %#04x", err.Opcode)
}

type Registers struct {
	A, B, C, X, Y, Z, I, J Word
	PC                     Word
	SP                     Word
	O                      Word
}

type Region struct {
	Start  Word
	Length Word
}

func (r Region) Contains(address Word) bool {
	return address >= r.Start && address < r.Start+r.Length
}

// End() returns the first address not contained in the region
func (r Region) End() Word {
	return r.Start + r.Length
}

func (r Region) Union(r2 Region) Region {
	var reg Region
	if r2.Start < r.Start {
		reg.Start = r2.Start
	} else {
		reg.Start = r.Start
	}
	if r2.End() > r.End() {
		reg.Length = r2.End() - reg.Start
	} else {
		reg.Length = r.End() - reg.Start
	}
	return reg
}

type State struct {
	Registers
	Ram       [0x10000]Word
	Protected []Region
}

func decodeOpcode(opcode Word) (oooo, aaaaaa, bbbbbb Word) {
	oooo = opcode & 0xF
	aaaaaa = (opcode >> 4) & 0x3F
	bbbbbb = (opcode >> 10) & 0x3F
	return
}

// wordCount counts the number of words in the instruction identified by the given opcode
func wordCount(opcode Word) Word {
	_, a, b := decodeOpcode(opcode)
	count := Word(1)
	switch {
	case a >= 16 && a <= 23:
	case a == 30:
	case a == 31:
		count++
	}
	switch {
	case b >= 16 && b <= 23:
	case b == 30:
	case b == 31:
		count++
	}
	return count
}

func (s *State) translateOperand(op Word) (val Word, assignable *Word) {
	switch op {
	// 0-7: register value - register values
	case 0:
		assignable = &s.A
	case 1:
		assignable = &s.B
	case 2:
		assignable = &s.C
	case 3:
		assignable = &s.X
	case 4:
		assignable = &s.Y
	case 5:
		assignable = &s.Z
	case 6:
		assignable = &s.I
	case 7:
		assignable = &s.J
	// 8-15: [register value] - value at address in registries
	case 8:
		assignable = &s.Ram[s.A]
	case 9:
		assignable = &s.Ram[s.B]
	case 10:
		assignable = &s.Ram[s.C]
	case 11:
		assignable = &s.Ram[s.X]
	case 12:
		assignable = &s.Ram[s.Y]
	case 13:
		assignable = &s.Ram[s.Z]
	case 14:
		assignable = &s.Ram[s.I]
	case 15:
		assignable = &s.Ram[s.J]
	// 16-23: [next word of ram + register value] - memory address offset by register value
	case 16:
		assignable = &s.Ram[s.Ram[s.PC]+s.A]
		s.PC++
	case 17:
		assignable = &s.Ram[s.Ram[s.PC]+s.B]
		s.PC++
	case 18:
		assignable = &s.Ram[s.Ram[s.PC]+s.C]
		s.PC++
	case 19:
		assignable = &s.Ram[s.Ram[s.PC]+s.X]
		s.PC++
	case 20:
		assignable = &s.Ram[s.Ram[s.PC]+s.Y]
		s.PC++
	case 21:
		assignable = &s.Ram[s.Ram[s.PC]+s.Z]
		s.PC++
	case 22:
		assignable = &s.Ram[s.Ram[s.PC]+s.I]
		s.PC++
	case 23:
		assignable = &s.Ram[s.Ram[s.PC]+s.J]
		s.PC++
	// 24: POP - value at stack address, then increases stack counter
	case 24:
		assignable = &s.Ram[s.SP]
		s.SP++
	// 25: PEEK - value at stack address
	case 25:
		assignable = &s.Ram[s.SP]
	// 26: PUSH - decreases stack address, then value at stack address
	case 26:
		s.SP--
		assignable = &s.Ram[s.SP]
	// 27: SP - current stack pointer value - current stack address
	case 27:
		assignable = &s.SP
	// 28: PC - program counter- current program counter
	case 28:
		assignable = &s.PC
	// 29: O - overflow - current value of the overflow
	case 29:
		assignable = &s.O
	// 30: [next word of ram] - memory address
	case 30:
		assignable = &s.Ram[s.Ram[s.PC]]
		s.PC++
	// 31: next word of ram - literal, does nothing on assign
	case 31:
		val = s.Ram[s.PC]
		s.PC++
	default:
		if op >= 64 {
			panic("Out of bounds operand")
		}
		val = op - 32
	}
	if assignable != nil {
		val = *assignable
	}
	return
}

func (s *State) isProtected(address Word) bool {
	for _, region := range s.Protected {
		if region.Contains(address) {
			return true
		}
		if region.Start > address {
			break
		}
	}
	return false
}

func (s *State) isProtectedPtr(address *Word) (bool, Word) {
	// are we in our ram?
	ptr := uintptr(unsafe.Pointer(address))
	ramStart := uintptr(unsafe.Pointer(&s.Ram[0]))
	ramEnd := uintptr(unsafe.Pointer(&s.Ram[len(s.Ram)-1]))
	if ptr >= ramStart && ptr <= ramEnd {
		index := Word((ptr - ramStart) / unsafe.Sizeof(s.Ram[0]))
		return s.isProtected(index), index
	}
	return false, 0
}

// Step iterates the CPU by one instruction.
func (s *State) Step() error {
	// fetch
	opcode := s.Ram[s.PC]
	s.PC++

	// decode
	ins, a, b := decodeOpcode(opcode)

	var assignable *Word
	if ins != 0 { // don't translate for the non-basic opcodes
		a, assignable = s.translateOperand(a)
		b, _ = s.translateOperand(b)
	}

	// execute
	var val Word
	switch ins {
	case 0:
		ins, a = a, b
		switch ins {
		case 1:
			// JSR a - pushes the address of the next instruction to the stack, then sets PC to a
			_, assignable = s.translateOperand(0x1a) // PUSH
			a, _ = s.translateOperand(a)
			if ok, index := s.isProtectedPtr(assignable); ok {
				return &ProtectionError{
					Address:  index,
					Opcode:   opcode,
					OperandA: a,
				}
			}
			*assignable = s.PC
			s.PC = a
		default:
			return &OpcodeError{opcode}
		}
	case 1:
		// SET a, b - sets a to b
		val = b
	case 2:
		// ADD a, b - sets a to a+b, sets O to 0x0001 if there's an overflow, 0x0 otherwise
		result := uint32(a) + uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16) // will always be 0x0 or 0x1
	case 3:
		// SUB a, b - sets a to a-b, sets O to 0xffff if there's an underflow, 0x0 otherwise
		result := uint32(a) - uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16) // will always be 0x0 or 0xffff
	case 4:
		// MUL a, b - sets a to a*b, sets O to ((a*b)>>16)&0xffff
		result := uint32(a) * uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16)
	case 5:
		// DIV a, b - sets a to a/b, sets O to ((a<<16)/b)&0xffff. if b==0, sets a and O to 0 instead.
		if b == 0 {
			val, s.O = 0, 0
		} else {
			val = a / b
			s.O = Word(((uint32(a) << 16) / uint32(b)))
		}
	case 6:
		// MOD a, b - sets a to a%b. if b==0, sets a to 0 instead.
		if b == 0 {
			val = 0
		} else {
			val = a % b
		}
	case 7:
		// SHL a, b - sets a to a<<b, sets O to ((a<<b)>>16)&0xffff
		result := uint32(a) << uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16)
	case 8:
		// SHR a, b - sets a to a>>b, sets O to ((a<<16)>>b)&0xffff
		val = a >> b
		s.O = Word((uint32(a) << 16) >> b)
	case 9:
		// AND a, b - sets a to a&b
		val = a & b
	case 10:
		// BOR a, b - sets a to a|b
		val = a | b
	case 11:
		// XOR a, b - sets a to a^b
		val = a ^ b
	case 12:
		// IFE a, b - performs next instruction only if a==b
		if a != b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 13:
		// IFN a, b - performs next instruction only if a!=b
		if a == b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 14:
		// IFG a, b - performs next instruction only if a>b
		if a <= b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 15:
		// IFB a, b - performs next instruction only if (a&b)!=0
		if (a & b) == 0 {
			s.PC += wordCount(s.Ram[s.PC])
		}
	default:
		panic("Out of bounds opcode")
	}

	// store
	if ins >= 1 && ins <= 11 && assignable != nil {
		// test memory protection
		if ok, index := s.isProtectedPtr(assignable); ok {
			// protection error
			return &ProtectionError{
				Address:  index,
				Opcode:   opcode,
				OperandA: a,
				OperandB: b,
			}
		}
		// go ahead and store
		*assignable = val
	}

	return nil
}
<commit_msg>Fix the implementation of JSR<commit_after>package dcpu

import (
	"fmt"
	"unsafe"
)

type Word uint16

type ProtectionError struct {
	Address            Word
	Opcode             Word
	OperandA, OperandB Word
}

func (err *ProtectionError) Error() string {
	return fmt.Sprintf("protection violation at address %#x (instruction %#04x, operands %#x, %#x)",
		err.Address, err.Opcode, err.OperandA, err.OperandB)
}

type OpcodeError struct {
	Opcode Word
}

func (err *OpcodeError) Error() string {
	return fmt.Sprintf("invalid opcode %#04x", err.Opcode)
}

type Registers struct {
	A, B, C, X, Y, Z, I, J Word
	PC                     Word
	SP                     Word
	O                      Word
}

type Region struct {
	Start  Word
	Length Word
}

func (r Region) Contains(address Word) bool {
	return address >= r.Start && address < r.Start+r.Length
}

// End() returns the first address not contained in the region
func (r Region) End() Word {
	return r.Start + r.Length
}

func (r Region) Union(r2 Region) Region {
	var reg Region
	if r2.Start < r.Start {
		reg.Start = r2.Start
	} else {
		reg.Start = r.Start
	}
	if r2.End() > r.End() {
		reg.Length = r2.End() - reg.Start
	} else {
		reg.Length = r.End() - reg.Start
	}
	return reg
}

type State struct {
	Registers
	Ram       [0x10000]Word
	Protected []Region
}

func decodeOpcode(opcode Word) (oooo, aaaaaa, bbbbbb Word) {
	oooo = opcode & 0xF
	aaaaaa = (opcode >> 4) & 0x3F
	bbbbbb = (opcode >> 10) & 0x3F
	return
}

// wordCount counts the number of words in the instruction identified by the given opcode
func wordCount(opcode Word) Word {
	_, a, b := decodeOpcode(opcode)
	count := Word(1)
	switch {
	case a >= 16 && a <= 23:
	case a == 30:
	case a == 31:
		count++
	}
	switch {
	case b >= 16 && b <= 23:
	case b == 30:
	case b == 31:
		count++
	}
	return count
}

func (s *State) translateOperand(op Word) (val Word, assignable *Word) {
	switch op {
	// 0-7: register value - register values
	case 0:
		assignable = &s.A
	case 1:
		assignable = &s.B
	case 2:
		assignable = &s.C
	case 3:
		assignable = &s.X
	case 4:
		assignable = &s.Y
	case 5:
		assignable = &s.Z
	case 6:
		assignable = &s.I
	case 7:
		assignable = &s.J
	// 8-15: [register value] - value at address in registries
	case 8:
		assignable = &s.Ram[s.A]
	case 9:
		assignable = &s.Ram[s.B]
	case 10:
		assignable = &s.Ram[s.C]
	case 11:
		assignable = &s.Ram[s.X]
	case 12:
		assignable = &s.Ram[s.Y]
	case 13:
		assignable = &s.Ram[s.Z]
	case 14:
		assignable = &s.Ram[s.I]
	case 15:
		assignable = &s.Ram[s.J]
	// 16-23: [next word of ram + register value] - memory address offset by register value
	case 16:
		assignable = &s.Ram[s.Ram[s.PC]+s.A]
		s.PC++
	case 17:
		assignable = &s.Ram[s.Ram[s.PC]+s.B]
		s.PC++
	case 18:
		assignable = &s.Ram[s.Ram[s.PC]+s.C]
		s.PC++
	case 19:
		assignable = &s.Ram[s.Ram[s.PC]+s.X]
		s.PC++
	case 20:
		assignable = &s.Ram[s.Ram[s.PC]+s.Y]
		s.PC++
	case 21:
		assignable = &s.Ram[s.Ram[s.PC]+s.Z]
		s.PC++
	case 22:
		assignable = &s.Ram[s.Ram[s.PC]+s.I]
		s.PC++
	case 23:
		assignable = &s.Ram[s.Ram[s.PC]+s.J]
		s.PC++
	// 24: POP - value at stack address, then increases stack counter
	case 24:
		assignable = &s.Ram[s.SP]
		s.SP++
	// 25: PEEK - value at stack address
	case 25:
		assignable = &s.Ram[s.SP]
	// 26: PUSH - decreases stack address, then value at stack address
	case 26:
		s.SP--
		assignable = &s.Ram[s.SP]
	// 27: SP - current stack pointer value - current stack address
	case 27:
		assignable = &s.SP
	// 28: PC - program counter- current program counter
	case 28:
		assignable = &s.PC
	// 29: O - overflow - current value of the overflow
	case 29:
		assignable = &s.O
	// 30: [next word of ram] - memory address
	case 30:
		assignable = &s.Ram[s.Ram[s.PC]]
		s.PC++
	// 31: next word of ram - literal, does nothing on assign
	case 31:
		val = s.Ram[s.PC]
		s.PC++
	default:
		if op >= 64 {
			panic("Out of bounds operand")
		}
		val = op - 32
	}
	if assignable != nil {
		val = *assignable
	}
	return
}

func (s *State) isProtected(address Word) bool {
	for _, region := range s.Protected {
		if region.Contains(address) {
			return true
		}
		if region.Start > address {
			break
		}
	}
	return false
}

func (s *State) isProtectedPtr(address *Word) (bool, Word) {
	// are we in our ram?
	ptr := uintptr(unsafe.Pointer(address))
	ramStart := uintptr(unsafe.Pointer(&s.Ram[0]))
	ramEnd := uintptr(unsafe.Pointer(&s.Ram[len(s.Ram)-1]))
	if ptr >= ramStart && ptr <= ramEnd {
		index := Word((ptr - ramStart) / unsafe.Sizeof(s.Ram[0]))
		return s.isProtected(index), index
	}
	return false, 0
}

// Step iterates the CPU by one instruction.
func (s *State) Step() error {
	// fetch
	opcode := s.Ram[s.PC]
	s.PC++

	// decode
	ins, a, b := decodeOpcode(opcode)

	var assignable *Word
	if ins != 0 { // don't translate for the non-basic opcodes
		a, assignable = s.translateOperand(a)
		b, _ = s.translateOperand(b)
	}

	// execute
	var val Word
	switch ins {
	case 0:
		// non-basic opcodes
		ins, a = a, b
		switch ins {
		case 1:
			// JSR a - pushes the address of the next instruction to the stack, then sets PC to a
			_, assignable = s.translateOperand(0x1a) // PUSH
			a, _ = s.translateOperand(a)
			if ok, index := s.isProtectedPtr(assignable); ok {
				return &ProtectionError{
					Address:  index,
					Opcode:   opcode,
					OperandA: a,
				}
			}
			val = s.PC
			s.PC = a
		default:
			return &OpcodeError{opcode}
		}
	case 1:
		// SET a, b - sets a to b
		val = b
	case 2:
		// ADD a, b - sets a to a+b, sets O to 0x0001 if there's an overflow, 0x0 otherwise
		result := uint32(a) + uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16) // will always be 0x0 or 0x1
	case 3:
		// SUB a, b - sets a to a-b, sets O to 0xffff if there's an underflow, 0x0 otherwise
		result := uint32(a) - uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16) // will always be 0x0 or 0xffff
	case 4:
		// MUL a, b - sets a to a*b, sets O to ((a*b)>>16)&0xffff
		result := uint32(a) * uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16)
	case 5:
		// DIV a, b - sets a to a/b, sets O to ((a<<16)/b)&0xffff. if b==0, sets a and O to 0 instead.
		if b == 0 {
			val, s.O = 0, 0
		} else {
			val = a / b
			s.O = Word(((uint32(a) << 16) / uint32(b)))
		}
	case 6:
		// MOD a, b - sets a to a%b. if b==0, sets a to 0 instead.
		if b == 0 {
			val = 0
		} else {
			val = a % b
		}
	case 7:
		// SHL a, b - sets a to a<<b, sets O to ((a<<b)>>16)&0xffff
		result := uint32(a) << uint32(b)
		val = Word(result & 0xFFFF)
		s.O = Word(result >> 16)
	case 8:
		// SHR a, b - sets a to a>>b, sets O to ((a<<16)>>b)&0xffff
		val = a >> b
		s.O = Word((uint32(a) << 16) >> b)
	case 9:
		// AND a, b - sets a to a&b
		val = a & b
	case 10:
		// BOR a, b - sets a to a|b
		val = a | b
	case 11:
		// XOR a, b - sets a to a^b
		val = a ^ b
	case 12:
		// IFE a, b - performs next instruction only if a==b
		if a != b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 13:
		// IFN a, b - performs next instruction only if a!=b
		if a == b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 14:
		// IFG a, b - performs next instruction only if a>b
		if a <= b {
			s.PC += wordCount(s.Ram[s.PC])
		}
	case 15:
		// IFB a, b - performs next instruction only if (a&b)!=0
		if (a & b) == 0 {
			s.PC += wordCount(s.Ram[s.PC])
		}
	default:
		panic("Out of bounds opcode")
	}

	// store
	if ins >= 1 && ins <= 11 && assignable != nil {
		// test memory protection
		if ok, index := s.isProtectedPtr(assignable); ok {
			// protection error
			return &ProtectionError{
				Address:  index,
				Opcode:   opcode,
				OperandA: a,
				OperandB: b,
			}
		}
		// go ahead and store
		*assignable = val
	}

	return nil
}
<|endoftext|>


<commit_before>package azurerm

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"regexp"

	"github.com/Azure/azure-sdk-for-go/arm/documentdb"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceArmCosmosDB() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmCosmosDBCreateUpdate,
		Read:   resourceArmCosmosDBRead,
		Update: resourceArmCosmosDBCreateUpdate,
		Delete: resourceArmCosmosDBDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateAzureRmCosmosDBName,
			},

			"location": {
				Type:      schema.TypeString,
				Required:  true,
				ForceNew:  true,
				StateFunc: azureRMNormalizeLocation,
			},

			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"offer_type": {
				Type:     schema.TypeString,
				Required: true,
				ValidateFunc: validation.StringInSlice([]string{
					string(documentdb.Standard),
				}, true),
			},

			"ip_range_filter": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"consistency_policy": {
				Type:     schema.TypeSet,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"consistency_level": {
							Type:             schema.TypeString,
							Required:         true,
							DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
							ValidateFunc: validation.StringInSlice([]string{
								string(documentdb.BoundedStaleness),
								string(documentdb.Eventual),
								string(documentdb.Session),
								string(documentdb.Strong),
							}, true),
						},

						"max_interval_in_seconds": {
							// TODO: file a bug, apparently these can be optional/computed
							Type:         schema.TypeInt,
							Required:     true,
							ValidateFunc: validation.IntBetween(1, 100),
						},

						"max_staleness_prefix": {
							// TODO: file a bug, apparently these can be optional/computed
							Type:         schema.TypeInt,
							Required:     true,
							ValidateFunc: validation.IntBetween(1, 2147483647),
						},
					},
				},
				Set: resourceAzureRMCosmosDBConsistencyPolicyHash,
			},

			"failover_policy": {
				Type:     schema.TypeSet,
				Required: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"id": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"location": {
							Type:      schema.TypeString,
							Required:  true,
							StateFunc: azureRMNormalizeLocation,
						},

						"priority": {
							Type:     schema.TypeInt,
							Required: true,
						},
					},
				},
				Set: resourceAzureRMCosmosDBFailoverPolicyHash,
			},

			"primary_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"secondary_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"primary_readonly_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"secondary_readonly_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceArmCosmosDBCreateUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient
	log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB creation.")

	name := d.Get("name").(string)
	location := d.Get("location").(string)
	resGroup := d.Get("resource_group_name").(string)
	offerType := d.Get("offer_type").(string)
	ipRangeFilter := d.Get("ip_range_filter").(string)

	consistencyPolicy := expandAzureRmCosmosDBConsistencyPolicy(d)
	failoverPolicies, err := expandAzureRmCosmosDBFailoverPolicies(name, d)
	if err != nil {
		return err
	}
	tags := d.Get("tags").(map[string]interface{})

	parameters := documentdb.DatabaseAccountCreateUpdateParameters{
		Location: &location,
		DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{
			ConsistencyPolicy:        &consistencyPolicy,
			DatabaseAccountOfferType: &offerType,
			Locations:                &failoverPolicies,
			IPRangeFilter:            &ipRangeFilter,
		},
		Tags: expandTags(tags),
	}

	_, error := client.CreateOrUpdate(resGroup, name, parameters, make(chan struct{}))
	err = <-error
	if err != nil {
		return err
	}

	read, err := client.Get(resGroup, name)
	if err != nil {
		return err
	}

	if read.ID == nil {
		return fmt.Errorf("Cannot read Document DB instance %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmCosmosDBRead(d, meta)
}

func resourceArmCosmosDBRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient
	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["databaseAccounts"]

	resp, err := client.Get(resGroup, name)
	if err != nil {
		return fmt.Errorf("Error making Read request on AzureRM CosmosDB %s: %s", name, err)
	}
	if resp.StatusCode == http.StatusNotFound {
		d.SetId("")
		return nil
	}

	d.Set("name", resp.Name)
	d.Set("location", azureRMNormalizeLocation(*resp.Location))
	d.Set("resource_group_name", resGroup)
	d.Set("offer_type", string(resp.DatabaseAccountOfferType))
	d.Set("ip_range_filter", resp.IPRangeFilter)
	flattenAndSetAzureRmCosmosDBConsistencyPolicy(d, resp.ConsistencyPolicy)
	flattenAndSetAzureRmCosmosDBFailoverPolicy(d, resp.FailoverPolicies)

	keys, err := client.ListKeys(resGroup, name)
	if err != nil {
		log.Printf("[ERROR] Unable to List Write keys for CosmosDB %s: %s", name, err)
	} else {
		d.Set("primary_master_key", keys.PrimaryMasterKey)
		d.Set("secondary_master_key", keys.SecondaryMasterKey)
	}

	readonlyKeys, err := client.ListReadOnlyKeys(resGroup, name)
	if err != nil {
		log.Printf("[ERROR] Unable to List read-only keys for CosmosDB %s: %s", name, err)
	} else {
		d.Set("primary_readonly_master_key", readonlyKeys.PrimaryReadonlyMasterKey)
		d.Set("secondary_readonly_master_key", readonlyKeys.SecondaryReadonlyMasterKey)
	}

	flattenAndSetTags(d, resp.Tags)

	return nil
}

func resourceArmCosmosDBDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["databaseAccounts"]

	deleteResp, error := client.Delete(resGroup, name, make(chan struct{}))
	resp := <-deleteResp
	err = <-error

	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			return nil
		}

		return fmt.Errorf("Error issuing AzureRM delete request for CosmosDB instance '%s': %+v", name, err)
	}

	return nil
}

func expandAzureRmCosmosDBConsistencyPolicy(d *schema.ResourceData) documentdb.ConsistencyPolicy {
	inputs := d.Get("consistency_policy").(*schema.Set).List()
	input := inputs[0].(map[string]interface{})

	consistencyLevel := input["consistency_level"].(string)

	policy := documentdb.ConsistencyPolicy{
		DefaultConsistencyLevel: documentdb.DefaultConsistencyLevel(consistencyLevel),
	}

	// TODO: file a bug about these two being required
	// documentdb.DatabaseAccountsClient#CreateOrUpdate:
	// Invalid input: autorest/validation: validation failed:
	// parameter=createUpdateParameters.DatabaseAccountCreateUpdateProperties.ConsistencyPolicy.MaxStalenessPrefix
	// constraint=InclusiveMinimum value=0 details: value must be greater than or equal to 1
	if stalenessPrefix, ok := input["max_staleness_prefix"].(int); ok {
		maxStalenessPrefix := int64(stalenessPrefix)
		policy.MaxStalenessPrefix = &maxStalenessPrefix
	}

	if maxInterval, ok := input["max_interval_in_seconds"].(int); ok {
		maxIntervalInSeconds := int32(maxInterval)
		policy.MaxIntervalInSeconds = &maxIntervalInSeconds
	}

	return policy
}

func expandAzureRmCosmosDBFailoverPolicies(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) {
	input := d.Get("failover_policy").(*schema.Set).List()
	locations := make([]documentdb.Location, 0, len(input))

	for _, configRaw := range input {
		data := configRaw.(map[string]interface{})

		locationName := azureRMNormalizeLocation(data["location"].(string))
		id := fmt.Sprintf("%s-%s", databaseName, locationName)
		failoverPriority := int32(data["priority"].(int))

		location := documentdb.Location{
			ID:               &id,
			LocationName:     &locationName,
			FailoverPriority: &failoverPriority,
		}

		locations = append(locations, location)
	}

	containsWriteLocation := false
	writeFailoverPriority := int32(0)
	for _, location := range locations {
		if *location.FailoverPriority == writeFailoverPriority {
			containsWriteLocation = true
			break
		}
	}

	// all priorities must be unique
	locationIds := make(map[int]struct{}, len(locations))
	for _, location := range locations {
		priority := int(*location.FailoverPriority)
		if _, ok := locationIds[priority]; ok {
			err := fmt.Errorf("Each CosmosDB Failover Policy needs to be unique")
			return nil, err
		}

		locationIds[priority] = struct{}{}
	}

	if !containsWriteLocation {
		err := fmt.Errorf("CosmosDB Failover Policy should contain a Write Location (Location '0')")
		return nil, err
	}

	return locations, nil
}

func flattenAndSetAzureRmCosmosDBConsistencyPolicy(d *schema.ResourceData, policy *documentdb.ConsistencyPolicy) {
	results := schema.Set{
		F: resourceAzureRMCosmosDBConsistencyPolicyHash,
	}

	result := map[string]interface{}{}
	result["consistency_level"] = string(policy.DefaultConsistencyLevel)
	result["max_interval_in_seconds"] = int(*policy.MaxIntervalInSeconds)
	result["max_staleness_prefix"] = int(*policy.MaxStalenessPrefix)
	results.Add(result)

	d.Set("consistency_policy", &results)
}

func flattenAndSetAzureRmCosmosDBFailoverPolicy(d *schema.ResourceData, list *[]documentdb.FailoverPolicy) {
	results := schema.Set{
		F: resourceAzureRMCosmosDBFailoverPolicyHash,
	}

	for _, i := range *list {
		result := map[string]interface{}{
			"id":       *i.ID,
			"location": azureRMNormalizeLocation(*i.LocationName),
			"priority": int(*i.FailoverPriority),
		}

		results.Add(result)
	}

	d.Set("failover_policy", &results)
}

func resourceAzureRMCosmosDBConsistencyPolicyHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	consistencyLevel := m["consistency_level"].(string)
	maxInterval := m["max_interval_in_seconds"].(int)
	maxStalenessPrefix := m["max_staleness_prefix"].(int)

	buf.WriteString(fmt.Sprintf("%s-%d-%d", consistencyLevel, maxInterval, maxStalenessPrefix))

	return hashcode.String(buf.String())
}

func resourceAzureRMCosmosDBFailoverPolicyHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	locationName := m["location"].(string)
	location := azureRMNormalizeLocation(locationName)
	priority := int32(m["priority"].(int))

	buf.WriteString(fmt.Sprintf("%s-%d", location, priority))

	return hashcode.String(buf.String())
}

func validateAzureRmCosmosDBName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)

	r, _ := regexp.Compile("[a-z0-9-]")
	if !r.MatchString(value) {
		errors = append(errors, fmt.Errorf("CosmosDB Name can only contain lower-case characters, numbers and the `-` character."))
	}

	length := len(value)
	if length > 50 || 3 > length {
		errors = append(errors, fmt.Errorf("CosmosDB Name can only be between 3 and 50 seconds."))
	}

	return
}
<commit_msg>max_interval_in_seconds / max_staleness_prefix can be Optional/Computed<commit_after>package azurerm

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"regexp"

	"github.com/Azure/azure-sdk-for-go/arm/documentdb"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceArmCosmosDB() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmCosmosDBCreateUpdate,
		Read:   resourceArmCosmosDBRead,
		Update: resourceArmCosmosDBCreateUpdate,
		Delete: resourceArmCosmosDBDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateAzureRmCosmosDBName,
			},

			"location": {
				Type:      schema.TypeString,
				Required:  true,
				ForceNew:  true,
				StateFunc: azureRMNormalizeLocation,
			},

			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"offer_type": {
				Type:     schema.TypeString,
				Required: true,
				ValidateFunc: validation.StringInSlice([]string{
					string(documentdb.Standard),
				}, true),
			},

			"ip_range_filter": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"consistency_policy": {
				Type:     schema.TypeSet,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"consistency_level": {
							Type:             schema.TypeString,
							Required:         true,
							DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
							ValidateFunc: validation.StringInSlice([]string{
								string(documentdb.BoundedStaleness),
								string(documentdb.Eventual),
								string(documentdb.Session),
								string(documentdb.Strong),
							}, true),
						},

						"max_interval_in_seconds": {
							// TODO: apparently these can be optional/computed
							Type:     schema.TypeInt,
							Optional: true,
							Computed: true,
							//ValidateFunc: validation.IntBetween(1, 100),
						},

						"max_staleness_prefix": {
							// TODO: apparently these can be optional/computed
							Type:     schema.TypeInt,
							Optional: true,
							Computed: true,
							//ValidateFunc: validation.IntBetween(1, 2147483647),
						},
					},
				},
				Set: resourceAzureRMCosmosDBConsistencyPolicyHash,
			},

			"failover_policy": {
				Type:     schema.TypeSet,
				Required: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"id": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"location": {
							Type:      schema.TypeString,
							Required:  true,
							StateFunc: azureRMNormalizeLocation,
						},

						"priority": {
							Type:     schema.TypeInt,
							Required: true,
						},
					},
				},
				Set: resourceAzureRMCosmosDBFailoverPolicyHash,
			},

			"primary_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"secondary_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"primary_readonly_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"secondary_readonly_master_key": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceArmCosmosDBCreateUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient
	log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB creation.")

	name := d.Get("name").(string)
	location := d.Get("location").(string)
	resGroup := d.Get("resource_group_name").(string)
	offerType := d.Get("offer_type").(string)
	ipRangeFilter := d.Get("ip_range_filter").(string)

	consistencyPolicy := expandAzureRmCosmosDBConsistencyPolicy(d)
	failoverPolicies, err := expandAzureRmCosmosDBFailoverPolicies(name, d)
	if err != nil {
		return err
	}
	tags := d.Get("tags").(map[string]interface{})

	parameters := documentdb.DatabaseAccountCreateUpdateParameters{
		Location: &location,
		DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{
			ConsistencyPolicy:        &consistencyPolicy,
			DatabaseAccountOfferType: &offerType,
			Locations:                &failoverPolicies,
			IPRangeFilter:            &ipRangeFilter,
		},
		Tags: expandTags(tags),
	}

	_, error := client.CreateOrUpdate(resGroup, name, parameters, make(chan struct{}))
	err = <-error
	if err != nil {
		return err
	}

	read, err := client.Get(resGroup, name)
	if err != nil {
		return err
	}

	if read.ID == nil {
		return fmt.Errorf("Cannot read Document DB instance %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmCosmosDBRead(d, meta)
}

func resourceArmCosmosDBRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient
	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["databaseAccounts"]

	resp, err := client.Get(resGroup, name)
	if err != nil {
		return fmt.Errorf("Error making Read request on AzureRM CosmosDB %s: %s", name, err)
	}
	if resp.StatusCode == http.StatusNotFound {
		d.SetId("")
		return nil
	}

	d.Set("name", resp.Name)
	d.Set("location", azureRMNormalizeLocation(*resp.Location))
	d.Set("resource_group_name", resGroup)
	d.Set("offer_type", string(resp.DatabaseAccountOfferType))
	d.Set("ip_range_filter", resp.IPRangeFilter)
	flattenAndSetAzureRmCosmosDBConsistencyPolicy(d, resp.ConsistencyPolicy)
	flattenAndSetAzureRmCosmosDBFailoverPolicy(d, resp.FailoverPolicies)

	keys, err := client.ListKeys(resGroup, name)
	if err != nil {
		log.Printf("[ERROR] Unable to List Write keys for CosmosDB %s: %s", name, err)
	} else {
		d.Set("primary_master_key", keys.PrimaryMasterKey)
		d.Set("secondary_master_key", keys.SecondaryMasterKey)
	}

	readonlyKeys, err := client.ListReadOnlyKeys(resGroup, name)
	if err != nil {
		log.Printf("[ERROR] Unable to List read-only keys for CosmosDB %s: %s", name, err)
	} else {
		d.Set("primary_readonly_master_key", readonlyKeys.PrimaryReadonlyMasterKey)
		d.Set("secondary_readonly_master_key", readonlyKeys.SecondaryReadonlyMasterKey)
	}

	flattenAndSetTags(d, resp.Tags)

	return nil
}

func resourceArmCosmosDBDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).documentDBClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["databaseAccounts"]

	deleteResp, error := client.Delete(resGroup, name, make(chan struct{}))
	resp := <-deleteResp
	err = <-error

	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			return nil
		}

		return fmt.Errorf("Error issuing AzureRM delete request for CosmosDB instance '%s': %+v", name, err)
	}

	return nil
}

func expandAzureRmCosmosDBConsistencyPolicy(d *schema.ResourceData) documentdb.ConsistencyPolicy {
	inputs := d.Get("consistency_policy").(*schema.Set).List()
	input := inputs[0].(map[string]interface{})

	consistencyLevel := input["consistency_level"].(string)

	policy := documentdb.ConsistencyPolicy{
		DefaultConsistencyLevel: documentdb.DefaultConsistencyLevel(consistencyLevel),
	}

	// TODO: file a bug about these two being required
	// documentdb.DatabaseAccountsClient#CreateOrUpdate:
	// Invalid input: autorest/validation: validation failed:
	// parameter=createUpdateParameters.DatabaseAccountCreateUpdateProperties.ConsistencyPolicy.MaxStalenessPrefix
	// constraint=InclusiveMinimum value=0 details: value must be greater than or equal to 1
	if stalenessPrefix, ok := input["max_staleness_prefix"].(int); ok {
		maxStalenessPrefix := int64(stalenessPrefix)
		policy.MaxStalenessPrefix = &maxStalenessPrefix
	}

	if maxInterval, ok := input["max_interval_in_seconds"].(int); ok {
		maxIntervalInSeconds := int32(maxInterval)
		policy.MaxIntervalInSeconds = &maxIntervalInSeconds
	}

	return policy
}

func expandAzureRmCosmosDBFailoverPolicies(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) {
	input := d.Get("failover_policy").(*schema.Set).List()
	locations := make([]documentdb.Location, 0, len(input))

	for _, configRaw := range input {
		data := configRaw.(map[string]interface{})

		locationName := azureRMNormalizeLocation(data["location"].(string))
		id := fmt.Sprintf("%s-%s", databaseName, locationName)
		failoverPriority := int32(data["priority"].(int))

		location := documentdb.Location{
			ID:               &id,
			LocationName:     &locationName,
			FailoverPriority: &failoverPriority,
		}

		locations = append(locations, location)
	}

	containsWriteLocation := false
	writeFailoverPriority := int32(0)
	for _, location := range locations {
		if *location.FailoverPriority == writeFailoverPriority {
			containsWriteLocation = true
			break
		}
	}

	// all priorities must be unique
	locationIds := make(map[int]struct{}, len(locations))
	for _, location := range locations {
		priority := int(*location.FailoverPriority)
		if _, ok := locationIds[priority]; ok {
			err := fmt.Errorf("Each CosmosDB Failover Policy needs to be unique")
			return nil, err
		}

		locationIds[priority] = struct{}{}
	}

	if !containsWriteLocation {
		err := fmt.Errorf("CosmosDB Failover Policy should contain a Write Location (Location '0')")
		return nil, err
	}

	return locations, nil
}

func flattenAndSetAzureRmCosmosDBConsistencyPolicy(d *schema.ResourceData, policy *documentdb.ConsistencyPolicy) {
	results := schema.Set{
		F: resourceAzureRMCosmosDBConsistencyPolicyHash,
	}

	result := map[string]interface{}{}
	result["consistency_level"] = string(policy.DefaultConsistencyLevel)
	result["max_interval_in_seconds"] = int(*policy.MaxIntervalInSeconds)
	result["max_staleness_prefix"] = int(*policy.MaxStalenessPrefix)
	results.Add(result)

	d.Set("consistency_policy", &results)
}

func flattenAndSetAzureRmCosmosDBFailoverPolicy(d *schema.ResourceData, list *[]documentdb.FailoverPolicy) {
	results := schema.Set{
		F: resourceAzureRMCosmosDBFailoverPolicyHash,
	}

	for _, i := range *list {
		result := map[string]interface{}{
			"id":       *i.ID,
			"location": azureRMNormalizeLocation(*i.LocationName),
			"priority": int(*i.FailoverPriority),
		}

		results.Add(result)
	}

	d.Set("failover_policy", &results)
}

func resourceAzureRMCosmosDBConsistencyPolicyHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	consistencyLevel := m["consistency_level"].(string)
	maxInterval := m["max_interval_in_seconds"].(int)
	maxStalenessPrefix := m["max_staleness_prefix"].(int)

	buf.WriteString(fmt.Sprintf("%s-%d-%d", consistencyLevel, maxInterval, maxStalenessPrefix))

	return hashcode.String(buf.String())
}

func resourceAzureRMCosmosDBFailoverPolicyHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	locationName := m["location"].(string)
	location := azureRMNormalizeLocation(locationName)
	priority := int32(m["priority"].(int))

	buf.WriteString(fmt.Sprintf("%s-%d", location, priority))

	return hashcode.String(buf.String())
}

func validateAzureRmCosmosDBName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)

	r, _ := regexp.Compile("[a-z0-9-]")
	if !r.MatchString(value) {
		errors = append(errors, fmt.Errorf("CosmosDB Name can only contain lower-case characters, numbers and the `-` character."))
	}

	length := len(value)
	if length > 50 || 3 > length {
		errors = append(errors, fmt.Errorf("CosmosDB Name can only be between 3 and 50 seconds."))
	}

	return
}
<|endoftext|>


<commit_before>package azurerm

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/Azure/azure-sdk-for-go/arm/network"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceArmNetworkInterface() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmNetworkInterfaceCreate,
		Read:   resourceArmNetworkInterfaceRead,
		Update: resourceArmNetworkInterfaceCreate,
		Delete: resourceArmNetworkInterfaceDelete,

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"location": locationSchema(),

			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"network_security_group_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"mac_address": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"private_ip_address": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"virtual_machine_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"ip_configuration": {
				Type:     schema.TypeSet,
				Required: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"name": {
							Type:     schema.TypeString,
							Required: true,
						},

						"subnet_id": {
							Type:     schema.TypeString,
							Required: true,
						},

						"private_ip_address": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"private_ip_address_allocation": {
							Type:             schema.TypeString,
							Required:         true,
							ValidateFunc:     validateNetworkInterfacePrivateIpAddressAllocation,
							StateFunc:        ignoreCaseStateFunc,
							DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
						},

						"public_ip_address_id": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"load_balancer_backend_address_pools_ids": {
							Type:     schema.TypeSet,
							Optional: true,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},

						"load_balancer_inbound_nat_rules_ids": {
							Type:     schema.TypeSet,
							Optional: true,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
					},
				},
				Set: resourceArmNetworkInterfaceIpConfigurationHash,
			},

			"dns_servers": {
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

			"internal_dns_name_label": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"applied_dns_servers": {
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

			"internal_fqdn": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"enable_ip_forwarding": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceArmNetworkInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient)
	ifaceClient := client.ifaceClient

	log.Printf("[INFO] preparing arguments for Azure ARM Network Interface creation.")

	name := d.Get("name").(string)
	location := d.Get("location").(string)
	resGroup := d.Get("resource_group_name").(string)
	enableIpForwarding := d.Get("enable_ip_forwarding").(bool)
	tags := d.Get("tags").(map[string]interface{})

	properties := network.InterfacePropertiesFormat{
		EnableIPForwarding: &enableIpForwarding,
	}

	if v, ok := d.GetOk("network_security_group_id"); ok {
		nsgId := v.(string)
		properties.NetworkSecurityGroup = &network.SecurityGroup{
			ID: &nsgId,
		}

		networkSecurityGroupName, err := parseNetworkSecurityGroupName(nsgId)
		if err != nil {
			return err
		}

		armMutexKV.Lock(networkSecurityGroupName)
		defer armMutexKV.Unlock(networkSecurityGroupName)
	}

	dns, hasDns := d.GetOk("dns_servers")
	nameLabel, hasNameLabel := d.GetOk("internal_dns_name_label")
	if hasDns || hasNameLabel {
		ifaceDnsSettings := network.InterfaceDNSSettings{}

		if hasDns {
			var dnsServers []string
			dns := dns.(*schema.Set).List()
			for _, v := range dns {
				str := v.(string)
				dnsServers = append(dnsServers, str)
			}
			ifaceDnsSettings.DNSServers = &dnsServers
		}

		if hasNameLabel {
			name_label := nameLabel.(string)
			ifaceDnsSettings.InternalDNSNameLabel = &name_label
		}

		properties.DNSSettings = &ifaceDnsSettings
	}

	ipConfigs, namesToLock, sgErr := expandAzureRmNetworkInterfaceIpConfigurations(d)
	if sgErr != nil {
		return fmt.Errorf("Error Building list of Network Interface IP Configurations: %s", sgErr)
	}

	azureRMLockMultiple(namesToLock)
	defer azureRMUnlockMultiple(namesToLock)

	if len(ipConfigs) > 0 {
		properties.IPConfigurations = &ipConfigs
	}

	iface := network.Interface{
		Name:                      &name,
		Location:                  &location,
		InterfacePropertiesFormat: &properties,
		Tags: expandTags(tags),
	}

	_, err := ifaceClient.CreateOrUpdate(resGroup, name, iface, make(chan struct{}))
	if err != nil {
		return err
	}

	read, err := ifaceClient.Get(resGroup, name, "")
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read NIC %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmNetworkInterfaceRead(d, meta)
}

func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error {
	ifaceClient := meta.(*ArmClient).ifaceClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["networkInterfaces"]

	resp, err := ifaceClient.Get(resGroup, name, "")
	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on Azure Network Interface %s: %s", name, err)
	}

	iface := *resp.InterfacePropertiesFormat

	if iface.MacAddress != nil {
		if *iface.MacAddress != "" {
			d.Set("mac_address", iface.MacAddress)
		}
	}

	if iface.IPConfigurations != nil && len(*iface.IPConfigurations) > 0 {
		var privateIPAddress *string
		///TODO: Change this to a loop when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed
		if (*iface.IPConfigurations)[0].InterfaceIPConfigurationPropertiesFormat != nil {
			privateIPAddress = (*iface.IPConfigurations)[0].InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress
		}

		if *privateIPAddress != "" {
			d.Set("private_ip_address", *privateIPAddress)
		}
	}

	if iface.VirtualMachine != nil {
		if *iface.VirtualMachine.ID != "" {
			d.Set("virtual_machine_id", *iface.VirtualMachine.ID)
		}
	}

	if iface.DNSSettings != nil {
		if iface.DNSSettings.AppliedDNSServers != nil && len(*iface.DNSSettings.AppliedDNSServers) > 0 {
			dnsServers := make([]string, 0, len(*iface.DNSSettings.AppliedDNSServers))
			for _, dns := range *iface.DNSSettings.AppliedDNSServers {
				dnsServers = append(dnsServers, dns)
			}

			if err := d.Set("applied_dns_servers", dnsServers); err != nil {
				return err
			}
		}

		if iface.DNSSettings.InternalFqdn != nil && *iface.DNSSettings.InternalFqdn != "" {
			d.Set("internal_fqdn", iface.DNSSettings.InternalFqdn)
		}
	}

	flattenAndSetTags(d, resp.Tags)

	return nil
}

func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
	ifaceClient := meta.(*ArmClient).ifaceClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["networkInterfaces"]

	if v, ok := d.GetOk("network_security_group_id"); ok {
		networkSecurityGroupId := v.(string)
		networkSecurityGroupName, err := parseNetworkSecurityGroupName(networkSecurityGroupId)
		if err != nil {
			return err
		}

		armMutexKV.Lock(networkSecurityGroupName)
		defer armMutexKV.Unlock(networkSecurityGroupName)
	}

	configs := d.Get("ip_configuration").(*schema.Set).List()
	namesToLock := make([]string, 0)

	for _, configRaw := range configs {
		data := configRaw.(map[string]interface{})

		subnet_id := data["subnet_id"].(string)
		subnetId, err := parseAzureResourceID(subnet_id)
		if err != nil {
			return err
		}
		subnetName := subnetId.Path["subnets"]
		virtualNetworkName := subnetId.Path["virtualNetworks"]
		namesToLock = append(namesToLock, subnetName)
		namesToLock = append(namesToLock, virtualNetworkName)
	}

	azureRMLockMultiple(&namesToLock)
	defer azureRMUnlockMultiple(&namesToLock)

	_, err = ifaceClient.Delete(resGroup, name, make(chan struct{}))

	return err
}

func resourceArmNetworkInterfaceIpConfigurationHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
	buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string)))
	if m["private_ip_address"] != nil {
		buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address"].(string)))
	}
	buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address_allocation"].(string)))
	if m["public_ip_address_id"] != nil {
		buf.WriteString(fmt.Sprintf("%s-", m["public_ip_address_id"].(string)))
	}
	if m["load_balancer_backend_address_pools_ids"] != nil {
		ids := m["load_balancer_backend_address_pools_ids"].(*schema.Set).List()
		for _, id := range ids {
			buf.WriteString(fmt.Sprintf("%d-", schema.HashString(id.(string))))
		}
	}
	if m["load_balancer_inbound_nat_rules_ids"] != nil {
		ids := m["load_balancer_inbound_nat_rules_ids"].(*schema.Set).List()
		for _, id := range ids {
			buf.WriteString(fmt.Sprintf("%d-", schema.HashString(id.(string))))
		}
	}

	return hashcode.String(buf.String())
}

func validateNetworkInterfacePrivateIpAddressAllocation(v interface{}, k string) (ws []string, errors []error) {
	value := strings.ToLower(v.(string))
	allocations := map[string]bool{
		"static":  true,
		"dynamic": true,
	}

	if !allocations[value] {
		errors = append(errors, fmt.Errorf("Network Interface Allocations can only be Static or Dynamic"))
	}
	return
}

func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]network.InterfaceIPConfiguration, *[]string, error) {
	configs := d.Get("ip_configuration").(*schema.Set).List()
	ipConfigs := make([]network.InterfaceIPConfiguration, 0, len(configs))
	namesToLock := make([]string, 0)

	for _, configRaw := range configs {
		data := configRaw.(map[string]interface{})

		subnet_id := data["subnet_id"].(string)
		private_ip_allocation_method := data["private_ip_address_allocation"].(string)

		var allocationMethod network.IPAllocationMethod
		switch strings.ToLower(private_ip_allocation_method) {
		case "dynamic":
			allocationMethod = network.Dynamic
		case "static":
			allocationMethod = network.Static
		default:
			return []network.InterfaceIPConfiguration{}, nil, fmt.Errorf(
				"valid values for private_ip_allocation_method are 'dynamic' and 'static' - got '%s'",
				private_ip_allocation_method)
		}

		properties := network.InterfaceIPConfigurationPropertiesFormat{
			Subnet: &network.Subnet{
				ID: &subnet_id,
			},
			PrivateIPAllocationMethod: allocationMethod,
		}

		subnetId, err := parseAzureResourceID(subnet_id)
		if err != nil {
			return nil, nil, err
		}
		subnetName := subnetId.Path["subnets"]
		virtualNetworkName := subnetId.Path["virtualNetworks"]
		namesToLock = append(namesToLock, subnetName)
		namesToLock = append(namesToLock, virtualNetworkName)

		if v := data["private_ip_address"].(string); v != "" {
			properties.PrivateIPAddress = &v
		}

		if v := data["public_ip_address_id"].(string); v != "" {
			properties.PublicIPAddress = &network.PublicIPAddress{
				ID: &v,
			}
		}

		if v, ok := data["load_balancer_backend_address_pools_ids"]; ok {
			var ids []network.BackendAddressPool
			pools := v.(*schema.Set).List()
			for _, p := range pools {
				pool_id := p.(string)
				id := network.BackendAddressPool{
					ID: &pool_id,
				}

				ids = append(ids, id)
			}

			properties.LoadBalancerBackendAddressPools = &ids
		}

		if v, ok := data["load_balancer_inbound_nat_rules_ids"]; ok {
			var natRules []network.InboundNatRule
			rules := v.(*schema.Set).List()
			for _, r := range rules {
				rule_id := r.(string)
				rule := network.InboundNatRule{
					ID: &rule_id,
				}

				natRules = append(natRules, rule)
			}

			properties.LoadBalancerInboundNatRules = &natRules
		}

		name := data["name"].(string)
		ipConfig := network.InterfaceIPConfiguration{
			Name: &name,
			InterfaceIPConfigurationPropertiesFormat: &properties,
		}

		ipConfigs = append(ipConfigs, ipConfig)
	}

	return ipConfigs, &namesToLock, nil
}
<commit_msg>Ensuring we return an empty slice to match<commit_after>package azurerm

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/Azure/azure-sdk-for-go/arm/network"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceArmNetworkInterface() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmNetworkInterfaceCreate,
		Read:   resourceArmNetworkInterfaceRead,
		Update: resourceArmNetworkInterfaceCreate,
		Delete: resourceArmNetworkInterfaceDelete,

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"location": locationSchema(),

			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"network_security_group_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"mac_address": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"private_ip_address": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"virtual_machine_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"ip_configuration": {
				Type:     schema.TypeSet,
				Required: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"name": {
							Type:     schema.TypeString,
							Required: true,
						},

						"subnet_id": {
							Type:     schema.TypeString,
							Required: true,
						},

						"private_ip_address": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"private_ip_address_allocation": {
							Type:             schema.TypeString,
							Required:         true,
							ValidateFunc:     validateNetworkInterfacePrivateIpAddressAllocation,
							StateFunc:        ignoreCaseStateFunc,
							DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
						},

						"public_ip_address_id": {
							Type:     schema.TypeString,
							Optional: true,
							Computed: true,
						},

						"load_balancer_backend_address_pools_ids": {
							Type:     schema.TypeSet,
							Optional: true,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},

						"load_balancer_inbound_nat_rules_ids": {
							Type:     schema.TypeSet,
							Optional: true,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
					},
				},
				Set: resourceArmNetworkInterfaceIpConfigurationHash,
			},

			"dns_servers": {
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

			"internal_dns_name_label": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"applied_dns_servers": {
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},

			"internal_fqdn": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"enable_ip_forwarding": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceArmNetworkInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient)
	ifaceClient := client.ifaceClient

	log.Printf("[INFO] preparing arguments for Azure ARM Network Interface creation.")

	name := d.Get("name").(string)
	location := d.Get("location").(string)
	resGroup := d.Get("resource_group_name").(string)
	enableIpForwarding := d.Get("enable_ip_forwarding").(bool)
	tags := d.Get("tags").(map[string]interface{})

	properties := network.InterfacePropertiesFormat{
		EnableIPForwarding: &enableIpForwarding,
	}

	if v, ok := d.GetOk("network_security_group_id"); ok {
		nsgId := v.(string)
		properties.NetworkSecurityGroup = &network.SecurityGroup{
			ID: &nsgId,
		}

		networkSecurityGroupName, err := parseNetworkSecurityGroupName(nsgId)
		if err != nil {
			return err
		}

		armMutexKV.Lock(networkSecurityGroupName)
		defer armMutexKV.Unlock(networkSecurityGroupName)
	}

	dns, hasDns := d.GetOk("dns_servers")
	nameLabel, hasNameLabel := d.GetOk("internal_dns_name_label")
	if hasDns || hasNameLabel {
		ifaceDnsSettings := network.InterfaceDNSSettings{}

		if hasDns {
			var dnsServers []string
			dns := dns.(*schema.Set).List()
			for _, v := range dns {
				str := v.(string)
				dnsServers = append(dnsServers, str)
			}
			ifaceDnsSettings.DNSServers = &dnsServers
		}

		if hasNameLabel {
			name_label := nameLabel.(string)
			ifaceDnsSettings.InternalDNSNameLabel = &name_label
		}

		properties.DNSSettings = &ifaceDnsSettings
	}

	ipConfigs, namesToLock, sgErr := expandAzureRmNetworkInterfaceIpConfigurations(d)
	if sgErr != nil {
		return fmt.Errorf("Error Building list of Network Interface IP Configurations: %s", sgErr)
	}

	azureRMLockMultiple(namesToLock)
	defer azureRMUnlockMultiple(namesToLock)

	if len(ipConfigs) > 0 {
		properties.IPConfigurations = &ipConfigs
	}

	iface := network.Interface{
		Name:                      &name,
		Location:                  &location,
		InterfacePropertiesFormat: &properties,
		Tags: expandTags(tags),
	}

	_, err := ifaceClient.CreateOrUpdate(resGroup, name, iface, make(chan struct{}))
	if err != nil {
		return err
	}

	read, err := ifaceClient.Get(resGroup, name, "")
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read NIC %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmNetworkInterfaceRead(d, meta)
}

func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error {
	ifaceClient := meta.(*ArmClient).ifaceClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["networkInterfaces"]

	resp, err := ifaceClient.Get(resGroup, name, "")
	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on Azure Network Interface %s: %s", name, err)
	}

	iface := *resp.InterfacePropertiesFormat

	if iface.MacAddress != nil {
		if *iface.MacAddress != "" {
			d.Set("mac_address", iface.MacAddress)
		}
	}

	if iface.IPConfigurations != nil && len(*iface.IPConfigurations) > 0 {
		var privateIPAddress *string
		///TODO: Change this to a loop when https://github.com/Azure/azure-sdk-for-go/issues/259 is fixed
		if (*iface.IPConfigurations)[0].InterfaceIPConfigurationPropertiesFormat != nil {
			privateIPAddress = (*iface.IPConfigurations)[0].InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress
		}

		if *privateIPAddress != "" {
			d.Set("private_ip_address", *privateIPAddress)
		}
	}

	if iface.VirtualMachine != nil {
		if *iface.VirtualMachine.ID != "" {
			d.Set("virtual_machine_id", *iface.VirtualMachine.ID)
		}
	}

	if iface.DNSSettings != nil {
		if iface.DNSSettings.AppliedDNSServers != nil && len(*iface.DNSSettings.AppliedDNSServers) > 0 {
			dnsServers := make([]string, 0, len(*iface.DNSSettings.AppliedDNSServers))
			for _, dns := range *iface.DNSSettings.AppliedDNSServers {
				dnsServers = append(dnsServers, dns)
			}

			if err := d.Set("applied_dns_servers", dnsServers); err != nil {
				return err
			}
		}

		if iface.DNSSettings.InternalFqdn != nil && *iface.DNSSettings.InternalFqdn != "" {
			d.Set("internal_fqdn", iface.DNSSettings.InternalFqdn)
		}
	}

	flattenAndSetTags(d, resp.Tags)

	return nil
}

func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
	ifaceClient := meta.(*ArmClient).ifaceClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["networkInterfaces"]

	if v, ok := d.GetOk("network_security_group_id"); ok {
		networkSecurityGroupId := v.(string)
		networkSecurityGroupName, err := parseNetworkSecurityGroupName(networkSecurityGroupId)
		if err != nil {
			return err
		}

		armMutexKV.Lock(networkSecurityGroupName)
		defer armMutexKV.Unlock(networkSecurityGroupName)
	}

	configs := d.Get("ip_configuration").(*schema.Set).List()
	namesToLock := make([]string, 0)

	for _, configRaw := range configs {
		data := configRaw.(map[string]interface{})

		subnet_id := data["subnet_id"].(string)
		subnetId, err := parseAzureResourceID(subnet_id)
		if err != nil {
			return err
		}
		subnetName := subnetId.Path["subnets"]
		virtualNetworkName := subnetId.Path["virtualNetworks"]
		namesToLock = append(namesToLock, subnetName)
		namesToLock = append(namesToLock, virtualNetworkName)
	}

	azureRMLockMultiple(&namesToLock)
	defer azureRMUnlockMultiple(&namesToLock)

	_, err = ifaceClient.Delete(resGroup, name, make(chan struct{}))

	return err
}

func resourceArmNetworkInterfaceIpConfigurationHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
	buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string)))
	if m["private_ip_address"] != nil {
		buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address"].(string)))
	}
	buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address_allocation"].(string)))
	if m["public_ip_address_id"] != nil {
		buf.WriteString(fmt.Sprintf("%s-", m["public_ip_address_id"].(string)))
	}
	if m["load_balancer_backend_address_pools_ids"] != nil {
		ids := m["load_balancer_backend_address_pools_ids"].(*schema.Set).List()
		for _, id := range ids {
			buf.WriteString(fmt.Sprintf("%d-", schema.HashString(id.(string))))
		}
	}
	if m["load_balancer_inbound_nat_rules_ids"] != nil {
		ids := m["load_balancer_inbound_nat_rules_ids"].(*schema.Set).List()
		for _, id := range ids {
			buf.WriteString(fmt.Sprintf("%d-", schema.HashString(id.(string))))
		}
	}

	return hashcode.String(buf.String())
}

func validateNetworkInterfacePrivateIpAddressAllocation(v interface{}, k string) (ws []string, errors []error) {
	value := strings.ToLower(v.(string))
	allocations := map[string]bool{
		"static":  true,
		"dynamic": true,
	}

	if !allocations[value] {
		errors = append(errors, fmt.Errorf("Network Interface Allocations can only be Static or Dynamic"))
	}
	return
}

func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]network.InterfaceIPConfiguration, *[]string, error) {
	configs := d.Get("ip_configuration").(*schema.Set).List()
	ipConfigs := make([]network.InterfaceIPConfiguration, 0, len(configs))
	namesToLock := make([]string, 0)

	for _, configRaw := range configs {
		data := configRaw.(map[string]interface{})

		subnet_id := data["subnet_id"].(string)
		private_ip_allocation_method := data["private_ip_address_allocation"].(string)

		var allocationMethod network.IPAllocationMethod
		switch strings.ToLower(private_ip_allocation_method) {
		case "dynamic":
			allocationMethod = network.Dynamic
		case "static":
			allocationMethod = network.Static
		default:
			return []network.InterfaceIPConfiguration{}, nil, fmt.Errorf(
				"valid values for private_ip_allocation_method are 'dynamic' and 'static' - got '%s'",
				private_ip_allocation_method)
		}

		properties := network.InterfaceIPConfigurationPropertiesFormat{
			Subnet: &network.Subnet{
				ID: &subnet_id,
			},
			PrivateIPAllocationMethod: allocationMethod,
		}

		subnetId, err := parseAzureResourceID(subnet_id)
		if err != nil {
			return []network.InterfaceIPConfiguration{}, nil, err
		}
		subnetName := subnetId.Path["subnets"]
		virtualNetworkName := subnetId.Path["virtualNetworks"]
		namesToLock = append(namesToLock, subnetName)
		namesToLock = append(namesToLock, virtualNetworkName)

		if v := data["private_ip_address"].(string); v != "" {
			properties.PrivateIPAddress = &v
		}

		if v := data["public_ip_address_id"].(string); v != "" {
			properties.PublicIPAddress = &network.PublicIPAddress{
				ID: &v,
			}
		}

		if v, ok := data["load_balancer_backend_address_pools_ids"]; ok {
			var ids []network.BackendAddressPool
			pools := v.(*schema.Set).List()
			for _, p := range pools {
				pool_id := p.(string)
				id := network.BackendAddressPool{
					ID: &pool_id,
				}

				ids = append(ids, id)
			}

			properties.LoadBalancerBackendAddressPools = &ids
		}

		if v, ok := data["load_balancer_inbound_nat_rules_ids"]; ok {
			var natRules []network.InboundNatRule
			rules := v.(*schema.Set).List()
			for _, r := range rules {
				rule_id := r.(string)
				rule := network.InboundNatRule{
					ID: &rule_id,
				}

				natRules = append(natRules, rule)
			}

			properties.LoadBalancerInboundNatRules = &natRules
		}

		name := data["name"].(string)
		ipConfig := network.InterfaceIPConfiguration{
			Name: &name,
			InterfaceIPConfigurationPropertiesFormat: &properties,
		}

		ipConfigs = append(ipConfigs, ipConfig)
	}

	return ipConfigs, &namesToLock, nil
}
<|endoftext|>


<commit_before>// +build windows

package cli

import (
	"context"

	"github.com/pkg/errors"
)

func (g *Git) fixConfigOSDep(ctx context.Context) error {
	if g.gpg == "" {
		return nil
	}

	if err := g.Cmd(ctx, "gitFixConfigOSDep", "config", "--local", "gpg.program", s.gpg); err != nil {
		return errors.Wrapf(err, "failed to set git config gpg.program")
	}
	return nil
}
<commit_msg>Fix typo<commit_after>// +build windows

package cli

import (
	"context"

	"github.com/pkg/errors"
)

func (g *Git) fixConfigOSDep(ctx context.Context) error {
	if g.gpg == "" {
		return nil
	}

	if err := g.Cmd(ctx, "gitFixConfigOSDep", "config", "--local", "gpg.program", g.gpg); err != nil {
		return errors.Wrapf(err, "failed to set git config gpg.program")
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/putsi/paparazzo.go"
	"time"
)

func main() {

	port := ":8080"
	user := ""
	pass := ""
	timeout := 5 * time.Second
	mjpegStream := "http://westunioncam.studentaffairs.duke.edu/mjpg/video.mjpg"
	imgPath := "/img.jpg"

	mp := mjpegproxy.NewMjpegproxy()

	mp.StartCrawling(mjpegStream, user, pass, timeout)
	mp.Serve(imgPath, port)

	block := make(chan bool)

	// time.Sleep(time.Second * 30)
	// mp.StopServing()
	// mp.StopCrawling()
	<-block

}
<commit_msg>Update demo.go<commit_after>package main

import (
	"github.com/putsi/paparazzo.go"
	"time"
)

func main() {

	// Local server settings
	imgPath := "/img.jpg"
	addr := ":8080"

	// MJPEG-stream settings
	user := ""
	pass := ""
	timeout := 5 * time.Second
	mjpegStream := "http://westunioncam.studentaffairs.duke.edu/mjpg/video.mjpg"

	mp := mjpegproxy.NewMjpegproxy()

	mp.StartCrawling(mjpegStream, user, pass, timeout)
	mp.Serve(imgPath, addr)

	block := make(chan bool)

	// time.Sleep(time.Second * 30)
	// mp.StopServing()
	// mp.StopCrawling()
	<-block

}
<|endoftext|>


<commit_before>package dice

import (
	"strings"
	"testing"
)

var (
	testDice      = "1d20"
	testBag       = []string{"1d20", "4d4", "6d6"}
	testBagMax    = 72
	testBagMin    = 11
	rollTests     = 1000000
	expectedStr   = "Expected [%s], got [%s]\n"
	outOfBoundStr = "%s is out of bounds: %d\n"
	badAggSetStr  = "%s should contain %d elements, has %d\n"
)

func TestNewDice(t *testing.T) {
	d, _ := NewDice(testDice)
	if d.String() != testDice {
		t.Fatalf(expectedStr, testDice, d.String())
	}
}

func TestDiceAdd(t *testing.T) {
	d, _ := NewDice("3d20")
	e := "4d20"
	d.Add(1)
	if d.String() != e {
		t.Fatalf(expectedStr, e, d.String())
	}
}

func TestDiceRemove(t *testing.T) {
	d, _ := NewDice("3d20")
	e := "2d20"
	d.Remove(1)
	if d.String() != e {
		t.Fatalf(expectedStr, e, d.String())
	}
}

func TestDiceRoll(t *testing.T) {
	d, _ := NewDice(testDice)
	for i := 0; i < rollTests; i++ {
		r, s := d.Roll()
		// test individual roll
		if r < 1 || r > d.sides {
			t.Fatalf(outOfBoundStr, testDice, r)
		}
		// test set
		if len(s) != d.number {
			t.Fatalf(badAggSetStr, s, d.number, len(s))
		}
	}
}

func TestNewBag(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := strings.Join(testBag, ", ")
	if b.String() != e {
		t.Fatalf(expectedStr, e, b)
	}
}

func TestNewBagMulti(t *testing.T) {
	b, _ := NewBag("1d20", "3d20", "8d10")
	e := "4d20, 8d10"
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagAdd(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := "2d20, 4d4, 6d6"
	b.Add(testDice)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}

	d, e := "3d10", e+", 3d10"
	b.Add(d)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagRemove(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := "0d20, 4d4, 6d6"
	b.Remove("2d20")
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}

	d, e := "2d4", "0d20, 2d4, 6d6"
	b.Remove(d)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagRoll(t *testing.T) {
	b, _ := NewBag(testBag...)
	for i := 0; i < rollTests; i++ {
		r, s := b.Roll()
		// Check rolls
		if r < testBagMin || r > testBagMax {
			t.Fatalf(outOfBoundStr, b, r)
		}
		// Check set maps
		if len(s) != len(testBag) {
			t.Fatalf(badAggSetStr, s, len(testBag), len(s))
		}
	}
}
<commit_msg>added min/max tests<commit_after>package dice

import (
	"strings"
	"testing"
)

var (
	testDice      = "1d20"
	testBag       = []string{"1d20", "4d4", "6d6"}
	testBagMax    = 72
	testBagMin    = 11
	rollTests     = 1000000
	expectedStr   = "Expected [%s], got [%s]\n"
	outOfBoundStr = "%s is out of bounds: %d\n"
	badAggSetStr  = "%s should contain %d elements, has %d\n"
)

func TestNewDice(t *testing.T) {
	d, _ := NewDice(testDice)
	if d.String() != testDice {
		t.Fatalf(expectedStr, testDice, d.String())
	}
}

func TestDiceAdd(t *testing.T) {
	d, _ := NewDice("3d20")
	e := "4d20"
	d.Add(1)
	if d.String() != e {
		t.Fatalf(expectedStr, e, d.String())
	}
}

func TestDiceRemove(t *testing.T) {
	d, _ := NewDice("3d20")
	e := "2d20"
	d.Remove(1)
	if d.String() != e {
		t.Fatalf(expectedStr, e, d.String())
	}
}

func TestDiceRoll(t *testing.T) {
	d, _ := NewDice(testDice)
	for i := 0; i < rollTests; i++ {
		r, s := d.Roll()
		// test individual roll
		if r < 1 || r > d.sides {
			t.Fatalf(outOfBoundStr, testDice, r)
		}
		// test set
		if len(s) != d.number {
			t.Fatalf(badAggSetStr, s, d.number, len(s))
		}
	}
}

func TestDiceMin(t *testing.T) {
	d, _ := NewDice(testDice)
	if d.Min() != 1 {
		t.Fatalf(expectedStr, 1, d.Min())
	}
}

func TestDiceMax(t *testing.T) {
	d, _ := NewDice(testDice)
	if d.Max() != 20 {
		t.Fatalf(expectedStr, 20, d.Max())
	}
}

func TestNewBag(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := strings.Join(testBag, ", ")
	if b.String() != e {
		t.Fatalf(expectedStr, e, b)
	}
}

func TestNewBagMulti(t *testing.T) {
	b, _ := NewBag("1d20", "3d20", "8d10")
	e := "4d20, 8d10"
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagAdd(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := "2d20, 4d4, 6d6"
	b.Add(testDice)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}

	d, e := "3d10", e+", 3d10"
	b.Add(d)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagRemove(t *testing.T) {
	b, _ := NewBag(testBag...)
	e := "0d20, 4d4, 6d6"
	b.Remove("2d20")
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}

	d, e := "2d4", "0d20, 2d4, 6d6"
	b.Remove(d)
	if b.String() != e {
		t.Fatalf(expectedStr, e, b.String())
	}
}

func TestBagRoll(t *testing.T) {
	b, _ := NewBag(testBag...)
	for i := 0; i < rollTests; i++ {
		r, s := b.Roll()
		// Check rolls
		if r < testBagMin || r > testBagMax {
			t.Fatalf(outOfBoundStr, b, r)
		}
		// Check set maps
		if len(s) != len(testBag) {
			t.Fatalf(badAggSetStr, s, len(testBag), len(s))
		}
	}
}

func TestBagMin(t *testing.T) {
	b, _ := NewBag(testBag...)
	if b.Min() != 11 {
		t.Fatalf(expectedStr, 11, b.Min())
	}
}

func TestBagMax(t *testing.T) {
	b, _ := NewBag(testBag...)
	if b.Max() != 72 {
		t.Fatalf(expectedStr, 72, b.Max())
	}
}
<|endoftext|>