<commit_before>package vmwarevsphere

import (
	"fmt"
	"path/filepath"

	"github.com/rancher/machine/libmachine/log"
	"github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/object"
	"github.com/vmware/govmomi/vapi/library"
	vapifinder "github.com/vmware/govmomi/vapi/library/finder"
	"github.com/vmware/govmomi/vapi/vcenter"
	"github.com/vmware/govmomi/vim25/soap"
	"github.com/vmware/govmomi/vim25/types"
)

func (d *Driver) preCreate() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	d.finder = find.NewFinder(c.Client, true)

	d.datacenter, err = d.finder.DatacenterOrDefault(d.getCtx(), d.Datacenter)
	if err != nil {
		return err
	}

	d.finder.SetDatacenter(d.datacenter)
	for _, netName := range d.Networks {
		net, err := d.finder.NetworkOrDefault(d.getCtx(), netName)
		if err != nil {
			return err
		}
		d.networks[netName] = net
	}

	if d.HostSystem != "" {
		var err error
		d.hostsystem, err = d.finder.HostSystemOrDefault(d.getCtx(), d.HostSystem)
		if err != nil {
			return err
		}
	}

	if d.Pool != "" {
		// Find specified Resource Pool
		d.resourcepool, err = d.finder.ResourcePool(d.getCtx(), d.Pool)
		if err != nil {
			return err
		}
	} else if d.HostSystem != "" {
		// Pick default Resource Pool for Host System
		d.resourcepool, err = d.hostsystem.ResourcePool(d.getCtx())
		if err != nil {
			return err
		}
	} else {
		// Pick the default Resource Pool for the Datacenter.
		d.resourcepool, err = d.finder.DefaultResourcePool(d.getCtx())
		if err != nil {
			return err
		}
	}

	return nil
}

func (d *Driver) postCreate(vm *object.VirtualMachine) error {
	if err := d.addConfigParams(vm); err != nil {
		return err
	}

	if err := d.cloudInit(vm); err != nil {
		return err
	}

	if err := d.addTags(vm); err != nil {
		return err
	}

	if err := d.addCustomAttributes(vm); err != nil {
		return err
	}

	return d.Start()
}

func (d *Driver) createLegacy() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	spec := types.VirtualMachineConfigSpec{
		Name:       d.MachineName,
		GuestId:    "otherLinux64Guest",
		NumCPUs:    int32(d.CPU),
		MemoryMB:   int64(d.Memory),
		VAppConfig: d.getVAppConfig(),
	}

	scsi, err := object.SCSIControllerTypes().CreateSCSIController("pvscsi")
	if err != nil {
		return err
	}

	spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{
		Operation: types.VirtualDeviceConfigSpecOperationAdd,
		Device:    scsi,
	})

	folder, err := d.findFolder()
	if err != nil {
		return err
	}

	ds, err := d.getDatastore(&spec)
	if err != nil {
		return err
	}

	spec.Files = &types.VirtualMachineFileInfo{
		VmPathName: fmt.Sprintf("[%s]", ds.Name()),
	}

	task, err := folder.CreateVM(d.getCtx(), spec, d.resourcepool, d.hostsystem)
	if err != nil {
		return err
	}

	info, err := task.WaitForResult(d.getCtx(), nil)
	if err != nil {
		return err
	}

	log.Infof("Uploading Boot2docker ISO ...")
	vm := object.NewVirtualMachine(c.Client, info.Result.(types.ManagedObjectReference))
	vmPath, err := d.getVmFolder(vm)
	if err != nil {
		return err
	}

	dsurl := ds.NewURL(filepath.Join(vmPath, isoFilename))
	p := soap.DefaultUpload
	if err = c.Client.UploadFile(d.getCtx(), d.ISO, dsurl, &p); err != nil {
		return err
	}

	devices, err := vm.Device(d.getCtx())
	if err != nil {
		return err
	}

	var add []types.BaseVirtualDevice
	controller, err := devices.FindDiskController("scsi")
	if err != nil {
		return err
	}

	disk := devices.CreateDisk(controller, ds.Reference(),
		ds.Path(fmt.Sprintf("%s/%s.vmdk", vmPath, d.MachineName)))

	// Convert MB to KB
	disk.CapacityInKB = int64(d.DiskSize) * 1024
	add = append(add, disk)
	ide, err := devices.FindIDEController("")
	if err != nil {
		return err
	}

	cdrom, err := devices.CreateCdrom(ide)
	if err != nil {
		return err
	}

	add = append(add, devices.InsertIso(cdrom, ds.Path(fmt.Sprintf("%s/%s", vmPath, isoFilename))))
	if err := vm.AddDevice(d.getCtx(), add...); err != nil {
		return err
	}

	if err := d.addNetworks(vm, d.networks); err != nil {
		return err
	}

	err = d.postCreate(vm)
	if err != nil {
		return err
	}

	if err := d.provisionVm(vm); err != nil {
		return err
	}

	return nil
}

func (d *Driver) createFromVmName() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	var info *types.TaskInfo
	var loc types.VirtualMachineRelocateSpec

	if d.resourcepool != nil {
		pool := d.resourcepool.Reference()
		loc.Pool = &pool
	}

	if d.hostsystem != nil {
		host := d.hostsystem.Reference()
		loc.Host = &host
	}

	spec := types.VirtualMachineCloneSpec{
		Location: loc,
		Config: &types.VirtualMachineConfigSpec{
			NumCPUs:    int32(d.CPU),
			MemoryMB:   int64(d.Memory),
			VAppConfig: d.getVAppConfig(),
		},
	}

	ds, err := d.getDatastore(spec.Config)
	if err != nil {
		return err
	}

	spec.Config.Files = &types.VirtualMachineFileInfo{
		VmPathName: fmt.Sprintf("[%s]", ds.Name()),
	}

	dsref := ds.Reference()
	spec.Location.Datastore = &dsref

	vm2Clone, err := d.fetchVM(d.CloneFrom)
	if err != nil {
		return err
	}

	folder, err := d.findFolder()
	if err != nil {
		return err
	}

	task, err := vm2Clone.Clone(d.getCtx(), folder, d.MachineName, spec)
	if err != nil {
		return err
	}

	info, err = task.WaitForResult(d.getCtx(), nil)
	if err != nil {
		return err
	}

	// Retrieve the new VM
	vm := object.NewVirtualMachine(c.Client, info.Result.(types.ManagedObjectReference))
	if err := d.addNetworks(vm, d.networks); err != nil {
		return err
	}

	if err := d.resizeDisk(vm); err != nil {
		return err
	}

	return d.postCreate(vm)
}

func (d *Driver) createFromLibraryName() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	folders, err := d.datacenter.Folders(d.getCtx())
	if err != nil {
		return err
	}

	libManager := library.NewManager(d.getRestLogin(c.Client))
	if err := libManager.Login(d.getCtx(), d.getUserInfo()); err != nil {
		return err
	}

	query := fmt.Sprintf("/%s/%s", d.ContentLibrary, d.CloneFrom)
	results, err := vapifinder.NewFinder(libManager).Find(d.getCtx(), query)
	if err != nil {
		return err
	}

	if len(results) < 1 {
		return fmt.Errorf("No results found in content library: %s", d.CloneFrom)
	}

	if len(results) > 1 {
		return fmt.Errorf("More than one result returned from finder query: %s", d.CloneFrom)
	}

	item, ok := results[0].GetResult().(library.Item)
	if !ok {
		return fmt.Errorf("Content Library item is not a template: %q is a %T", d.CloneFrom, item)
	}

	var nets []vcenter.NetworkMapping
	for k, n := range d.networks {
		nets = append(nets, vcenter.NetworkMapping{
			Key:   k,
			Value: n.Reference().Value,
		})
	}

	hostId := ""
	if d.hostsystem != nil {
		hostId = d.hostsystem.Reference().Value
	}

	ds, err := d.getDatastore(&types.VirtualMachineConfigSpec{})
	if err != nil {
		return err
	}

	deploy := vcenter.Deploy{
		DeploymentSpec: vcenter.DeploymentSpec{
			Name:                d.MachineName,
			DefaultDatastoreID:  ds.Reference().Value,
			AcceptAllEULA:       true,
			NetworkMappings:     nets,
			StorageProvisioning: "thin",
		},
		Target: vcenter.Target{
			ResourcePoolID: d.resourcepool.Reference().Value,
			HostID:         hostId,
			FolderID:       folders.VmFolder.Reference().Value,
		},
	}

	m := vcenter.NewManager(libManager.Client)

	ref, err := m.DeployLibraryItem(d.getCtx(), item.ID, deploy)
	if err != nil {
		return err
	}

	obj, err := d.finder.ObjectReference(d.getCtx(), *ref)
	if err != nil {
		return err
	}

	vm := obj.(*object.VirtualMachine)
	if err := d.resizeDisk(vm); err != nil {
		return err
	}

	return d.postCreate(vm)
}
<commit_msg>VM folder path fix<commit_after>package vmwarevsphere

import (
	"fmt"
	"path/filepath"

	"github.com/rancher/machine/libmachine/log"
	"github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/object"
	"github.com/vmware/govmomi/vapi/library"
	vapifinder "github.com/vmware/govmomi/vapi/library/finder"
	"github.com/vmware/govmomi/vapi/vcenter"
	"github.com/vmware/govmomi/vim25/soap"
	"github.com/vmware/govmomi/vim25/types"
)

func (d *Driver) preCreate() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	d.finder = find.NewFinder(c.Client, true)

	d.datacenter, err = d.finder.DatacenterOrDefault(d.getCtx(), d.Datacenter)
	if err != nil {
		return err
	}

	d.finder.SetDatacenter(d.datacenter)
	for _, netName := range d.Networks {
		net, err := d.finder.NetworkOrDefault(d.getCtx(), netName)
		if err != nil {
			return err
		}
		d.networks[netName] = net
	}

	if d.HostSystem != "" {
		var err error
		d.hostsystem, err = d.finder.HostSystemOrDefault(d.getCtx(), d.HostSystem)
		if err != nil {
			return err
		}
	}

	if d.Pool != "" {
		// Find specified Resource Pool
		d.resourcepool, err = d.finder.ResourcePool(d.getCtx(), d.Pool)
		if err != nil {
			return err
		}
	} else if d.HostSystem != "" {
		// Pick default Resource Pool for Host System
		d.resourcepool, err = d.hostsystem.ResourcePool(d.getCtx())
		if err != nil {
			return err
		}
	} else {
		// Pick the default Resource Pool for the Datacenter.
		d.resourcepool, err = d.finder.DefaultResourcePool(d.getCtx())
		if err != nil {
			return err
		}
	}

	return nil
}

func (d *Driver) postCreate(vm *object.VirtualMachine) error {
	if err := d.addConfigParams(vm); err != nil {
		return err
	}

	if err := d.cloudInit(vm); err != nil {
		return err
	}

	if err := d.addTags(vm); err != nil {
		return err
	}

	if err := d.addCustomAttributes(vm); err != nil {
		return err
	}

	return d.Start()
}

func (d *Driver) createLegacy() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	spec := types.VirtualMachineConfigSpec{
		Name:       d.MachineName,
		GuestId:    "otherLinux64Guest",
		NumCPUs:    int32(d.CPU),
		MemoryMB:   int64(d.Memory),
		VAppConfig: d.getVAppConfig(),
	}

	scsi, err := object.SCSIControllerTypes().CreateSCSIController("pvscsi")
	if err != nil {
		return err
	}

	spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{
		Operation: types.VirtualDeviceConfigSpecOperationAdd,
		Device:    scsi,
	})

	folder, err := d.findFolder()
	if err != nil {
		return err
	}

	ds, err := d.getDatastore(&spec)
	if err != nil {
		return err
	}

	spec.Files = &types.VirtualMachineFileInfo{
		VmPathName: fmt.Sprintf("[%s]", ds.Name()),
	}

	task, err := folder.CreateVM(d.getCtx(), spec, d.resourcepool, d.hostsystem)
	if err != nil {
		return err
	}

	info, err := task.WaitForResult(d.getCtx(), nil)
	if err != nil {
		return err
	}

	log.Infof("Uploading Boot2docker ISO ...")
	vm := object.NewVirtualMachine(c.Client, info.Result.(types.ManagedObjectReference))
	vmPath, err := d.getVmFolder(vm)
	if err != nil {
		return err
	}

	dsurl := ds.NewURL(filepath.Join(vmPath, isoFilename))
	p := soap.DefaultUpload
	if err = c.Client.UploadFile(d.getCtx(), d.ISO, dsurl, &p); err != nil {
		return err
	}

	devices, err := vm.Device(d.getCtx())
	if err != nil {
		return err
	}

	var add []types.BaseVirtualDevice
	controller, err := devices.FindDiskController("scsi")
	if err != nil {
		return err
	}

	disk := devices.CreateDisk(controller, ds.Reference(),
		ds.Path(fmt.Sprintf("%s/%s.vmdk", vmPath, d.MachineName)))

	// Convert MB to KB
	disk.CapacityInKB = int64(d.DiskSize) * 1024
	add = append(add, disk)
	ide, err := devices.FindIDEController("")
	if err != nil {
		return err
	}

	cdrom, err := devices.CreateCdrom(ide)
	if err != nil {
		return err
	}

	add = append(add, devices.InsertIso(cdrom, ds.Path(fmt.Sprintf("%s/%s", vmPath, isoFilename))))
	if err := vm.AddDevice(d.getCtx(), add...); err != nil {
		return err
	}

	if err := d.addNetworks(vm, d.networks); err != nil {
		return err
	}

	err = d.postCreate(vm)
	if err != nil {
		return err
	}

	if err := d.provisionVm(vm); err != nil {
		return err
	}

	return nil
}

func (d *Driver) createFromVmName() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	var info *types.TaskInfo
	var loc types.VirtualMachineRelocateSpec

	if d.resourcepool != nil {
		pool := d.resourcepool.Reference()
		loc.Pool = &pool
	}

	if d.hostsystem != nil {
		host := d.hostsystem.Reference()
		loc.Host = &host
	}

	spec := types.VirtualMachineCloneSpec{
		Location: loc,
		Config: &types.VirtualMachineConfigSpec{
			NumCPUs:    int32(d.CPU),
			MemoryMB:   int64(d.Memory),
			VAppConfig: d.getVAppConfig(),
		},
	}

	ds, err := d.getDatastore(spec.Config)
	if err != nil {
		return err
	}

	spec.Config.Files = &types.VirtualMachineFileInfo{
		VmPathName: fmt.Sprintf("[%s]", ds.Name()),
	}

	dsref := ds.Reference()
	spec.Location.Datastore = &dsref

	vm2Clone, err := d.fetchVM(d.CloneFrom)
	if err != nil {
		return err
	}

	folder, err := d.findFolder()
	if err != nil {
		return err
	}

	task, err := vm2Clone.Clone(d.getCtx(), folder, d.MachineName, spec)
	if err != nil {
		return err
	}

	info, err = task.WaitForResult(d.getCtx(), nil)
	if err != nil {
		return err
	}

	// Retrieve the new VM
	vm := object.NewVirtualMachine(c.Client, info.Result.(types.ManagedObjectReference))
	if err := d.addNetworks(vm, d.networks); err != nil {
		return err
	}

	if err := d.resizeDisk(vm); err != nil {
		return err
	}

	return d.postCreate(vm)
}

func (d *Driver) createFromLibraryName() error {
	c, err := d.getSoapClient()
	if err != nil {
		return err
	}

	folder, err := d.findFolder()
	if err != nil {
		return err
	}

	libManager := library.NewManager(d.getRestLogin(c.Client))
	if err := libManager.Login(d.getCtx(), d.getUserInfo()); err != nil {
		return err
	}

	query := fmt.Sprintf("/%s/%s", d.ContentLibrary, d.CloneFrom)
	results, err := vapifinder.NewFinder(libManager).Find(d.getCtx(), query)
	if err != nil {
		return err
	}

	if len(results) < 1 {
		return fmt.Errorf("No results found in content library: %s", d.CloneFrom)
	}

	if len(results) > 1 {
		return fmt.Errorf("More than one result returned from finder query: %s", d.CloneFrom)
	}

	item, ok := results[0].GetResult().(library.Item)
	if !ok {
		return fmt.Errorf("Content Library item is not a template: %q is a %T", d.CloneFrom, item)
	}

	var nets []vcenter.NetworkMapping
	for k, n := range d.networks {
		nets = append(nets, vcenter.NetworkMapping{
			Key:   k,
			Value: n.Reference().Value,
		})
	}

	hostId := ""
	if d.hostsystem != nil {
		hostId = d.hostsystem.Reference().Value
	}

	ds, err := d.getDatastore(&types.VirtualMachineConfigSpec{})
	if err != nil {
		return err
	}

	deploy := vcenter.Deploy{
		DeploymentSpec: vcenter.DeploymentSpec{
			Name:                d.MachineName,
			DefaultDatastoreID:  ds.Reference().Value,
			AcceptAllEULA:       true,
			NetworkMappings:     nets,
			StorageProvisioning: "thin",
		},
		Target: vcenter.Target{
			ResourcePoolID: d.resourcepool.Reference().Value,
			HostID:         hostId,
			FolderID:       folder.Reference().Value,
		},
	}

	m := vcenter.NewManager(libManager.Client)

	ref, err := m.DeployLibraryItem(d.getCtx(), item.ID, deploy)
	if err != nil {
		return err
	}

	obj, err := d.finder.ObjectReference(d.getCtx(), *ref)
	if err != nil {
		return err
	}

	vm := obj.(*object.VirtualMachine)
	if err := d.resizeDisk(vm); err != nil {
		return err
	}

	return d.postCreate(vm)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 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 metrics

import (
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

// ValueType is an enumeration of metric types that represent a simple value.
type ValueType int

// Possible values for the ValueType enum.
const (
	_ ValueType = iota
	CounterValue
	GaugeValue
	UntypedValue
)

func (vt *ValueType) toPromValueType() prometheus.ValueType {
	return prometheus.ValueType(*vt)
}

// NewLazyConstMetric is a helper of MustNewConstMetric.
//
// Note: If the metrics described by the desc is hidden, the metrics will not be created.
func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
	if desc.IsHidden() {
		return nil
	}
	return prometheus.MustNewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
}

// NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp.
//
// Warning: the Metric 'm' must be the one created by NewLazyConstMetric(),
//
//	otherwise, no stability guarantees would be offered.
func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric {
	if m == nil {
		return nil
	}

	return prometheus.NewMetricWithTimestamp(t, m)
}
<commit_msg>component-base/metrics: Add NewConstMetric function<commit_after>/*
Copyright 2019 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 metrics

import (
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

// ValueType is an enumeration of metric types that represent a simple value.
type ValueType int

// Possible values for the ValueType enum.
const (
	_ ValueType = iota
	CounterValue
	GaugeValue
	UntypedValue
)

func (vt *ValueType) toPromValueType() prometheus.ValueType {
	return prometheus.ValueType(*vt)
}

// NewLazyConstMetric is a helper of MustNewConstMetric.
//
// Note: If the metrics described by the desc is hidden, the metrics will not be created.
func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
	if desc.IsHidden() {
		return nil
	}
	return prometheus.MustNewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
}

// NewConstMetric is a helper of NewConstMetric.
//
// Note: If the metrics described by the desc is hidden, the metrics will not be created.
func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
	if desc.IsHidden() {
		return nil, nil
	}
	return prometheus.NewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
}

// NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp.
//
// Warning: the Metric 'm' must be the one created by NewLazyConstMetric(),
//
//	otherwise, no stability guarantees would be offered.
func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric {
	if m == nil {
		return nil
	}

	return prometheus.NewMetricWithTimestamp(t, m)
}
<|endoftext|>


<commit_before>package schema

import (
	"fmt"
	"strings"
	"time"
)

// Go has a different date formatting style. Converting to the one
// used in https://specs.frictionlessdata.io/table-schema/#date
// https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
var strftimeToGoConversionTable = map[string]string{
	"%d":  "02",
	"%-d": "2",
	"%B":  "January",
	"%b":  "Jan",
	"%h":  "Jan",
	"%m":  "01",
	"%_m": " 1",
	"%-m": "1",
	"%Y":  "2006",
	"%y":  "06",
	"%H":  "15",
	"%I":  "03",
	"%M":  "04",
	"%S":  "05",
	"%f":  "999999",
	"%z":  "Z0700",
	"%:z": "Z07:00",
	"%Z":  "MST",
	"%p":  "PM",
}

func castDate(format, value string) (time.Time, error) {
	return decodeDefaultOrCustomTime("2006-01-02", format, value)
}

func decodeYearMonth(value string, c Constraints) (time.Time, error) {
	y, err := decodeYearMonthWithoutChecks(value)
	if err != nil {
		return time.Now(), err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeYearMonthWithoutChecks(c.Maximum)
		if err != nil {
			return time.Now(), err
		}
	}
	if c.Minimum != "" {
		min, err = decodeYearMonthWithoutChecks(c.Minimum)
		if err != nil {
			return time.Now(), err
		}
	}
	return checkConstraints(y, max, min, YearMonthType)
}

func decodeYearMonthWithoutChecks(value string) (time.Time, error) {
	return time.Parse("2006-01", value)
}

func decodeYearWithoutChecks(value string) (time.Time, error) {
	return time.Parse("2006", value)
}

func decodeYear(value string, c Constraints) (time.Time, error) {
	y, err := decodeYearWithoutChecks(value)
	if err != nil {
		return time.Now(), err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeYearWithoutChecks(c.Maximum)
		if err != nil {
			return time.Now(), err
		}
	}
	if c.Minimum != "" {
		min, err = decodeYearWithoutChecks(c.Minimum)
		if err != nil {
			return time.Now(), err
		}
	}
	return checkConstraints(y, max, min, YearType)
}

func scastDateTime(format, value string) (time.Time, error) {
	return decodeDefaultOrCustomTime(time.RFC3339, format, value)
}

func decodeDateTime(value string, c Constraints) (time.Time, error) {
	dt, err := decodeDateTimeWithoutChecks(value)
	if err != nil {
		return time.Time{}, err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeDateTimeWithoutChecks(c.Maximum)
		if err != nil {
			return time.Time{}, err
		}
	}
	if c.Minimum != "" {
		min, err = decodeDateTimeWithoutChecks(c.Minimum)
		if err != nil {
			return time.Time{}, err
		}
	}
	return checkConstraints(dt, max, min, DateTimeType)
}

func decodeDateTimeWithoutChecks(value string) (time.Time, error) {
	return time.Parse(time.RFC3339, value)
}

func checkConstraints(v, max, min time.Time, t string) (time.Time, error) {
	if !max.IsZero() && v.After(max) {
		return time.Now(), fmt.Errorf("constraint check error: %s:%v > maximum:%v", t, v, max)
	}
	if !min.IsZero() && v.Before(min) {
		return time.Now(), fmt.Errorf("constraint check error: %s:%v < minimum:%v", t, v, min)
	}
	return v, nil
}

func decodeDefaultOrCustomTime(defaultFormat, format, value string) (time.Time, error) {
	switch format {
	case "", defaultFieldFormat:
		t, err := time.Parse(defaultFormat, value)
		if err != nil {
			return time.Now(), err
		}
		return t.In(time.UTC), nil
	case AnyDateFormat:
		return time.Unix(0, 0), fmt.Errorf("any date format not yet supported. Please file an issue at github.com/frictionlessdata/tableschema-go")
	}
	goFormat := format
	for f, s := range strftimeToGoConversionTable {
		goFormat = strings.Replace(goFormat, f, s, -1)
	}
	t, err := time.Parse(goFormat, value)
	if err != nil {
		return time.Now(), err
	}
	return t.In(time.UTC), nil
}
<commit_msg>removed unused function<commit_after>package schema

import (
	"fmt"
	"strings"
	"time"
)

// Go has a different date formatting style. Converting to the one
// used in https://specs.frictionlessdata.io/table-schema/#date
// https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
var strftimeToGoConversionTable = map[string]string{
	"%d":  "02",
	"%-d": "2",
	"%B":  "January",
	"%b":  "Jan",
	"%h":  "Jan",
	"%m":  "01",
	"%_m": " 1",
	"%-m": "1",
	"%Y":  "2006",
	"%y":  "06",
	"%H":  "15",
	"%I":  "03",
	"%M":  "04",
	"%S":  "05",
	"%f":  "999999",
	"%z":  "Z0700",
	"%:z": "Z07:00",
	"%Z":  "MST",
	"%p":  "PM",
}

func castDate(format, value string) (time.Time, error) {
	return decodeDefaultOrCustomTime("2006-01-02", format, value)
}

func decodeYearMonth(value string, c Constraints) (time.Time, error) {
	y, err := decodeYearMonthWithoutChecks(value)
	if err != nil {
		return time.Now(), err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeYearMonthWithoutChecks(c.Maximum)
		if err != nil {
			return time.Now(), err
		}
	}
	if c.Minimum != "" {
		min, err = decodeYearMonthWithoutChecks(c.Minimum)
		if err != nil {
			return time.Now(), err
		}
	}
	return checkConstraints(y, max, min, YearMonthType)
}

func decodeYearMonthWithoutChecks(value string) (time.Time, error) {
	return time.Parse("2006-01", value)
}

func decodeYearWithoutChecks(value string) (time.Time, error) {
	return time.Parse("2006", value)
}

func decodeYear(value string, c Constraints) (time.Time, error) {
	y, err := decodeYearWithoutChecks(value)
	if err != nil {
		return time.Now(), err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeYearWithoutChecks(c.Maximum)
		if err != nil {
			return time.Now(), err
		}
	}
	if c.Minimum != "" {
		min, err = decodeYearWithoutChecks(c.Minimum)
		if err != nil {
			return time.Now(), err
		}
	}
	return checkConstraints(y, max, min, YearType)
}

func decodeDateTime(value string, c Constraints) (time.Time, error) {
	dt, err := decodeDateTimeWithoutChecks(value)
	if err != nil {
		return time.Time{}, err
	}
	var max, min time.Time
	if c.Maximum != "" {
		max, err = decodeDateTimeWithoutChecks(c.Maximum)
		if err != nil {
			return time.Time{}, err
		}
	}
	if c.Minimum != "" {
		min, err = decodeDateTimeWithoutChecks(c.Minimum)
		if err != nil {
			return time.Time{}, err
		}
	}
	return checkConstraints(dt, max, min, DateTimeType)
}

func decodeDateTimeWithoutChecks(value string) (time.Time, error) {
	return time.Parse(time.RFC3339, value)
}

func checkConstraints(v, max, min time.Time, t string) (time.Time, error) {
	if !max.IsZero() && v.After(max) {
		return time.Now(), fmt.Errorf("constraint check error: %s:%v > maximum:%v", t, v, max)
	}
	if !min.IsZero() && v.Before(min) {
		return time.Now(), fmt.Errorf("constraint check error: %s:%v < minimum:%v", t, v, min)
	}
	return v, nil
}

func decodeDefaultOrCustomTime(defaultFormat, format, value string) (time.Time, error) {
	switch format {
	case "", defaultFieldFormat:
		t, err := time.Parse(defaultFormat, value)
		if err != nil {
			return time.Now(), err
		}
		return t.In(time.UTC), nil
	case AnyDateFormat:
		return time.Unix(0, 0), fmt.Errorf("any date format not yet supported. Please file an issue at github.com/frictionlessdata/tableschema-go")
	}
	goFormat := format
	for f, s := range strftimeToGoConversionTable {
		goFormat = strings.Replace(goFormat, f, s, -1)
	}
	t, err := time.Parse(goFormat, value)
	if err != nil {
		return time.Now(), err
	}
	return t.In(time.UTC), nil
}
<|endoftext|>


<commit_before>package schemas

//  This method takes the topic name as a parameter
//  and determines the struct to return as a schema.
func IdentifySchema(topicName string) interface{} {
    switch topicName {
    case "tx-closed":
        return &TxClosed{}
    case "document-generation-started":
        return &DocumentGenerationStarted{}
    case "document-generation-completed":
        return &DocumentGenerationCompleted{}
    case "email-send":
        return &EmailSend{}
    case "render-submitted-data-document":
        return &RenderSubmittedDataDocument{}
    case "filing-received":
        return &FilingReceived{}
    }
    return nil
}<commit_msg>Add filing-procesed to switch case<commit_after>package schemas

//  This method takes the topic name as a parameter
//  and determines the struct to return as a schema.
func IdentifySchema(topicName string) interface{} {
    switch topicName {
    case "tx-closed":
        return &TxClosed{}
    case "document-generation-started":
        return &DocumentGenerationStarted{}
    case "document-generation-completed":
        return &DocumentGenerationCompleted{}
    case "email-send":
        return &EmailSend{}
    case "render-submitted-data-document":
        return &RenderSubmittedDataDocument{}
    case "filing-received":
        return &FilingReceived{}
    case "filing-processed":
        return &FilingProcessed{}
    }
    return nil
}<|endoftext|>


<commit_before>// RTLAMR - An rtl-sdr receiver for smart meters operating in the 900MHz ISM band.
// Copyright (C) 2015 Douglas Hall
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package scmplus

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"strconv"

	"github.com/bemasher/rtlamr/crc"
	"github.com/bemasher/rtlamr/decode"
	"github.com/bemasher/rtlamr/parse"
)

func init() {
	parse.Register("scm+", NewParser)
}

func NewPacketConfig(symbolLength int) (cfg decode.PacketConfig) {
	cfg.CenterFreq = 912600155
	cfg.DataRate = 32768
	cfg.SymbolLength = symbolLength
	cfg.PreambleSymbols = 16
	cfg.PacketSymbols = 16 * 8
	cfg.Preamble = "0001011010100011"

	return
}

type Parser struct {
	decode.Decoder
	crc.CRC
}

func (p Parser) Dec() decode.Decoder {
	return p.Decoder
}

func (p *Parser) Cfg() *decode.PacketConfig {
	return &p.Decoder.Cfg
}

func NewParser(symbolLength, decimation int) (p parse.Parser) {
	return &Parser{
		decode.NewDecoder(NewPacketConfig(symbolLength), decimation),
		crc.NewCRC("CCITT", 0xFFFF, 0x1021, 0x1D0F),
	}
}

func (p Parser) Parse(indices []int) (msgs []parse.Message) {
	seen := make(map[string]bool)

	for _, pkt := range p.Decoder.Slice(indices) {
		s := string(pkt)
		if seen[s] {
			continue
		}
		seen[s] = true

		data := parse.NewDataFromBytes(pkt)

		// If the checksum fails, bail.
		if residue := p.Checksum(data.Bytes[2:]); residue != p.Residue {
			continue
		}

		scm := NewSCM(data)

		// If the meter id is 0, bail.
		if scm.EndpointID == 0 {
			continue
		}

		msgs = append(msgs, scm)
	}

	return
}

// Standard Consumption Message Plus
type SCM struct {
	FrameSync    uint16 `xml:",attr"`
	ProtocolID   uint8  `xml:",attr"`
	EndpointType uint8  `xml:",attr"`
	EndpointID   uint32 `xml:",attr"`
	Consumption  uint32 `xml:",attr"`
	Tamper       uint16 `xml:",attr"`
	PacketCRC    uint16 `xml:"Checksum,attr",json:"Checksum"`
}

func NewSCM(data parse.Data) (scm SCM) {
	binary.Read(bytes.NewReader(data.Bytes), binary.BigEndian, &scm)

	return
}

func (scm SCM) MsgType() string {
	return "SCM+"
}

func (scm SCM) MeterID() uint32 {
	return scm.EndpointID
}

func (scm SCM) MeterType() uint8 {
	return scm.EndpointType
}

func (scm SCM) Checksum() []byte {
	checksum := make([]byte, 2)
	binary.BigEndian.PutUint16(checksum, scm.PacketCRC)
	return checksum
}

func (scm SCM) String() string {
	return fmt.Sprintf("{ProtocolID:0x%02X EndpointType:0x%02X EndpointID:%10d Consumption:%10d Tamper:0x%04X PacketCRC:0x%04X}",
		scm.ProtocolID,
		scm.EndpointType,
		scm.EndpointID,
		scm.Consumption,
		scm.Tamper,
		scm.PacketCRC,
	)
}

func (scm SCM) Record() (r []string) {
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.FrameSync), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.ProtocolID), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.EndpointType), 16))
	r = append(r, strconv.FormatUint(uint64(scm.EndpointID), 10))
	r = append(r, strconv.FormatUint(uint64(scm.Consumption), 10))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.Tamper), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.PacketCRC), 16))

	return
}
<commit_msg>Add ProtocolID check to SCM+ decoder.<commit_after>// RTLAMR - An rtl-sdr receiver for smart meters operating in the 900MHz ISM band.
// Copyright (C) 2015 Douglas Hall
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package scmplus

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"strconv"

	"github.com/bemasher/rtlamr/crc"
	"github.com/bemasher/rtlamr/decode"
	"github.com/bemasher/rtlamr/parse"
)

func init() {
	parse.Register("scm+", NewParser)
}

func NewPacketConfig(symbolLength int) (cfg decode.PacketConfig) {
	cfg.CenterFreq = 912600155
	cfg.DataRate = 32768
	cfg.SymbolLength = symbolLength
	cfg.PreambleSymbols = 16
	cfg.PacketSymbols = 16 * 8
	cfg.Preamble = "0001011010100011"

	return
}

type Parser struct {
	decode.Decoder
	crc.CRC
}

func (p Parser) Dec() decode.Decoder {
	return p.Decoder
}

func (p *Parser) Cfg() *decode.PacketConfig {
	return &p.Decoder.Cfg
}

func NewParser(symbolLength, decimation int) (p parse.Parser) {
	return &Parser{
		decode.NewDecoder(NewPacketConfig(symbolLength), decimation),
		crc.NewCRC("CCITT", 0xFFFF, 0x1021, 0x1D0F),
	}
}

func (p Parser) Parse(indices []int) (msgs []parse.Message) {
	seen := make(map[string]bool)

	for _, pkt := range p.Decoder.Slice(indices) {
		s := string(pkt)
		if seen[s] {
			continue
		}
		seen[s] = true

		data := parse.NewDataFromBytes(pkt)

		// If the checksum fails, bail.
		if residue := p.Checksum(data.Bytes[2:]); residue != p.Residue {
			continue
		}

		scm := NewSCM(data)

		// If the meter id is 0, bail.
		if scm.EndpointID == 0 || scm.ProtocolID != 0x1E {
			continue
		}

		msgs = append(msgs, scm)
	}

	return
}

// Standard Consumption Message Plus
type SCM struct {
	FrameSync    uint16 `xml:",attr"`
	ProtocolID   uint8  `xml:",attr"`
	EndpointType uint8  `xml:",attr"`
	EndpointID   uint32 `xml:",attr"`
	Consumption  uint32 `xml:",attr"`
	Tamper       uint16 `xml:",attr"`
	PacketCRC    uint16 `xml:"Checksum,attr",json:"Checksum"`
}

func NewSCM(data parse.Data) (scm SCM) {
	binary.Read(bytes.NewReader(data.Bytes), binary.BigEndian, &scm)

	return
}

func (scm SCM) MsgType() string {
	return "SCM+"
}

func (scm SCM) MeterID() uint32 {
	return scm.EndpointID
}

func (scm SCM) MeterType() uint8 {
	return scm.EndpointType
}

func (scm SCM) Checksum() []byte {
	checksum := make([]byte, 2)
	binary.BigEndian.PutUint16(checksum, scm.PacketCRC)
	return checksum
}

func (scm SCM) String() string {
	return fmt.Sprintf("{ProtocolID:0x%02X EndpointType:0x%02X EndpointID:%10d Consumption:%10d Tamper:0x%04X PacketCRC:0x%04X}",
		scm.ProtocolID,
		scm.EndpointType,
		scm.EndpointID,
		scm.Consumption,
		scm.Tamper,
		scm.PacketCRC,
	)
}

func (scm SCM) Record() (r []string) {
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.FrameSync), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.ProtocolID), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.EndpointType), 16))
	r = append(r, strconv.FormatUint(uint64(scm.EndpointID), 10))
	r = append(r, strconv.FormatUint(uint64(scm.Consumption), 10))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.Tamper), 16))
	r = append(r, "0x"+strconv.FormatUint(uint64(scm.PacketCRC), 16))

	return
}
<|endoftext|>


<commit_before>package isolated

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

var _ = Describe("proxy", func() {
	var proxyURL string

	BeforeEach(func() {
		proxyURL = "http://127.0.0.1:9999"
	})

	Context("V2", func() {
		It("errors when proxy is not setup properly", func() {
			session := helpers.CFWithEnv(map[string]string{"https_proxy": proxyURL}, "api", apiURL)
			Eventually(session.Err).Should(Say("%s/v2/info.*proxy.*%s", apiURL, proxyURL))
			Eventually(session.Err).Should(Say("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection."))
			Eventually(session).Should(Exit(1))
		})
	})

	Context("V3", func() {
		It("errors when proxy is not setup properly", func() {
			session := helpers.CFWithEnv(map[string]string{"https_proxy": proxyURL}, "run-task", "app", "echo")
			Eventually(session.Err).Should(Say("Get %s: http: error connecting to proxy %s", apiURL, proxyURL))
			Eventually(session.Err).Should(Say("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection."))
			Eventually(session).Should(Exit(1))
		})
	})
})
<commit_msg>fixed v3 test<commit_after>package isolated

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

var _ = Describe("proxy", func() {
	var proxyURL string

	BeforeEach(func() {
		proxyURL = "http://127.0.0.1:9999"
	})

	Context("V2", func() {
		It("errors when proxy is not setup properly", func() {
			session := helpers.CFWithEnv(map[string]string{"https_proxy": proxyURL}, "api", apiURL)
			Eventually(session.Err).Should(Say("%s/v2/info.*proxy.*%s", apiURL, proxyURL))
			Eventually(session.Err).Should(Say("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection."))
			Eventually(session).Should(Exit(1))
		})
	})

	Context("V3", func() {
		It("errors when proxy is not setup properly", func() {
			session := helpers.CFWithEnv(map[string]string{"https_proxy": proxyURL}, "run-task", "app", "echo")
			Eventually(session.Err).Should(Say("%s.*proxy.*%s", apiURL, proxyURL))
			Eventually(session.Err).Should(Say("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection."))
			Eventually(session).Should(Exit(1))
		})
	})
})
<|endoftext|>


<commit_before>// Copyright (c) 2018 Cisco and/or its affiliates.
//
// 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 cryptodata

import (
	"github.com/ligato/cn-infra/db/keyval"
	"github.com/ligato/cn-infra/datasync"
)

// CoreBrokerWatcherWrapper wraps keyval.CoreBrokerWatcher with additional support of reading encrypted data
type CoreBrokerWatcherWrapper struct {
	// Wrapped CoreBrokerWatcher
	wrap keyval.CoreBrokerWatcher
	// Wrapped BytesBroker
	bytesWrap *BytesBrokerWrapper
	// Function used for decrypting arbitrary data later
	decryptArbitrary DecryptArbitrary
	// Decrypter is used to decrypt data
	decrypter Decrypter
}

// BytesBrokerWrapper wraps keyval.BytesBroker with additional support of reading encrypted data
type BytesBrokerWrapper struct {
	// Wrapped CoreBrokerWatcher
	wrap keyval.BytesBroker
	// Function used for decrypting arbitrary data later
	decryptArbitrary DecryptArbitrary
	// Decrypter is used to decrypt data
	decrypter Decrypter
}

// NewCoreBrokerWatcherWrapper creates wrapper for provided CoreBrokerWatcher, adding support for decrypting encrypted
// data
func NewCoreBrokerWatcherWrapper(cbw keyval.CoreBrokerWatcher, decrypter Decrypter, decryptArbitrary DecryptArbitrary) *CoreBrokerWatcherWrapper {
	return &CoreBrokerWatcherWrapper{
		wrap:             cbw,
		decryptArbitrary: decryptArbitrary,
		decrypter:        decrypter,
		bytesWrap: &BytesBrokerWrapper{
			wrap:             cbw,
			decryptArbitrary: decryptArbitrary,
			decrypter:        decrypter,
		},
	}
}

// Watch starts subscription for changes associated with the selected keys.
// Watch events will be delivered to callback (not channel) <respChan>.
// Channel <closeChan> can be used to close watching on respective key
func (cbw *CoreBrokerWatcherWrapper) Watch(respChan func(keyval.BytesWatchResp), closeChan chan string, keys ...string) error {
	return cbw.wrap.Watch(respChan, closeChan, keys...)
}

// NewBroker returns a BytesBroker instance that prepends given
// <keyPrefix> to all keys in its calls.
// To avoid using a prefix, pass keyval.Root constant as argument.
func (cbw *CoreBrokerWatcherWrapper) NewBroker(prefix string) keyval.BytesBroker {
	return &BytesBrokerWrapper{
		wrap:             cbw.wrap.NewBroker(prefix),
		decryptArbitrary: cbw.decryptArbitrary,
		decrypter:        cbw.decrypter,
	}
}

// NewWatcher returns a BytesWatcher instance. Given <keyPrefix> is
// prepended to keys during watch subscribe phase.
// The prefix is removed from the key retrieved by GetKey() in BytesWatchResp.
// To avoid using a prefix, pass keyval.Root constant as argument.
func (cbw *CoreBrokerWatcherWrapper) NewWatcher(prefix string) keyval.BytesWatcher {
	return cbw.wrap.NewWatcher(prefix)
}

// Close closes provided wrapper
func (cbw *CoreBrokerWatcherWrapper) Close() error {
	return cbw.wrap.Close()
}

// Put puts single key-value pair into db.
// The behavior of put can be adjusted using PutOptions.
func (cbw *CoreBrokerWatcherWrapper) Put(key string, data []byte, opts ...datasync.PutOption) error {
	return cbw.bytesWrap.Put(key, data, opts...)
}

// NewTxn creates a transaction.
func (cbw *CoreBrokerWatcherWrapper) NewTxn() keyval.BytesTxn {
	return cbw.bytesWrap.NewTxn()
}

// GetValue retrieves one item under the provided key.
func (cbw *CoreBrokerWatcherWrapper) GetValue(key string) (data []byte, found bool, revision int64, err error) {
	return cbw.bytesWrap.GetValue(key)
}

// ListValues returns an iterator that enables to traverse all items stored
// under the provided <key>.
func (cbw *CoreBrokerWatcherWrapper) ListValues(key string) (keyval.BytesKeyValIterator, error) {
	return cbw.bytesWrap.ListValues(key)
}

// ListKeys returns an iterator that allows to traverse all keys from data
// store that share the given <prefix>.
func (cbw *CoreBrokerWatcherWrapper) ListKeys(prefix string) (keyval.BytesKeyIterator, error) {
	return cbw.bytesWrap.ListKeys(prefix)
}

// Delete removes data stored under the <key>.
func (cbw *CoreBrokerWatcherWrapper) Delete(key string, opts ...datasync.DelOption) (existed bool, err error) {
	return cbw.bytesWrap.Delete(key, opts...)
}

// Put puts single key-value pair into db.
// The behavior of put can be adjusted using PutOptions.
func (cbb *BytesBrokerWrapper) Put(key string, data []byte, opts ...datasync.PutOption) error {
	return cbb.wrap.Put(key, data, opts...)
}

// NewTxn creates a transaction.
func (cbb *BytesBrokerWrapper) NewTxn() keyval.BytesTxn {
	return cbb.wrap.NewTxn()
}

// GetValue retrieves one item under the provided key.
func (cbb *BytesBrokerWrapper) GetValue(key string) (data []byte, found bool, revision int64, err error) {
	data, found, revision, err = cbb.wrap.GetValue(key)
	if err == nil {
		data = cbb.decrypter.Decrypt(data, cbb.decryptArbitrary)
	}
	return
}

// ListValues returns an iterator that enables to traverse all items stored
// under the provided <key>.
func (cbb *BytesBrokerWrapper) ListValues(key string) (keyval.BytesKeyValIterator, error) {
	return cbb.wrap.ListValues(key)
}

// ListKeys returns an iterator that allows to traverse all keys from data
// store that share the given <prefix>.
func (cbb *BytesBrokerWrapper) ListKeys(prefix string) (keyval.BytesKeyIterator, error) {
	return cbb.wrap.ListKeys(prefix)
}

// Delete removes data stored under the <key>.
func (cbb *BytesBrokerWrapper) Delete(key string, opts ...datasync.DelOption) (existed bool, err error) {
	return cbb.wrap.Delete(key, opts...)
}
<commit_msg>Embed CoreBrokerWatcher and BytesBroker in crypto<commit_after>// Copyright (c) 2018 Cisco and/or its affiliates.
//
// 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 cryptodata

import (
	"github.com/ligato/cn-infra/db/keyval"
)

// CoreBrokerWatcherWrapper wraps keyval.CoreBrokerWatcher with additional support of reading encrypted data
type CoreBrokerWatcherWrapper struct {
	// Wrapped CoreBrokerWatcher
	keyval.CoreBrokerWatcher
	// Wrapped BytesBroker
	bytesWrap *BytesBrokerWrapper
	// Function used for decrypting arbitrary data later
	decryptArbitrary DecryptArbitrary
	// Decrypter is used to decrypt data
	decrypter Decrypter
}

// BytesBrokerWrapper wraps keyval.BytesBroker with additional support of reading encrypted data
type BytesBrokerWrapper struct {
	// Wrapped BytesBroker
	keyval.BytesBroker
	// Function used for decrypting arbitrary data later
	decryptArbitrary DecryptArbitrary
	// Decrypter is used to decrypt data
	decrypter Decrypter
}

// NewCoreBrokerWatcherWrapper creates wrapper for provided CoreBrokerWatcher, adding support for decrypting encrypted
// data
func NewCoreBrokerWatcherWrapper(cbw keyval.CoreBrokerWatcher, decrypter Decrypter, decryptArbitrary DecryptArbitrary) *CoreBrokerWatcherWrapper {
	return &CoreBrokerWatcherWrapper{
		CoreBrokerWatcher: cbw,
		decryptArbitrary:  decryptArbitrary,
		decrypter:         decrypter,
		bytesWrap: &BytesBrokerWrapper{
			BytesBroker:      cbw,
			decryptArbitrary: decryptArbitrary,
			decrypter:        decrypter,
		},
	}
}

// NewBroker returns a BytesBroker instance with support for decrypting values that prepends given <keyPrefix> to all
// keys in its calls.
// To avoid using a prefix, pass keyval.Root constant as argument.
func (cbw *CoreBrokerWatcherWrapper) NewBroker(prefix string) keyval.BytesBroker {
	return &BytesBrokerWrapper{
		BytesBroker:      cbw.CoreBrokerWatcher.NewBroker(prefix),
		decryptArbitrary: cbw.decryptArbitrary,
		decrypter:        cbw.decrypter,
	}
}

// GetValue retrieves and tries to decrypt one item under the provided key.
func (cbb *BytesBrokerWrapper) GetValue(key string) (data []byte, found bool, revision int64, err error) {
	data, found, revision, err = cbb.BytesBroker.GetValue(key)
	if err == nil {
		data = cbb.decrypter.Decrypt(data, cbb.decryptArbitrary)
	}
	return
}
<|endoftext|>


<commit_before>package weed_server

import (
	"encoding/json"
	"io/ioutil"
	"math/rand"
	"os"
	"path"
	"reflect"
	"sort"
	"strings"
	"time"

	"github.com/chrislusf/raft"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/topology"
	"github.com/gorilla/mux"
)

type RaftServer struct {
	peers      []string // initial peers to join with
	raftServer raft.Server
	dataDir    string
	httpAddr   string
	router     *mux.Router
	topo       *topology.Topology
}

func NewRaftServer(r *mux.Router, peers []string, httpAddr string, dataDir string, topo *topology.Topology, pulseSeconds int) *RaftServer {
	s := &RaftServer{
		peers:    peers,
		httpAddr: httpAddr,
		dataDir:  dataDir,
		router:   r,
		topo:     topo,
	}

	if glog.V(4) {
		raft.SetLogLevel(2)
	}

	raft.RegisterCommand(&topology.MaxVolumeIdCommand{})

	var err error
	transporter := raft.NewHTTPTransporter("/cluster", time.Second)
	transporter.Transport.MaxIdleConnsPerHost = 1024
	transporter.Transport.IdleConnTimeout = time.Second
	glog.V(0).Infof("Starting RaftServer with %v", httpAddr)

	// Clear old cluster configurations if peers are changed
	if oldPeers, changed := isPeersChanged(s.dataDir, httpAddr, s.peers); changed {
		glog.V(0).Infof("Peers Change: %v => %v", oldPeers, s.peers)
		os.RemoveAll(path.Join(s.dataDir, "conf"))
		os.RemoveAll(path.Join(s.dataDir, "log"))
		os.RemoveAll(path.Join(s.dataDir, "snapshot"))
	}

	s.raftServer, err = raft.NewServer(s.httpAddr, s.dataDir, transporter, nil, topo, "")
	if err != nil {
		glog.V(0).Infoln(err)
		return nil
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.SetHeartbeatInterval(500 * time.Millisecond)
	s.raftServer.SetElectionTimeout(time.Duration(pulseSeconds) * 500 * time.Millisecond)
	s.raftServer.Start()

	s.router.HandleFunc("/cluster/status", s.statusHandler).Methods("GET")

	for _, peer := range s.peers {
		s.raftServer.AddPeer(peer, "http://"+peer)
	}
	time.Sleep(time.Duration(1000+rand.Int31n(3000)) * time.Millisecond)
	if s.raftServer.IsLogEmpty() {
		// Initialize the server by joining itself.
		glog.V(0).Infoln("Initializing new cluster")

		_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: "http://" + s.httpAddr,
		})

		if err != nil {
			glog.V(0).Infoln(err)
			return nil
		}
	}

	glog.V(0).Infof("current cluster leader: %v", s.raftServer.Leader())

	return s
}

func (s *RaftServer) Peers() (members []string) {
	peers := s.raftServer.Peers()

	for _, p := range peers {
		members = append(members, strings.TrimPrefix(p.ConnectionString, "http://"))
	}

	return
}

func isPeersChanged(dir string, self string, peers []string) (oldPeers []string, changed bool) {
	confPath := path.Join(dir, "conf")
	// open conf file
	b, err := ioutil.ReadFile(confPath)
	if err != nil {
		return oldPeers, true
	}
	conf := &raft.Config{}
	if err = json.Unmarshal(b, conf); err != nil {
		return oldPeers, true
	}

	for _, p := range conf.Peers {
		oldPeers = append(oldPeers, strings.TrimPrefix(p.ConnectionString, "http://"))
	}
	oldPeers = append(oldPeers, self)

	if len(peers) == 0 && len(oldPeers) <= 1 {
		return oldPeers, false
	}

	sort.Strings(peers)
	sort.Strings(oldPeers)

	return oldPeers, !reflect.DeepEqual(peers, oldPeers)

}
<commit_msg>add a timeout<commit_after>package weed_server

import (
	"encoding/json"
	"io/ioutil"
	"math/rand"
	"os"
	"path"
	"reflect"
	"sort"
	"strings"
	"time"

	"github.com/chrislusf/raft"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/topology"
	"github.com/gorilla/mux"
)

type RaftServer struct {
	peers      []string // initial peers to join with
	raftServer raft.Server
	dataDir    string
	httpAddr   string
	router     *mux.Router
	topo       *topology.Topology
}

func NewRaftServer(r *mux.Router, peers []string, httpAddr string, dataDir string, topo *topology.Topology, pulseSeconds int) *RaftServer {
	s := &RaftServer{
		peers:    peers,
		httpAddr: httpAddr,
		dataDir:  dataDir,
		router:   r,
		topo:     topo,
	}

	if glog.V(4) {
		raft.SetLogLevel(2)
	}

	raft.RegisterCommand(&topology.MaxVolumeIdCommand{})

	var err error
	transporter := raft.NewHTTPTransporter("/cluster", time.Second)
	transporter.Transport.MaxIdleConnsPerHost = 1024
	transporter.Transport.IdleConnTimeout = time.Second
	transporter.Transport.ResponseHeaderTimeout = time.Second
	glog.V(0).Infof("Starting RaftServer with %v", httpAddr)

	// Clear old cluster configurations if peers are changed
	if oldPeers, changed := isPeersChanged(s.dataDir, httpAddr, s.peers); changed {
		glog.V(0).Infof("Peers Change: %v => %v", oldPeers, s.peers)
		os.RemoveAll(path.Join(s.dataDir, "conf"))
		os.RemoveAll(path.Join(s.dataDir, "log"))
		os.RemoveAll(path.Join(s.dataDir, "snapshot"))
	}

	s.raftServer, err = raft.NewServer(s.httpAddr, s.dataDir, transporter, nil, topo, "")
	if err != nil {
		glog.V(0).Infoln(err)
		return nil
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.SetHeartbeatInterval(500 * time.Millisecond)
	s.raftServer.SetElectionTimeout(time.Duration(pulseSeconds) * 500 * time.Millisecond)
	s.raftServer.Start()

	s.router.HandleFunc("/cluster/status", s.statusHandler).Methods("GET")

	for _, peer := range s.peers {
		s.raftServer.AddPeer(peer, "http://"+peer)
	}
	time.Sleep(time.Duration(1000+rand.Int31n(3000)) * time.Millisecond)
	if s.raftServer.IsLogEmpty() {
		// Initialize the server by joining itself.
		glog.V(0).Infoln("Initializing new cluster")

		_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
			Name:             s.raftServer.Name(),
			ConnectionString: "http://" + s.httpAddr,
		})

		if err != nil {
			glog.V(0).Infoln(err)
			return nil
		}
	}

	glog.V(0).Infof("current cluster leader: %v", s.raftServer.Leader())

	return s
}

func (s *RaftServer) Peers() (members []string) {
	peers := s.raftServer.Peers()

	for _, p := range peers {
		members = append(members, strings.TrimPrefix(p.ConnectionString, "http://"))
	}

	return
}

func isPeersChanged(dir string, self string, peers []string) (oldPeers []string, changed bool) {
	confPath := path.Join(dir, "conf")
	// open conf file
	b, err := ioutil.ReadFile(confPath)
	if err != nil {
		return oldPeers, true
	}
	conf := &raft.Config{}
	if err = json.Unmarshal(b, conf); err != nil {
		return oldPeers, true
	}

	for _, p := range conf.Peers {
		oldPeers = append(oldPeers, strings.TrimPrefix(p.ConnectionString, "http://"))
	}
	oldPeers = append(oldPeers, self)

	if len(peers) == 0 && len(oldPeers) <= 1 {
		return oldPeers, false
	}

	sort.Strings(peers)
	sort.Strings(oldPeers)

	return oldPeers, !reflect.DeepEqual(peers, oldPeers)

}
<|endoftext|>


<commit_before>/*
Copyright 2020 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 deployer

import (
	"errors"
	"fmt"
	osexec "os/exec"
	"strings"

	"github.com/google/shlex"

	"k8s.io/klog/v2"
	"k8s.io/kops/tests/e2e/kubetest2-kops/aws"
	"k8s.io/kops/tests/e2e/kubetest2-kops/do"
	"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
	"k8s.io/kops/tests/e2e/pkg/util"
	"k8s.io/kops/tests/e2e/pkg/version"
	"sigs.k8s.io/kubetest2/pkg/exec"
)

func (d *deployer) Up() error {
	if err := d.init(); err != nil {
		return err
	}

	publicIP, err := util.ExternalIPRange()
	if err != nil {
		return err
	}

	adminAccess := d.AdminAccess
	if adminAccess == "" {
		adminAccess = publicIP
	}

	zones, err := d.zones()
	if err != nil {
		return err
	}

	if d.TemplatePath != "" {
		values, err := d.templateValues(zones, adminAccess)
		if err != nil {
			return err
		}
		if err := d.renderTemplate(values); err != nil {
			return err
		}
		if err := d.replace(); err != nil {
			return err
		}
	} else {
		err := d.createCluster(zones, adminAccess)
		if err != nil {
			return err
		}
	}
	isUp, err := d.IsUp()
	if err != nil {
		return err
	} else if isUp {
		klog.V(1).Infof("cluster reported as up")
	} else {
		klog.Errorf("cluster reported as down")
	}
	return nil
}

func (d *deployer) createCluster(zones []string, adminAccess string) error {

	args := []string{
		d.KopsBinaryPath, "create", "cluster",
		"--name", d.ClusterName,
		"--cloud", d.CloudProvider,
		"--kubernetes-version", d.KubernetesVersion,
		"--ssh-public-key", d.SSHPublicKeyPath,
		"--override", "cluster.spec.nodePortAccess=0.0.0.0/0",
		"--yes",
	}

	if d.CreateArgs != "" {
		createArgs, err := shlex.Split(d.CreateArgs)
		if err != nil {
			return err
		}
		args = append(args, createArgs...)
	}
	args = appendIfUnset(args, "--admin-access", adminAccess)
	args = appendIfUnset(args, "--master-count", "1")
	args = appendIfUnset(args, "--master-volume-size", "48")
	args = appendIfUnset(args, "--node-count", "4")
	args = appendIfUnset(args, "--node-volume-size", "48")
	args = appendIfUnset(args, "--override", adminAccess)
	args = appendIfUnset(args, "--admin-access", adminAccess)
	args = appendIfUnset(args, "--zones", strings.Join(zones, ","))

	switch d.CloudProvider {
	case "aws":
		args = appendIfUnset(args, "--master-size", "c5.large")
	case "gce":
		args = appendIfUnset(args, "--master-size", "e2-standard-2")
		if d.GCPProject != "" {
			args = appendIfUnset(args, "--project", d.GCPProject)
		}
	case "digitalocean":
		args = appendIfUnset(args, "--master-size", "s-8vcpu-16gb")
	}

	if d.terraform != nil {
		args = append(args, "--target", "terraform", "--out", d.terraform.Dir())
	}

	klog.Info(strings.Join(args, " "))
	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err := cmd.Run()
	if err != nil {
		return err
	}

	if d.terraform != nil {
		if err := d.terraform.InitApply(); err != nil {
			return err
		}
	}

	return nil
}

func (d *deployer) IsUp() (bool, error) {
	args := []string{
		d.KopsBinaryPath, "validate", "cluster",
		"--name", d.ClusterName,
		"--count", "10",
		"--wait", "15m",
	}
	klog.Info(strings.Join(args, " "))

	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err := cmd.Run()
	// `kops validate cluster` exits 2 if validation failed
	if exitErr, ok := err.(*osexec.ExitError); ok && exitErr.ExitCode() == 2 {
		return false, nil
	}
	return err == nil, err
}

// verifyUpFlags ensures fields are set for creation of the cluster
func (d *deployer) verifyUpFlags() error {
	if d.KubernetesVersion == "" {
		return errors.New("missing required --kubernetes-version flag")
	}

	v, err := version.ParseKubernetesVersion(d.KubernetesVersion)
	if err != nil {
		return err
	}
	d.KubernetesVersion = v

	return nil
}

func (d *deployer) zones() ([]string, error) {
	switch d.CloudProvider {
	case "aws":
		return aws.RandomZones(1)
	case "gce":
		return gce.RandomZones(1)
	case "digitalocean":
		return do.RandomZones(1)
	}
	return nil, fmt.Errorf("unsupported CloudProvider: %v", d.CloudProvider)
}

// appendIfUnset will append an argument and its value to args if the arg is not already present
// This shouldn't be used for arguments that can be specified multiple times like --override
func appendIfUnset(args []string, arg, value string) []string {
	for _, existingArg := range args {
		existingKey := strings.Split(existingArg, "=")
		if existingKey[0] == arg {
			return args
		}
	}
	args = append(args, arg, value)
	return args
}
<commit_msg>Kubetest2 - add more validation time for --target terraform<commit_after>/*
Copyright 2020 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 deployer

import (
	"errors"
	"fmt"
	osexec "os/exec"
	"strings"
	"time"

	"github.com/google/shlex"

	"k8s.io/klog/v2"
	"k8s.io/kops/tests/e2e/kubetest2-kops/aws"
	"k8s.io/kops/tests/e2e/kubetest2-kops/do"
	"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
	"k8s.io/kops/tests/e2e/pkg/util"
	"k8s.io/kops/tests/e2e/pkg/version"
	"sigs.k8s.io/kubetest2/pkg/exec"
)

func (d *deployer) Up() error {
	if err := d.init(); err != nil {
		return err
	}

	publicIP, err := util.ExternalIPRange()
	if err != nil {
		return err
	}

	adminAccess := d.AdminAccess
	if adminAccess == "" {
		adminAccess = publicIP
	}

	zones, err := d.zones()
	if err != nil {
		return err
	}

	if d.TemplatePath != "" {
		values, err := d.templateValues(zones, adminAccess)
		if err != nil {
			return err
		}
		if err := d.renderTemplate(values); err != nil {
			return err
		}
		if err := d.replace(); err != nil {
			return err
		}
	} else {
		err := d.createCluster(zones, adminAccess)
		if err != nil {
			return err
		}
	}
	isUp, err := d.IsUp()
	if err != nil {
		return err
	} else if isUp {
		klog.V(1).Infof("cluster reported as up")
	} else {
		klog.Errorf("cluster reported as down")
	}
	return nil
}

func (d *deployer) createCluster(zones []string, adminAccess string) error {

	args := []string{
		d.KopsBinaryPath, "create", "cluster",
		"--name", d.ClusterName,
		"--cloud", d.CloudProvider,
		"--kubernetes-version", d.KubernetesVersion,
		"--ssh-public-key", d.SSHPublicKeyPath,
		"--override", "cluster.spec.nodePortAccess=0.0.0.0/0",
		"--yes",
	}

	if d.CreateArgs != "" {
		createArgs, err := shlex.Split(d.CreateArgs)
		if err != nil {
			return err
		}
		args = append(args, createArgs...)
	}
	args = appendIfUnset(args, "--admin-access", adminAccess)
	args = appendIfUnset(args, "--master-count", "1")
	args = appendIfUnset(args, "--master-volume-size", "48")
	args = appendIfUnset(args, "--node-count", "4")
	args = appendIfUnset(args, "--node-volume-size", "48")
	args = appendIfUnset(args, "--override", adminAccess)
	args = appendIfUnset(args, "--admin-access", adminAccess)
	args = appendIfUnset(args, "--zones", strings.Join(zones, ","))

	switch d.CloudProvider {
	case "aws":
		args = appendIfUnset(args, "--master-size", "c5.large")
	case "gce":
		args = appendIfUnset(args, "--master-size", "e2-standard-2")
		if d.GCPProject != "" {
			args = appendIfUnset(args, "--project", d.GCPProject)
		}
	case "digitalocean":
		args = appendIfUnset(args, "--master-size", "s-8vcpu-16gb")
	}

	if d.terraform != nil {
		args = append(args, "--target", "terraform", "--out", d.terraform.Dir())
	}

	klog.Info(strings.Join(args, " "))
	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err := cmd.Run()
	if err != nil {
		return err
	}

	if d.terraform != nil {
		if err := d.terraform.InitApply(); err != nil {
			return err
		}
	}

	return nil
}

func (d *deployer) IsUp() (bool, error) {
	wait := "15m"
	if d.TerraformVersion != "" {
		// `--target terraform` doesn't precreate the API DNS records,
		// so kops is more likely to hit negative TTLs during validation
		wait = "20m"
	}
	args := []string{
		d.KopsBinaryPath, "validate", "cluster",
		"--name", d.ClusterName,
		"--count", "10",
		"--wait", wait,
	}
	klog.Info(strings.Join(args, " "))

	cmd := exec.Command(args[0], args[1:]...)
	cmd.SetEnv(d.env()...)

	exec.InheritOutput(cmd)
	err := cmd.Run()
	// `kops validate cluster` exits 2 if validation failed
	if exitErr, ok := err.(*osexec.ExitError); ok && exitErr.ExitCode() == 2 {
		return false, nil
	}
	if err == nil && d.TerraformVersion != "" && d.commonOptions.ShouldTest() {
		klog.Info("Waiting 5 minutes for DNS TTLs before starting tests")
		time.Sleep(5 * time.Minute)
	}
	return err == nil, err
}

// verifyUpFlags ensures fields are set for creation of the cluster
func (d *deployer) verifyUpFlags() error {
	if d.KubernetesVersion == "" {
		return errors.New("missing required --kubernetes-version flag")
	}

	v, err := version.ParseKubernetesVersion(d.KubernetesVersion)
	if err != nil {
		return err
	}
	d.KubernetesVersion = v

	return nil
}

func (d *deployer) zones() ([]string, error) {
	switch d.CloudProvider {
	case "aws":
		return aws.RandomZones(1)
	case "gce":
		return gce.RandomZones(1)
	case "digitalocean":
		return do.RandomZones(1)
	}
	return nil, fmt.Errorf("unsupported CloudProvider: %v", d.CloudProvider)
}

// appendIfUnset will append an argument and its value to args if the arg is not already present
// This shouldn't be used for arguments that can be specified multiple times like --override
func appendIfUnset(args []string, arg, value string) []string {
	for _, existingArg := range args {
		existingKey := strings.Split(existingArg, "=")
		if existingKey[0] == arg {
			return args
		}
	}
	args = append(args, arg, value)
	return args
}
<|endoftext|>


<commit_before>// Basic tool to talk to the rangeserver over http

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
)

//globals
var debug bool
var help bool
var timing bool
var vip string

func init() {
	parseFlags()
	if help == true {
		printHelp()
		os.Exit(0)
	}
	return
}

func parseFlags() {
	flag.BoolVar(&debug, "debug", false, "enable debug")
	flag.BoolVar(&help, "help", false, "enable help")
	flag.BoolVar(&timing, "timing", false, "enable timing")
	flag.StringVar(&vip, "vip", "localhost", "vip endpoint")

	flag.Parse()
	return
}

func printHelp() {
	fmt.Println(
		`	Usage: rangerclient [OPTIONS] <query>
	eg: yr %RANGE
	--debug .................... Run client in debug mode
	--help ..................... Prints this documentation
	--timing ................... profiling of execution time
	--vip ...................... Range vip endpoint`)
	os.Exit(0)
	return
}

func main() {
	query := ""
	if len(os.Args) == 1 {
		printHelp()
	}
	query = os.Args[len(os.Args)-1] //trying to get the last element of an array
	if vip == "localhost" {
		vip = "localhost:9999"
	}
	res, err := http.Get(fmt.Sprintf("http://%s/v1/range/list?%s", vip, url.QueryEscape(query)))
	if err != nil {
		log.Fatal(err)
	}
	results, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		log.Fatal("%s", err)
	}
	if res.Header.Get("Range-Err-Count") != "" {
		fmt.Printf("%s", results)
	} else {
		fmt.Printf("%s\n", results)
	}
	if timing == true {
		fmt.Printf("Range-Expand-Microsecond : %sms \n", res.Header.Get("Range-Expand-Microsecond"))
	}
}
<commit_msg>fixing git config<commit_after>// Basic tool to talk to the rangeserver over http

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
)

//globals
var debug bool
var help bool
var timing bool
var vip string

func init() {
	parseFlags()
	if help == true {
		printHelp()
		os.Exit(0)
	}
	return
}

func parseFlags() {
	flag.BoolVar(&debug, "debug", false, "enable debug")
	flag.BoolVar(&help, "help", false, "enable help")
	flag.BoolVar(&timing, "timing", false, "enable timing")
	flag.StringVar(&vip, "vip", "localhost", "vip endpoint")
	flag.Parse()
	return
}

func printHelp() {
	fmt.Println(
		`	Usage: rangerclient [OPTIONS] <query>
	eg: yr %RANGE
	--debug .................... Run client in debug mode
	--help ..................... Prints this documentation
	--timing ................... profiling of execution time
	--vip ...................... Range vip endpoint`)
	os.Exit(0)
	return
}

func main() {
	query := ""
	if len(os.Args) == 1 {
		printHelp()
	}
	query = os.Args[len(os.Args)-1] //trying to get the last element of an array
	if vip == "localhost" {
		vip = "localhost:9999"
	}
	res, err := http.Get(fmt.Sprintf("http://%s/v1/range/list?%s", vip, url.QueryEscape(query)))
	if err != nil {
		log.Fatal(err)
	}
	results, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		log.Fatal("%s", err)
	}
	if res.Header.Get("Range-Err-Count") != "" {
		fmt.Printf("%s", results)
	} else {
		fmt.Printf("%s\n", results)
	}
	if timing == true {
		fmt.Printf("Range-Expand-Microsecond : %sms \n", res.Header.Get("Range-Expand-Microsecond"))
	}
}
<|endoftext|>


<commit_before>package postgres

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/url"
	"os"
	"path"
	"path/filepath"
	gotemplate "text/template"

	"github.com/nuveo/log"
	"github.com/prest/adapters"
	"github.com/prest/adapters/internal/scanner"
	"github.com/prest/adapters/postgres/internal/connection"
	"github.com/prest/config"
	"github.com/prest/template"
)

// GetScript get SQL template file
func (adapter *Postgres) GetScript(verb, folder, scriptName string) (script string, err error) {
	verbs := map[string]string{
		"GET":    ".read.sql",
		"POST":   ".write.sql",
		"PATCH":  ".update.sql",
		"PUT":    ".update.sql",
		"DELETE": ".delete.sql",
	}

	sufix, ok := verbs[verb]
	if !ok {
		err = fmt.Errorf("invalid http method %s", verb)
		return
	}

	script = filepath.Join(config.PrestConf.QueriesPath, folder, fmt.Sprint(scriptName, sufix))

	if _, err = os.Stat(script); os.IsNotExist(err) {
		err = fmt.Errorf("could not load %s", script)
		return
	}

	return
}

// ParseScript use values sent by users and add on script
func (adapter *Postgres) ParseScript(scriptPath string, queryURL url.Values) (sqlQuery string, values []interface{}, err error) {
	_, tplName := path.Split(scriptPath)
	q := make(map[string]string)
	pid := 1
	for key := range queryURL {
		q[key] = queryURL.Get(key)
		pid++
	}

	funcs := &template.FuncRegistry{TemplateData: q}
	tpl := gotemplate.New(tplName).Funcs(funcs.RegistryAllFuncs())

	tpl, err = tpl.ParseFiles(scriptPath)
	if err != nil {
		err = fmt.Errorf("could not parse file %s: %+v", scriptPath, err)
		return
	}

	var buff bytes.Buffer
	err = tpl.Execute(&buff, funcs.TemplateData)
	if err != nil {
		err = fmt.Errorf("could not execute template %v", err)
		return
	}

	sqlQuery = buff.String()
	return
}

// WriteSQL perform INSERT's, UPDATE's, DELETE's operations
func WriteSQL(sql string, values []interface{}) (sc adapters.Scanner) {
	db, err := connection.Get()
	if err != nil {
		log.Println(err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}
	stmt, err := Prepare(db, sql)
	if err != nil {
		log.Printf("could not prepare sql: %s\n Error: %v\n", sql, err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}
	valuesAux := make([]interface{}, 0, len(values))

	for i := 0; i < len(values); i++ {
		valuesAux = append(valuesAux, values[i])
	}

	result, err := stmt.Exec(valuesAux...)
	if err != nil {
		log.Printf("sql = %+v\n", sql)
		err = fmt.Errorf("could not peform sql: %v", err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		err = fmt.Errorf("could not rows affected: %v", err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	var resultByte []byte
	resultByte, err = json.Marshal(data)
	sc = &scanner.PrestScanner{
		Error: err,
		Buff:  bytes.NewBuffer(resultByte),
	}
	return
}

// ExecuteScripts run sql templates created by users
func (adapter *Postgres) ExecuteScripts(method, sql string, values []interface{}) (sc adapters.Scanner) {
	switch method {
	case "GET":
		sc = adapter.Query(sql, values...)
	case "POST", "PUT", "PATCH", "DELETE":
		sc = WriteSQL(sql, values)
	default:
		sc = &scanner.PrestScanner{Error: fmt.Errorf("invalid method %s", method)}
	}

	return
}
<commit_msg>add supprt to slice on scripts<commit_after>package postgres

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/url"
	"os"
	"path"
	"path/filepath"
	gotemplate "text/template"

	"github.com/nuveo/log"
	"github.com/prest/adapters"
	"github.com/prest/adapters/internal/scanner"
	"github.com/prest/adapters/postgres/internal/connection"
	"github.com/prest/config"
	"github.com/prest/template"
)

// GetScript get SQL template file
func (adapter *Postgres) GetScript(verb, folder, scriptName string) (script string, err error) {
	verbs := map[string]string{
		"GET":    ".read.sql",
		"POST":   ".write.sql",
		"PATCH":  ".update.sql",
		"PUT":    ".update.sql",
		"DELETE": ".delete.sql",
	}

	sufix, ok := verbs[verb]
	if !ok {
		err = fmt.Errorf("invalid http method %s", verb)
		return
	}

	script = filepath.Join(config.PrestConf.QueriesPath, folder, fmt.Sprint(scriptName, sufix))

	if _, err = os.Stat(script); os.IsNotExist(err) {
		err = fmt.Errorf("could not load %s", script)
		return
	}

	return
}

// ParseScript use values sent by users and add on script
func (adapter *Postgres) ParseScript(scriptPath string, queryURL url.Values) (sqlQuery string, values []interface{}, err error) {
	_, tplName := path.Split(scriptPath)
	q := make(map[string]interface{})
	for key, value := range queryURL {
		if len(value) == 1 {
			q[key] = value[0]
			continue
		}
		q[key] = value
	}

	funcs := &template.FuncRegistry{TemplateData: q}
	tpl := gotemplate.New(tplName).Funcs(funcs.RegistryAllFuncs())

	tpl, err = tpl.ParseFiles(scriptPath)
	if err != nil {
		err = fmt.Errorf("could not parse file %s: %+v", scriptPath, err)
		return
	}

	var buff bytes.Buffer
	err = tpl.Execute(&buff, funcs.TemplateData)
	if err != nil {
		err = fmt.Errorf("could not execute template %v", err)
		return
	}

	sqlQuery = buff.String()
	return
}

// WriteSQL perform INSERT's, UPDATE's, DELETE's operations
func WriteSQL(sql string, values []interface{}) (sc adapters.Scanner) {
	db, err := connection.Get()
	if err != nil {
		log.Println(err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}
	stmt, err := Prepare(db, sql)
	if err != nil {
		log.Printf("could not prepare sql: %s\n Error: %v\n", sql, err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}
	valuesAux := make([]interface{}, 0, len(values))

	for i := 0; i < len(values); i++ {
		valuesAux = append(valuesAux, values[i])
	}

	result, err := stmt.Exec(valuesAux...)
	if err != nil {
		log.Printf("sql = %+v\n", sql)
		err = fmt.Errorf("could not peform sql: %v", err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		err = fmt.Errorf("could not rows affected: %v", err)
		sc = &scanner.PrestScanner{Error: err}
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	var resultByte []byte
	resultByte, err = json.Marshal(data)
	sc = &scanner.PrestScanner{
		Error: err,
		Buff:  bytes.NewBuffer(resultByte),
	}
	return
}

// ExecuteScripts run sql templates created by users
func (adapter *Postgres) ExecuteScripts(method, sql string, values []interface{}) (sc adapters.Scanner) {
	switch method {
	case "GET":
		sc = adapter.Query(sql, values...)
	case "POST", "PUT", "PATCH", "DELETE":
		sc = WriteSQL(sql, values)
	default:
		sc = &scanner.PrestScanner{Error: fmt.Errorf("invalid method %s", method)}
	}

	return
}
<|endoftext|>


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

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var testData uint32

func checkSymbols(t *testing.T, nmoutput []byte) {
	var checkSymbolsFound, testDataFound bool
	scanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))
	for scanner.Scan() {
		f := strings.Fields(scanner.Text())
		if len(f) < 3 {
			continue
		}
		switch f[2] {
		case "cmd/nm.checkSymbols":
			checkSymbolsFound = true
			addr := "0x" + f[0]
			if addr != fmt.Sprintf("%p", checkSymbols) {
				t.Errorf("nm shows wrong address %v for checkSymbols (%p)", addr, checkSymbols)
			}
		case "cmd/nm.testData":
			testDataFound = true
			addr := "0x" + f[0]
			if addr != fmt.Sprintf("%p", &testData) {
				t.Errorf("nm shows wrong address %v for testData (%p)", addr, &testData)
			}
		}
	}
	if err := scanner.Err(); err != nil {
		t.Errorf("error while reading symbols: %v", err)
		return
	}
	if !checkSymbolsFound {
		t.Error("nm shows no checkSymbols symbol")
	}
	if !testDataFound {
		t.Error("nm shows no testData symbol")
	}
}

func TestNM(t *testing.T) {
	if runtime.GOOS == "nacl" {
		t.Skip("skipping on nacl")
	}

	tmpDir, err := ioutil.TempDir("", "TestNM")
	if err != nil {
		t.Fatal("TempDir failed: ", err)
	}
	defer os.RemoveAll(tmpDir)

	testnmpath := filepath.Join(tmpDir, "testnm.exe")
	out, err := exec.Command("go", "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
	if err != nil {
		t.Fatalf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
	}

	testfiles := []string{
		"elf/testdata/gcc-386-freebsd-exec",
		"elf/testdata/gcc-amd64-linux-exec",
		"macho/testdata/gcc-386-darwin-exec",
		"macho/testdata/gcc-amd64-darwin-exec",
		"pe/testdata/gcc-amd64-mingw-exec",
		"pe/testdata/gcc-386-mingw-exec",
		"plan9obj/testdata/amd64-plan9-exec",
		"plan9obj/testdata/386-plan9-exec",
	}
	for _, f := range testfiles {
		exepath := filepath.Join(runtime.GOROOT(), "src", "pkg", "debug", f)
		cmd := exec.Command(testnmpath, exepath)
		out, err := cmd.CombinedOutput()
		if err != nil {
			t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
		}
	}

	cmd := exec.Command(testnmpath, os.Args[0])
	out, err = cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
	}
	checkSymbols(t, out)
}
<commit_msg>cmd/nm: skip test on android (no Go tool)<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var testData uint32

func checkSymbols(t *testing.T, nmoutput []byte) {
	var checkSymbolsFound, testDataFound bool
	scanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))
	for scanner.Scan() {
		f := strings.Fields(scanner.Text())
		if len(f) < 3 {
			continue
		}
		switch f[2] {
		case "cmd/nm.checkSymbols":
			checkSymbolsFound = true
			addr := "0x" + f[0]
			if addr != fmt.Sprintf("%p", checkSymbols) {
				t.Errorf("nm shows wrong address %v for checkSymbols (%p)", addr, checkSymbols)
			}
		case "cmd/nm.testData":
			testDataFound = true
			addr := "0x" + f[0]
			if addr != fmt.Sprintf("%p", &testData) {
				t.Errorf("nm shows wrong address %v for testData (%p)", addr, &testData)
			}
		}
	}
	if err := scanner.Err(); err != nil {
		t.Errorf("error while reading symbols: %v", err)
		return
	}
	if !checkSymbolsFound {
		t.Error("nm shows no checkSymbols symbol")
	}
	if !testDataFound {
		t.Error("nm shows no testData symbol")
	}
}

func TestNM(t *testing.T) {
	switch runtime.GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", runtime.GOOS)
	}

	tmpDir, err := ioutil.TempDir("", "TestNM")
	if err != nil {
		t.Fatal("TempDir failed: ", err)
	}
	defer os.RemoveAll(tmpDir)

	testnmpath := filepath.Join(tmpDir, "testnm.exe")
	out, err := exec.Command("go", "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
	if err != nil {
		t.Fatalf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
	}

	testfiles := []string{
		"elf/testdata/gcc-386-freebsd-exec",
		"elf/testdata/gcc-amd64-linux-exec",
		"macho/testdata/gcc-386-darwin-exec",
		"macho/testdata/gcc-amd64-darwin-exec",
		"pe/testdata/gcc-amd64-mingw-exec",
		"pe/testdata/gcc-386-mingw-exec",
		"plan9obj/testdata/amd64-plan9-exec",
		"plan9obj/testdata/386-plan9-exec",
	}
	for _, f := range testfiles {
		exepath := filepath.Join(runtime.GOROOT(), "src", "pkg", "debug", f)
		cmd := exec.Command(testnmpath, exepath)
		out, err := cmd.CombinedOutput()
		if err != nil {
			t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
		}
	}

	cmd := exec.Command(testnmpath, os.Args[0])
	out, err = cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
	}
	checkSymbols(t, out)
}
<|endoftext|>


<commit_before>// problem54.go
//
// The file, poker.txt, contains one-thousand random hands dealt to two
// players. How many hands does Player 1 win?

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
)

// Hand represents a five-card poker hand.
type Hand struct {
	// The ranks are sorted in descending order.
	// e.g. the hand [AC 8D 8H 3S 2S] has ranks [14 8 8 3 2]
	//               [KC 9D 9H 3C 2C]           [13 9 9 3 2]
	ranks []int

	// A set of strings which the hand contains. Used to determine if
	// the hand is a flush.
	suits map[string]bool

	// A slice of [count rank] pairs. This will be used to break ties between
	// two hands of equal value (e.g. two hands that both have 'one-pair').
	// Will be sorted highest count first, then highest rank first.
	// e.g. the hands [AC 8D 8H 3S 2S] and [KC 9D 9H 3C 2C] have groups
	//	[[2 8], [1 14], [1 3], [1 2]]
	//	[[2 9], [1 13], [1 3], [1 2]]
	// This allows us to correctly judge that the second hand beats the former
	// by sorting Hands lexicographically based on the groups field.
	groups [][]int

	// A sorted slice of counts of the card ranks.
	// e.g. the ranks [14 8 8 3 2] have pattern [2 1 1 1]
	//                [10 9 7 7 7]              [3 1 1]
	// Used to determine whether the hand has 'two-pair' or 'threeofakind' etc.
	pattern []int
}

// newHand constructs a new Hand type from the given cards.
// cards is of the form e.g. [AC 8D 8H 3C 2S]
func newHand(cards []string) Hand {
	trans := map[string]int{"A": 14, "K": 13, "Q": 12, "J": 11, "T": 10}

	var ranks []int                  // The ranks field.
	suits := make(map[string]bool)   // The suits field.
	rankToCount := make(map[int]int) // Used to create other fields.
	for _, card := range cards {
		s := string(card[1])
		suits[s] = true
		r, ok := trans[string(card[0])]
		if !ok {
			r, _ = strconv.Atoi(string(card[0]))
		}
		ranks = append(ranks, r)
		rankToCount[r]++
	}
	sort.Sort(sort.Reverse(sort.IntSlice(ranks)))

	// An ace should be played 'low' i.e. with rank 1 if it makes a straight.
	if reflect.DeepEqual(ranks, []int{14, 5, 4, 3, 2}) {
		ranks = []int{5, 4, 3, 2, 1}
	}

	var pattern []int                   // The pattern field.
	countToRanks := make(map[int][]int) // Used to create the groups field.
	for k, v := range rankToCount {
		pattern = append(pattern, v)
		countToRanks[v] = append(countToRanks[v], k)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(pattern)))

	var groups [][]int         // The groups field.
	seen := make(map[int]bool) // Used to ensure no duplicates.
	for _, count := range pattern {
		// For every count in the pattern append to groups a [count rank] pair.
		// groups is ordered by highest count first, then highest rank first.
		if !seen[count] {
			rs := countToRanks[count]
			sort.Sort(sort.Reverse(sort.IntSlice(rs)))
			for _, r := range rs {
				groups = append(groups, []int{count, r})
			}
		}
		seen[count] = true
	}

	return Hand{ranks, suits, groups, pattern}
}

// Hand type predicates.
func (h Hand) onepair() bool       { return h.samePatternAs([]int{2, 1, 1, 1}) }
func (h Hand) twopair() bool       { return h.samePatternAs([]int{2, 2, 1}) }
func (h Hand) threeofakind() bool  { return h.samePatternAs([]int{3, 1, 1}) }
func (h Hand) fourofakind() bool   { return h.samePatternAs([]int{4, 1}) }
func (h Hand) fullhouse() bool     { return h.samePatternAs([]int{3, 2}) }
func (h Hand) flush() bool         { return len(h.suits) == 1 }
func (h Hand) straight() bool      { return (len(h.pattern) == 5) && (h.ranks[0]-h.ranks[4] == 4) }
func (h Hand) straightflush() bool { return h.flush() && h.straight() }

// Check whether Hand h has the same pattern as the given pat.
func (h Hand) samePatternAs(pat []int) bool {
	if len(h.pattern) != len(pat) {
		return false
	}
	for i := 0; i < len(pat); i++ {
		if h.pattern[i] != pat[i] {
			return false
		}
	}
	return true
}

// Return a value for hand from an eight-point scale.
func (h Hand) evaluate() int {
	switch {
	case h.straightflush():
		return 8
	case h.fourofakind():
		return 7
	case h.fullhouse():
		return 6
	case h.flush():
		return 5
	case h.straight():
		return 4
	case h.threeofakind():
		return 3
	case h.twopair():
		return 2
	case h.onepair():
		return 1
	default:
		return 0
	}
}

// Did Player 1 win this round?
func player1wins(h1, h2 Hand) bool {
	// First check whether hands have different value on eight-point scale.
	if v1, v2 := h1.evaluate(), h2.evaluate(); v1 != v2 {
		return v1 > v2
	}
	// If those values are equal, perform lexicographic comparison based on
	// the groups field, a slice of [count rank] pairs ordered by highest
	// count first, then highest rank first.
	for i := range h1.groups {
		// Since v1 == v2, the groups are the same length and the
		// counts are identical. Therefore, compare ranks.
		g1, g2 := h1.groups[i], h2.groups[i]
		rank1, rank2 := g1[1], g2[1]
		switch {
		case rank1 > rank2:
			return true
		case rank1 < rank2:
			return false
		}
	}
	// The problem specifies that ties are not possible, so this
	// should be unreachable. This code path corresponds to
	// two hands being equal in all relevant respects (i.e. they
	// only differ by suit).
	return false
}

func problem54() int {
	file, err := os.Open("data/poker.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	var count int // Count of number of times Player 1 wins
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		row := scanner.Text()
		cards := strings.Split(row, " ")
		h1, h2 := newHand(cards[:5]), newHand(cards[5:])
		if player1wins(h1, h2) {
			count++
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
	return count
}

func main() {
	ans := problem54()
	fmt.Println(ans)
}
<commit_msg>Use simpler function name in problem54.go<commit_after>// problem54.go
//
// The file, poker.txt, contains one-thousand random hands dealt to two
// players. How many hands does Player 1 win?

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
)

// Hand represents a five-card poker hand.
type Hand struct {
	// The ranks are sorted in descending order.
	// e.g. the hand [AC 8D 8H 3S 2S] has ranks [14 8 8 3 2]
	//               [KC 9D 9H 3C 2C]           [13 9 9 3 2]
	ranks []int

	// A set of strings which the hand contains. Used to determine if
	// the hand is a flush.
	suits map[string]bool

	// A slice of [count rank] pairs. This will be used to break ties between
	// two hands of equal value (e.g. two hands that both have 'one-pair').
	// Will be sorted highest count first, then highest rank first.
	// e.g. the hands [AC 8D 8H 3S 2S] and [KC 9D 9H 3C 2C] have groups
	//	[[2 8], [1 14], [1 3], [1 2]]
	//	[[2 9], [1 13], [1 3], [1 2]]
	// This allows us to correctly judge that the second hand beats the former
	// by sorting Hands lexicographically based on the groups field.
	groups [][]int

	// A sorted slice of counts of the card ranks.
	// e.g. the ranks [14 8 8 3 2] have pattern [2 1 1 1]
	//                [10 9 7 7 7]              [3 1 1]
	// Used to determine whether the hand has 'two-pair' or 'threeofakind' etc.
	pattern []int
}

// newHand constructs a new Hand type from the given cards.
// cards is of the form e.g. [AC 8D 8H 3C 2S]
func newHand(cards []string) Hand {
	trans := map[string]int{"A": 14, "K": 13, "Q": 12, "J": 11, "T": 10}

	var ranks []int                  // The ranks field.
	suits := make(map[string]bool)   // The suits field.
	rankToCount := make(map[int]int) // Used to create other fields.
	for _, card := range cards {
		s := string(card[1])
		suits[s] = true
		r, ok := trans[string(card[0])]
		if !ok {
			r, _ = strconv.Atoi(string(card[0]))
		}
		ranks = append(ranks, r)
		rankToCount[r]++
	}
	sort.Sort(sort.Reverse(sort.IntSlice(ranks)))

	// An ace should be played 'low' i.e. with rank 1 if it makes a straight.
	if reflect.DeepEqual(ranks, []int{14, 5, 4, 3, 2}) {
		ranks = []int{5, 4, 3, 2, 1}
	}

	var pattern []int                   // The pattern field.
	countToRanks := make(map[int][]int) // Used to create the groups field.
	for k, v := range rankToCount {
		pattern = append(pattern, v)
		countToRanks[v] = append(countToRanks[v], k)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(pattern)))

	var groups [][]int         // The groups field.
	seen := make(map[int]bool) // Used to ensure no duplicates.
	for _, count := range pattern {
		// For every count in the pattern append to groups a [count rank] pair.
		// groups is ordered by highest count first, then highest rank first.
		if !seen[count] {
			rs := countToRanks[count]
			sort.Sort(sort.Reverse(sort.IntSlice(rs)))
			for _, r := range rs {
				groups = append(groups, []int{count, r})
			}
		}
		seen[count] = true
	}

	return Hand{ranks, suits, groups, pattern}
}

// Hand type predicates.
func (h Hand) onepair() bool       { return isEqual(h.pattern, []int{2, 1, 1, 1}) }
func (h Hand) twopair() bool       { return isEqual(h.pattern, []int{2, 2, 1}) }
func (h Hand) threeofakind() bool  { return isEqual(h.pattern, []int{3, 1, 1}) }
func (h Hand) fourofakind() bool   { return isEqual(h.pattern, []int{4, 1}) }
func (h Hand) fullhouse() bool     { return isEqual(h.pattern, []int{3, 2}) }
func (h Hand) flush() bool         { return len(h.suits) == 1 }
func (h Hand) straight() bool      { return (len(h.pattern) == 5) && (h.ranks[0]-h.ranks[4] == 4) }
func (h Hand) straightflush() bool { return h.flush() && h.straight() }

// Check whether two []int are identical.
func isEqual(x, y []int) bool {
	if len(x) != len(y) {
		return false
	}
	for i := 0; i < len(x); i++ {
		if x[i] != y[i] {
			return false
		}
	}
	return true
}

// Return a value for hand from an eight-point scale.
func (h Hand) evaluate() int {
	switch {
	case h.straightflush():
		return 8
	case h.fourofakind():
		return 7
	case h.fullhouse():
		return 6
	case h.flush():
		return 5
	case h.straight():
		return 4
	case h.threeofakind():
		return 3
	case h.twopair():
		return 2
	case h.onepair():
		return 1
	default:
		return 0
	}
}

// Did Player 1 win this round?
func player1wins(h1, h2 Hand) bool {
	// First check whether hands have different value on eight-point scale.
	if v1, v2 := h1.evaluate(), h2.evaluate(); v1 != v2 {
		return v1 > v2
	}
	// If those values are equal, perform lexicographic comparison based on
	// the groups field, a slice of [count rank] pairs ordered by highest
	// count first, then highest rank first.
	for i := range h1.groups {
		// Since v1 == v2, the groups are the same length and the
		// counts are identical. Therefore, compare ranks.
		g1, g2 := h1.groups[i], h2.groups[i]
		rank1, rank2 := g1[1], g2[1]
		switch {
		case rank1 > rank2:
			return true
		case rank1 < rank2:
			return false
		}
	}
	// The problem specifies that ties are not possible, so this
	// should be unreachable. This code path corresponds to
	// two hands being equal in all relevant respects (i.e. they
	// only differ by suit).
	return false
}

func problem54() int {
	file, err := os.Open("data/poker.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	var count int // Count of number of times Player 1 wins
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		row := scanner.Text()
		cards := strings.Split(row, " ")
		h1, h2 := newHand(cards[:5]), newHand(cards[5:])
		if player1wins(h1, h2) {
			count++
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
	return count
}

func main() {
	ans := problem54()
	fmt.Println(ans)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/parnurzeal/gorequest"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

///////////////////////////// CLI ENTRYPOINT //////////////////////////////////

func LoadDefaultConfigOrExit(http *gorequest.SuperAgent) *Config {
	pth := defaultConfigPath()
	errout := []error{}

	_, err := os.Stat(pth)

	if os.IsNotExist(err) {
		errout = append(errout, errors.New("No config file existed at "+pth+". You need to `nelson login` before running other commands."))
	}

	x, parsed := readConfigFile(pth)

	if x != nil {
		errout = append(errout, errors.New("Unable to read configuration file at '"+pth+"'. Reported error was: "+x.Error()))
	}

	ve := parsed.Validate()

	if ve != nil {
		errout = append(errout, ve...) // TIM: wtf golang, ... means "expand these as vararg function application"
	}

	// if there are errors loading the config, assume its an expired
	// token and try to regenerate the configuration
	if errout != nil {
		// configuration file does not exist
		if err != nil {
			bailout(errout)
		}

		if len(ve) > 0 {
			// retry the login based on information we know
			x := attemptConfigRefresh(http, parsed)
			// if that didnt help, then bail out and report the issue to the user.
			if x != nil {
				errout = append(errout, x...)
				bailout(errout)
			}
			_, contents := readConfigFile(pth)
			return contents
		}
	}
	// if regular loading of the config worked, then
	// just go with that! #happypath
	return parsed
}

func attemptConfigRefresh(http *gorequest.SuperAgent, existing *Config) []error {
	errout := []error{}
	var ghToken string = os.Getenv("GITHUB_TOKEN")
	e, u := hostFromUri(existing.Endpoint)
	if e != nil {
		return []error{e}
	}
	if len([]rune(ghToken)) == 0 {
		errout = append(errout, errors.New("Environment GITHUB_TOKEN variable not defined. "))
		bailout(errout)
		// return []error{errout}
	}
	if len([]rune(ghToken)) != 0{
		fmt.Println("Attempted token refresh...")
	}
	return Login(http, os.Getenv("GITHUB_TOKEN"), u, false)
}

func bailout(errors []error) {
	fmt.Println("🚫")
	fmt.Println("Encountered an unexpected problem(s) loading the configuration file: ")
	PrintTerminalErrors(errors)
	os.Exit(1)
}

////////////////////////////// CONFIG YAML ///////////////////////////////////

type Config struct {
	Endpoint      string `yaml:endpoint`
	ConfigSession `yaml:"session"`
}

type ConfigSession struct {
	Token     string `yaml:"token"`
	ExpiresAt int64  `yaml:"expires_at"`
}

func (c *Config) GetAuthCookie() *http.Cookie {
	expire := time.Now().AddDate(0, 0, 1)
	cookie := &http.Cookie{
		Name:       "nelson.session",
		Value:      c.ConfigSession.Token,
		Path:       "/",
		Domain:     "nelson-beta.oncue.verizon.net",
		Expires:    expire,
		RawExpires: expire.Format(time.UnixDate),
		MaxAge:     86400,
		Secure:     true,
		HttpOnly:   false,
	}

	return cookie
}

func generateConfigYaml(s Session, url string) string {
	temp := &Config{
		Endpoint: url,
		ConfigSession: ConfigSession{
			Token:     s.SessionToken,
			ExpiresAt: s.ExpiresAt,
		},
	}

	d, err := yaml.Marshal(&temp)
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	return "---\n" + string(d)
}

func parseConfigYaml(yamlAsBytes []byte) *Config {
	temp := &Config{}
	err := yaml.Unmarshal(yamlAsBytes, &temp)
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	return temp
}

func (c *Config) Validate() []error {
	// check that the token has not expired
	errs := []error{}

	if c.ConfigSession.ExpiresAt <= currentTimeMillis() {
		errs = append(errs, errors.New("Your session has expired. Please 'nelson login' again to reactivate your session."))
	}
	return errs
}

/////////////////////////////// CONFIG I/O ////////////////////////////////////

func defaultConfigPath() string {
	targetDir := os.Getenv("HOME") + "/.nelson"
	os.Mkdir(targetDir, 0775)
	return targetDir + "/config.yml"
}

// returns Unit, no error handling. YOLO
func writeConfigFile(s Session, url string, configPath string) {
	yamlConfig := generateConfigYaml(s, url)

	err := ioutil.WriteFile(configPath, []byte(yamlConfig), 0755)
	if err != nil {
		panic(err)
	}
}

func readConfigFile(configPath string) (error, *Config) {
	b, err := ioutil.ReadFile(configPath)
	return err, parseConfigYaml(b) // TIM: parsing never fails, right? ;-)
}
<commit_msg>change syntax<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/parnurzeal/gorequest"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

///////////////////////////// CLI ENTRYPOINT //////////////////////////////////

func LoadDefaultConfigOrExit(http *gorequest.SuperAgent) *Config {
	pth := defaultConfigPath()
	errout := []error{}

	_, err := os.Stat(pth)

	if os.IsNotExist(err) {
		errout = append(errout, errors.New("No config file existed at "+pth+". You need to `nelson login` before running other commands."))
	}

	x, parsed := readConfigFile(pth)

	if x != nil {
		errout = append(errout, errors.New("Unable to read configuration file at '"+pth+"'. Reported error was: "+x.Error()))
	}

	ve := parsed.Validate()

	if ve != nil {
		errout = append(errout, ve...) // TIM: wtf golang, ... means "expand these as vararg function application"
	}

	// if there are errors loading the config, assume its an expired
	// token and try to regenerate the configuration
	if errout != nil {
		// configuration file does not exist
		if err != nil {
			bailout(errout)
		}

		if len(ve) > 0 {
			// retry the login based on information we know
			x := attemptConfigRefresh(http, parsed)
			// if that didnt help, then bail out and report the issue to the user.
			if x != nil {
				errout = append(errout, x...)
				bailout(errout)
			}
			_, contents := readConfigFile(pth)
			return contents
		}
	}
	// if regular loading of the config worked, then
	// just go with that! #happypath
	return parsed
}

func attemptConfigRefresh(http *gorequest.SuperAgent, existing *Config) []error {
	errout := []error{}
	var ghToken string = os.Getenv("GITHUB_TOKEN")
	e, u := hostFromUri(existing.Endpoint)
	if e != nil {
		return []error{e}
	}
	if len([]rune(ghToken)) == 0 {
		errout = append(errout, errors.New("Environment GITHUB_TOKEN variable not defined. "))
		bailout(errout)
		// return []error{errout}
	}
	fmt.Println("Attempted token refresh...")
	return Login(http, ghToken, u, false)
}

func bailout(errors []error) {
	fmt.Println("🚫")
	fmt.Println("Encountered an unexpected problem(s) loading the configuration file: ")
	PrintTerminalErrors(errors)
	os.Exit(1)
}

////////////////////////////// CONFIG YAML ///////////////////////////////////

type Config struct {
	Endpoint      string `yaml:endpoint`
	ConfigSession `yaml:"session"`
}

type ConfigSession struct {
	Token     string `yaml:"token"`
	ExpiresAt int64  `yaml:"expires_at"`
}

func (c *Config) GetAuthCookie() *http.Cookie {
	expire := time.Now().AddDate(0, 0, 1)
	cookie := &http.Cookie{
		Name:       "nelson.session",
		Value:      c.ConfigSession.Token,
		Path:       "/",
		Domain:     "nelson-beta.oncue.verizon.net",
		Expires:    expire,
		RawExpires: expire.Format(time.UnixDate),
		MaxAge:     86400,
		Secure:     true,
		HttpOnly:   false,
	}

	return cookie
}

func generateConfigYaml(s Session, url string) string {
	temp := &Config{
		Endpoint: url,
		ConfigSession: ConfigSession{
			Token:     s.SessionToken,
			ExpiresAt: s.ExpiresAt,
		},
	}

	d, err := yaml.Marshal(&temp)
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	return "---\n" + string(d)
}

func parseConfigYaml(yamlAsBytes []byte) *Config {
	temp := &Config{}
	err := yaml.Unmarshal(yamlAsBytes, &temp)
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	return temp
}

func (c *Config) Validate() []error {
	// check that the token has not expired
	errs := []error{}

	if c.ConfigSession.ExpiresAt <= currentTimeMillis() {
		errs = append(errs, errors.New("Your session has expired. Please 'nelson login' again to reactivate your session."))
	}
	return errs
}

/////////////////////////////// CONFIG I/O ////////////////////////////////////

func defaultConfigPath() string {
	targetDir := os.Getenv("HOME") + "/.nelson"
	os.Mkdir(targetDir, 0775)
	return targetDir + "/config.yml"
}

// returns Unit, no error handling. YOLO
func writeConfigFile(s Session, url string, configPath string) {
	yamlConfig := generateConfigYaml(s, url)

	err := ioutil.WriteFile(configPath, []byte(yamlConfig), 0755)
	if err != nil {
		panic(err)
	}
}

func readConfigFile(configPath string) (error, *Config) {
	b, err := ioutil.ReadFile(configPath)
	return err, parseConfigYaml(b) // TIM: parsing never fails, right? ;-)
}
<|endoftext|>