<commit_before>// Copyright 2010-2012 The W32 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 w32

<<<<<<< HEAD
// #include <stdlib.h>
import (
	"C"
)

import (
	"fmt"
	// "github.com/davecgh/go-spew/spew"
=======
import (
	"errors"
>>>>>>> add some ALPC
	"syscall"
	"unsafe"
)

var (
<<<<<<< HEAD
	modntdll = syscall.NewLazyDLL("ntdll.dll")

	procAlpcGetMessageAttribute          = modntdll.NewProc("AlpcGetMessageAttribute")
	procNtAlpcAcceptConnectPort          = modntdll.NewProc("NtAlpcAcceptConnectPort")
	procNtAlpcCancelMessage              = modntdll.NewProc("NtAlpcCancelMessage")
	procNtAlpcConnectPort                = modntdll.NewProc("NtAlpcConnectPort")
	procNtAlpcCreatePort                 = modntdll.NewProc("NtAlpcCreatePort")
	procNtAlpcDisconnectPort             = modntdll.NewProc("NtAlpcDisconnectPort")
	procNtAlpcSendWaitReceivePort        = modntdll.NewProc("NtAlpcSendWaitReceivePort")
	procRtlCreateUnicodeStringFromAsciiz = modntdll.NewProc("RtlCreateUnicodeStringFromAsciiz")
)

func RtlCreateUnicodeStringFromAsciiz(s string) (us UNICODE_STRING, e error) {

	cs := C.CString(s)
	defer C.free(unsafe.Pointer(cs))

	ret, _, lastErr := procRtlCreateUnicodeStringFromAsciiz.Call(
		uintptr(unsafe.Pointer(&us)),
		uintptr(unsafe.Pointer(cs)),
	)

	if ret != 1 { // ret is a BOOL ( I think )
		e = lastErr
	}

	return
}

func newUnicodeString(s string) (us UNICODE_STRING, e error) {
	// TODO probably not the most efficient way to do this, but I couldn't
	// work out how to manually initialize the UNICODE_STRING struct in a way
	// that the ALPC subsystem liked.
	us, e = RtlCreateUnicodeStringFromAsciiz(s)
=======
	modkernel32 = syscall.NewLazyDLL("ntdll.dll")

	procNtAlpcCreatePort = modadvapi32.NewProc("NtAlpcCreatePort")
)

func newUnicodeString(s string) (us UNICODE_STRING, e error) {
	ustr, err := syscall.UTF16FromString(s)
	if err != nil {
		e = err
		return
	}
	us.Length = len(ustr)
	us.MaximumLength = len(ustr)
	us.Buffer = unsafe.Pointer(&ustr[0])
>>>>>>> add some ALPC
	return
}

// (this is a macro)
// VOID InitializeObjectAttributes(
//   [out]           POBJECT_ATTRIBUTES InitializedAttributes,
//   [in]            PUNICODE_STRING ObjectName,
//   [in]            ULONG Attributes,
//   [in]            HANDLE RootDirectory,
//   [in, optional]  PSECURITY_DESCRIPTOR SecurityDescriptor
// )
<<<<<<< HEAD
func InitializeObjectAttributes(
=======
func NewObjectAttributes(
>>>>>>> add some ALPC
	name string,
	attributes uint32,
	rootDir HANDLE,
	pSecurityDescriptor *SECURITY_DESCRIPTOR,
<<<<<<< HEAD
) (oa OBJECT_ATTRIBUTES, e error) {

	oa = OBJECT_ATTRIBUTES{
		RootDirectory:      rootDir,
		Attributes:         attributes,
		SecurityDescriptor: pSecurityDescriptor,
	}
	oa.Length = uint32(unsafe.Sizeof(oa))

	if len(name) > 0 {
		us, err := newUnicodeString(name)
		if err != nil {
			e = err
			return
		}
		oa.ObjectName = &us
	}

	return
}

// NTSTATUS
// NtAlpcCreatePort(
//   __out PHANDLE PortHandle,
//   __in POBJECT_ATTRIBUTES ObjectAttributes,
//   __in_opt PALPC_PORT_ATTRIBUTES PortAttributes
//   );
func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) {

	ret, _, _ := procNtAlpcCreatePort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(unsafe.Pointer(pObjectAttributes)),
		uintptr(unsafe.Pointer(pPortAttributes)),
	)

	if ret != ERROR_SUCCESS {
		return hPort, fmt.Errorf("0x%x", ret)
	}

	return
}

// NTSTATUS
// NtAlpcConnectPort(
//     __out PHANDLE PortHandle,
//     __in PUNICODE_STRING PortName,
//     __in POBJECT_ATTRIBUTES ObjectAttributes,
//     __in_opt PALPC_PORT_ATTRIBUTES PortAttributes,
//     __in ULONG Flags,
//     __in_opt PSID RequiredServerSid,
//     __inout PPORT_MESSAGE ConnectionMessage,
//     __inout_opt PULONG BufferLength,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
//     __in_opt PLARGE_INTEGER Timeout
//     );
func NtAlpcConnectPort(
	destPort string,
	pClientObjAttrs *OBJECT_ATTRIBUTES,
	pClientAlpcPortAttrs *ALPC_PORT_ATTRIBUTES,
	flags uint32,
	pRequiredServerSid *SID,
	pConnMsg *AlpcShortMessage,
	pBufLen *uint32,
	pOutMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	pInMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	timeout *int64,
) (hPort HANDLE, e error) {

	destPortU, e := newUnicodeString(destPort)
	if e != nil {
		return
	}

	ret, _, _ := procNtAlpcConnectPort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(unsafe.Pointer(&destPortU)),
		uintptr(unsafe.Pointer(pClientObjAttrs)),
		uintptr(unsafe.Pointer(pClientAlpcPortAttrs)),
		uintptr(flags),
		uintptr(unsafe.Pointer(pRequiredServerSid)),
		uintptr(unsafe.Pointer(pConnMsg)),
		uintptr(unsafe.Pointer(pBufLen)),
		uintptr(unsafe.Pointer(pOutMsgAttrs)),
		uintptr(unsafe.Pointer(pInMsgAttrs)),
		uintptr(unsafe.Pointer(timeout)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSTATUS
// NtAlpcAcceptConnectPort(
//     __out PHANDLE PortHandle,
//     __in HANDLE ConnectionPortHandle,
//     __in ULONG Flags,
//     __in POBJECT_ATTRIBUTES ObjectAttributes,
//     __in PALPC_PORT_ATTRIBUTES PortAttributes,
//     __in_opt PVOID PortContext,
//     __in PPORT_MESSAGE ConnectionRequest,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
//     __in BOOLEAN AcceptConnection
//     );
func NtAlpcAcceptConnectPort(
	hSrvConnPort HANDLE,
	flags uint32,
	pObjAttr *OBJECT_ATTRIBUTES,
	pPortAttr *ALPC_PORT_ATTRIBUTES,
	pContext *AlpcPortContext,
	pConnReq *AlpcShortMessage,
	pConnMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	accept uintptr,
) (hPort HANDLE, e error) {

	ret, _, _ := procNtAlpcAcceptConnectPort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(hSrvConnPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(pObjAttr)),
		uintptr(unsafe.Pointer(pPortAttr)),
		uintptr(unsafe.Pointer(pContext)),
		uintptr(unsafe.Pointer(pConnReq)),
		uintptr(unsafe.Pointer(pConnMsgAttrs)),
		accept,
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSTATUS
// NtAlpcSendWaitReceivePort(
//     __in HANDLE PortHandle,
//     __in ULONG Flags,
//     __in_opt PPORT_MESSAGE SendMessage,
//     __in_opt PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
//     __inout_opt PPORT_MESSAGE ReceiveMessage,
//     __inout_opt PULONG BufferLength,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
//     __in_opt PLARGE_INTEGER Timeout
//     );
func NtAlpcSendWaitReceivePort(
	hPort HANDLE,
	flags uint32,
	sendMsg *AlpcShortMessage, // Should actually point to PORT_MESSAGE + payload
	sendMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	recvMsg *AlpcShortMessage,
	recvBufLen *uint32,
	recvMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	timeout *int64, // use native int64
) (e error) {

	ret, _, _ := procNtAlpcSendWaitReceivePort.Call(
		uintptr(hPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(sendMsg)),
		uintptr(unsafe.Pointer(sendMsgAttrs)),
		uintptr(unsafe.Pointer(recvMsg)),
		uintptr(unsafe.Pointer(recvBufLen)),
		uintptr(unsafe.Pointer(recvMsgAttrs)),
		uintptr(unsafe.Pointer(timeout)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSYSAPI
// PVOID
// NTAPI
// AlpcGetMessageAttribute(
//     __in PALPC_MESSAGE_ATTRIBUTES Buffer,
//     __in ULONG AttributeFlag
//     );

// This basically returns a pointer to the correct struct for whichever
// message attribute you asked for. In Go terms, it returns unsafe.Pointer
// which you should then cast. Example:

// ptr := AlpcGetMessageAttribute(&recvMsgAttrs, ALPC_MESSAGE_CONTEXT_ATTRIBUTE)
// if ptr != nil {
//     context := (*ALPC_CONTEXT_ATTR)(ptr)
// }
func AlpcGetMessageAttribute(buf *ALPC_MESSAGE_ATTRIBUTES, attr uint32) unsafe.Pointer {

	ret, _, _ := procAlpcGetMessageAttribute.Call(
		uintptr(unsafe.Pointer(buf)),
		uintptr(attr),
	)
	return unsafe.Pointer(ret)
}

// NTSYSCALLAPI
// NTSTATUS
// NTAPI
// NtAlpcCancelMessage(
//     __in HANDLE PortHandle,
//     __in ULONG Flags,
//     __in PALPC_CONTEXT_ATTR MessageContext
//     );
func NtAlpcCancelMessage(hPort HANDLE, flags uint32, pMsgContext *ALPC_CONTEXT_ATTR) (e error) {

	ret, _, _ := procNtAlpcCancelMessage.Call(
		uintptr(hPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(pMsgContext)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSYSCALLAPI
// NTSTATUS
// NTAPI
// NtAlpcDisconnectPort(
//     __in HANDLE PortHandle,
//     __in ULONG Flags
//     );
func NtAlpcDisconnectPort(hPort HANDLE, flags uint32) (e error) {

	ret, _, _ := procNtAlpcDisconnectPort.Call(
		uintptr(hPort),
		uintptr(flags),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
=======
) (objectAttributes OBJECT_ATTRIBUTES, e error) {

	unicodeString, err := newUnicodeString(name)
	if err != nil {
		e = err
		return
	}

	objectAttributes = OBJECT_ATTRIBUTES{
		RootDirectory:      rootDir,
		ObjectName:         &unicodeString,
		Attributes:         attributes,
		SecurityDescriptor: pSecurityDescriptor,
	}
	return
}

// # NTSTATUS
// # NtAlpcCreatePort(
// #   __out PHANDLE PortHandle,
// #   __in POBJECT_ATTRIBUTES ObjectAttributes,
// #   __in_opt PALPC_PORT_ATTRIBUTES PortAttributes
// #   );
func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) {

	pHandle := &hPort
	ret, _, _ := procNtAlpcCreatePort.Call(
		uintptr(unsafe.Pointer(pHandle)),
		uintptr(unsafe.Pointer(pObjectAttributes)),
		uintptr(unsafe.Pointer(pPortAttributes)),
	)
	if ret != ERROR_SUCCESS {
		return hPort, errors.New(ret)
	}

>>>>>>> add some ALPC
	return
}
<commit_msg>bugfix<commit_after>// Copyright 2010-2012 The W32 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 w32

// #include <stdlib.h>
import (
	"C"
)

import (
	"fmt"
	// "github.com/davecgh/go-spew/spew"
	"syscall"
	"unsafe"
)

var (
	modntdll = syscall.NewLazyDLL("ntdll.dll")

	procAlpcGetMessageAttribute          = modntdll.NewProc("AlpcGetMessageAttribute")
	procNtAlpcAcceptConnectPort          = modntdll.NewProc("NtAlpcAcceptConnectPort")
	procNtAlpcCancelMessage              = modntdll.NewProc("NtAlpcCancelMessage")
	procNtAlpcConnectPort                = modntdll.NewProc("NtAlpcConnectPort")
	procNtAlpcCreatePort                 = modntdll.NewProc("NtAlpcCreatePort")
	procNtAlpcDisconnectPort             = modntdll.NewProc("NtAlpcDisconnectPort")
	procNtAlpcSendWaitReceivePort        = modntdll.NewProc("NtAlpcSendWaitReceivePort")
	procRtlCreateUnicodeStringFromAsciiz = modntdll.NewProc("RtlCreateUnicodeStringFromAsciiz")
)

func RtlCreateUnicodeStringFromAsciiz(s string) (us UNICODE_STRING, e error) {

	cs := C.CString(s)
	defer C.free(unsafe.Pointer(cs))

	ret, _, lastErr := procRtlCreateUnicodeStringFromAsciiz.Call(
		uintptr(unsafe.Pointer(&us)),
		uintptr(unsafe.Pointer(cs)),
	)

	if ret != 1 { // ret is a BOOL ( I think )
		e = lastErr
	}

	return
}

func newUnicodeString(s string) (us UNICODE_STRING, e error) {
	// TODO probably not the most efficient way to do this, but I couldn't
	// work out how to manually initialize the UNICODE_STRING struct in a way
	// that the ALPC subsystem liked.
	us, e = RtlCreateUnicodeStringFromAsciiz(s)
	return
}

// (this is a macro)
// VOID InitializeObjectAttributes(
//   [out]           POBJECT_ATTRIBUTES InitializedAttributes,
//   [in]            PUNICODE_STRING ObjectName,
//   [in]            ULONG Attributes,
//   [in]            HANDLE RootDirectory,
//   [in, optional]  PSECURITY_DESCRIPTOR SecurityDescriptor
// )
func InitializeObjectAttributes(
	name string,
	attributes uint32,
	rootDir HANDLE,
	pSecurityDescriptor *SECURITY_DESCRIPTOR,
) (oa OBJECT_ATTRIBUTES, e error) {

	oa = OBJECT_ATTRIBUTES{
		RootDirectory:      rootDir,
		Attributes:         attributes,
		SecurityDescriptor: pSecurityDescriptor,
	}
	oa.Length = uint32(unsafe.Sizeof(oa))

	if len(name) > 0 {
		us, err := newUnicodeString(name)
		if err != nil {
			e = err
			return
		}
		oa.ObjectName = &us
	}

	return
}

// NTSTATUS
// NtAlpcCreatePort(
//   __out PHANDLE PortHandle,
//   __in POBJECT_ATTRIBUTES ObjectAttributes,
//   __in_opt PALPC_PORT_ATTRIBUTES PortAttributes
//   );
func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) {

	ret, _, _ := procNtAlpcCreatePort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(unsafe.Pointer(pObjectAttributes)),
		uintptr(unsafe.Pointer(pPortAttributes)),
	)

	if ret != ERROR_SUCCESS {
		return hPort, fmt.Errorf("0x%x", ret)
	}

	return
}

// NTSTATUS
// NtAlpcConnectPort(
//     __out PHANDLE PortHandle,
//     __in PUNICODE_STRING PortName,
//     __in POBJECT_ATTRIBUTES ObjectAttributes,
//     __in_opt PALPC_PORT_ATTRIBUTES PortAttributes,
//     __in ULONG Flags,
//     __in_opt PSID RequiredServerSid,
//     __inout PPORT_MESSAGE ConnectionMessage,
//     __inout_opt PULONG BufferLength,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
//     __in_opt PLARGE_INTEGER Timeout
//     );
func NtAlpcConnectPort(
	destPort string,
	pClientObjAttrs *OBJECT_ATTRIBUTES,
	pClientAlpcPortAttrs *ALPC_PORT_ATTRIBUTES,
	flags uint32,
	pRequiredServerSid *SID,
	pConnMsg *AlpcShortMessage,
	pBufLen *uint32,
	pOutMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	pInMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	timeout *int64,
) (hPort HANDLE, e error) {

	destPortU, e := newUnicodeString(destPort)
	if e != nil {
		return
	}

	ret, _, _ := procNtAlpcConnectPort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(unsafe.Pointer(&destPortU)),
		uintptr(unsafe.Pointer(pClientObjAttrs)),
		uintptr(unsafe.Pointer(pClientAlpcPortAttrs)),
		uintptr(flags),
		uintptr(unsafe.Pointer(pRequiredServerSid)),
		uintptr(unsafe.Pointer(pConnMsg)),
		uintptr(unsafe.Pointer(pBufLen)),
		uintptr(unsafe.Pointer(pOutMsgAttrs)),
		uintptr(unsafe.Pointer(pInMsgAttrs)),
		uintptr(unsafe.Pointer(timeout)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSTATUS
// NtAlpcAcceptConnectPort(
//     __out PHANDLE PortHandle,
//     __in HANDLE ConnectionPortHandle,
//     __in ULONG Flags,
//     __in POBJECT_ATTRIBUTES ObjectAttributes,
//     __in PALPC_PORT_ATTRIBUTES PortAttributes,
//     __in_opt PVOID PortContext,
//     __in PPORT_MESSAGE ConnectionRequest,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
//     __in BOOLEAN AcceptConnection
//     );
func NtAlpcAcceptConnectPort(
	hSrvConnPort HANDLE,
	flags uint32,
	pObjAttr *OBJECT_ATTRIBUTES,
	pPortAttr *ALPC_PORT_ATTRIBUTES,
	pContext *AlpcPortContext,
	pConnReq *AlpcShortMessage,
	pConnMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	accept uintptr,
) (hPort HANDLE, e error) {

	ret, _, _ := procNtAlpcAcceptConnectPort.Call(
		uintptr(unsafe.Pointer(&hPort)),
		uintptr(hSrvConnPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(pObjAttr)),
		uintptr(unsafe.Pointer(pPortAttr)),
		uintptr(unsafe.Pointer(pContext)),
		uintptr(unsafe.Pointer(pConnReq)),
		uintptr(unsafe.Pointer(pConnMsgAttrs)),
		accept,
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSTATUS
// NtAlpcSendWaitReceivePort(
//     __in HANDLE PortHandle,
//     __in ULONG Flags,
//     __in_opt PPORT_MESSAGE SendMessage,
//     __in_opt PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
//     __inout_opt PPORT_MESSAGE ReceiveMessage,
//     __inout_opt PULONG BufferLength,
//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
//     __in_opt PLARGE_INTEGER Timeout
//     );
func NtAlpcSendWaitReceivePort(
	hPort HANDLE,
	flags uint32,
	sendMsg *AlpcShortMessage, // Should actually point to PORT_MESSAGE + payload
	sendMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	recvMsg *AlpcShortMessage,
	recvBufLen *uint32,
	recvMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
	timeout *int64, // use native int64
) (e error) {

	ret, _, _ := procNtAlpcSendWaitReceivePort.Call(
		uintptr(hPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(sendMsg)),
		uintptr(unsafe.Pointer(sendMsgAttrs)),
		uintptr(unsafe.Pointer(recvMsg)),
		uintptr(unsafe.Pointer(recvBufLen)),
		uintptr(unsafe.Pointer(recvMsgAttrs)),
		uintptr(unsafe.Pointer(timeout)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSYSAPI
// PVOID
// NTAPI
// AlpcGetMessageAttribute(
//     __in PALPC_MESSAGE_ATTRIBUTES Buffer,
//     __in ULONG AttributeFlag
//     );

// This basically returns a pointer to the correct struct for whichever
// message attribute you asked for. In Go terms, it returns unsafe.Pointer
// which you should then cast. Example:

// ptr := AlpcGetMessageAttribute(&recvMsgAttrs, ALPC_MESSAGE_CONTEXT_ATTRIBUTE)
// if ptr != nil {
//     context := (*ALPC_CONTEXT_ATTR)(ptr)
// }
func AlpcGetMessageAttribute(buf *ALPC_MESSAGE_ATTRIBUTES, attr uint32) unsafe.Pointer {

	ret, _, _ := procAlpcGetMessageAttribute.Call(
		uintptr(unsafe.Pointer(buf)),
		uintptr(attr),
	)
	return unsafe.Pointer(ret)
}

// NTSYSCALLAPI
// NTSTATUS
// NTAPI
// NtAlpcCancelMessage(
//     __in HANDLE PortHandle,
//     __in ULONG Flags,
//     __in PALPC_CONTEXT_ATTR MessageContext
//     );
func NtAlpcCancelMessage(hPort HANDLE, flags uint32, pMsgContext *ALPC_CONTEXT_ATTR) (e error) {

	ret, _, _ := procNtAlpcCancelMessage.Call(
		uintptr(hPort),
		uintptr(flags),
		uintptr(unsafe.Pointer(pMsgContext)),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}

// NTSYSCALLAPI
// NTSTATUS
// NTAPI
// NtAlpcDisconnectPort(
//     __in HANDLE PortHandle,
//     __in ULONG Flags
//     );
func NtAlpcDisconnectPort(hPort HANDLE, flags uint32) (e error) {

	ret, _, _ := procNtAlpcDisconnectPort.Call(
		uintptr(hPort),
		uintptr(flags),
	)

	if ret != ERROR_SUCCESS {
		e = fmt.Errorf("0x%x", ret)
	}
	return
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package protokube

import (
	"fmt"
	"github.com/golang/glog"
	"k8s.io/kops/dns-controller/pkg/dns"
	"net"
	"os/exec"
	"time"
)

type KubeBoot struct {
	Master            bool
	InternalDNSSuffix string
	InternalIP        net.IP
	//MasterID          int
	//EtcdClusters      []*EtcdClusterSpec

	volumeMounter   *VolumeMountController
	etcdControllers map[string]*EtcdController

	DNSScope dns.Scope

	ModelDir string

	Channels []string

	Kubernetes *KubernetesContext
}

func (k *KubeBoot) Init(volumesProvider Volumes) {
	k.volumeMounter = newVolumeMountController(volumesProvider)
	k.etcdControllers = make(map[string]*EtcdController)
}

var Containerized = false
var RootFS = "/"

func PathFor(hostPath string) string {
	if hostPath[0] != '/' {
		glog.Fatalf("path was not absolute: %q", hostPath)
	}
	return RootFS + hostPath[1:]
}

func (k *KubeBoot) String() string {
	return DebugString(k)
}

func (k *KubeBoot) RunSyncLoop() {
	for {
		err := k.syncOnce()
		if err != nil {
			glog.Warningf("error during attempt to bootstrap (will sleep and retry): %v", err)
		}

		time.Sleep(1 * time.Minute)
	}
}

func (k *KubeBoot) syncOnce() error {
	if k.Master {
		volumes, err := k.volumeMounter.mountMasterVolumes()
		if err != nil {
			return err
		}

		for _, v := range volumes {
			for _, etcdClusterSpec := range v.Info.EtcdClusters {
				key := etcdClusterSpec.ClusterKey + "::" + etcdClusterSpec.NodeName
				etcdController := k.etcdControllers[key]
				if etcdController == nil {
					glog.Infof("Found etcd cluster spec on volume %q: %v", v.ID, etcdClusterSpec)

					etcdController, err := newEtcdController(k, v, etcdClusterSpec)
					if err != nil {
						glog.Warningf("error building etcd controller: %v", err)
					} else {
						k.etcdControllers[key] = etcdController
						go etcdController.RunSyncLoop()
					}
				}
			}
		}

		//// Copy roles from volume
		//k.EtcdClusters = volumeInfo.EtcdClusters
		//for _, etcdClusterSpec := range volumeInfo.EtcdClusters {
		//	glog.Infof("Found etcd cluster spec on volume: %v", etcdClusterSpec)
		//}

		//k.MasterID = volumeInfo.MasterID

		// TODO: Should we set up symlinks here?
	}

	if k.Master {
		if err := ApplyMasterTaints(k.Kubernetes); err != nil {
			glog.Warningf("error updating master taints: %v", err)
		}
	}

	// Ensure kubelet is running. We avoid doing this automatically so
	// that when kubelet comes up the first time, all volume mounts
	// and DNS are available, avoiding the scenario where
	// etcd/apiserver retry too many times and go into backoff.
	if err := enableKubelet(); err != nil {
		glog.Warningf("error ensuring kubelet started: %v", err)
	}

	for _, channel := range k.Channels {
		if err := ApplyChannel(channel); err != nil {
			glog.Warningf("error applying channel %q: %v", channel, err)
		}
	}

	return nil
}

// enableKubelet: Make sure kubelet is running.
func enableKubelet() error {
	cmd := exec.Command("systemctl", "start", "--no-block", "kubelet")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("error starting kubelet: %v\nOutput: %s", err, output)
	}
	return nil
}
<commit_msg>protokube: log when starting kubelet<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package protokube

import (
	"fmt"
	"github.com/golang/glog"
	"k8s.io/kops/dns-controller/pkg/dns"
	"net"
	"os/exec"
	"time"
)

type KubeBoot struct {
	Master            bool
	InternalDNSSuffix string
	InternalIP        net.IP
	//MasterID          int
	//EtcdClusters      []*EtcdClusterSpec

	volumeMounter   *VolumeMountController
	etcdControllers map[string]*EtcdController

	DNSScope dns.Scope

	ModelDir string

	Channels []string

	Kubernetes *KubernetesContext
}

func (k *KubeBoot) Init(volumesProvider Volumes) {
	k.volumeMounter = newVolumeMountController(volumesProvider)
	k.etcdControllers = make(map[string]*EtcdController)
}

var Containerized = false
var RootFS = "/"

func PathFor(hostPath string) string {
	if hostPath[0] != '/' {
		glog.Fatalf("path was not absolute: %q", hostPath)
	}
	return RootFS + hostPath[1:]
}

func (k *KubeBoot) String() string {
	return DebugString(k)
}

func (k *KubeBoot) RunSyncLoop() {
	for {
		err := k.syncOnce()
		if err != nil {
			glog.Warningf("error during attempt to bootstrap (will sleep and retry): %v", err)
		}

		time.Sleep(1 * time.Minute)
	}
}

func (k *KubeBoot) syncOnce() error {
	if k.Master {
		volumes, err := k.volumeMounter.mountMasterVolumes()
		if err != nil {
			return err
		}

		for _, v := range volumes {
			for _, etcdClusterSpec := range v.Info.EtcdClusters {
				key := etcdClusterSpec.ClusterKey + "::" + etcdClusterSpec.NodeName
				etcdController := k.etcdControllers[key]
				if etcdController == nil {
					glog.Infof("Found etcd cluster spec on volume %q: %v", v.ID, etcdClusterSpec)

					etcdController, err := newEtcdController(k, v, etcdClusterSpec)
					if err != nil {
						glog.Warningf("error building etcd controller: %v", err)
					} else {
						k.etcdControllers[key] = etcdController
						go etcdController.RunSyncLoop()
					}
				}
			}
		}

		//// Copy roles from volume
		//k.EtcdClusters = volumeInfo.EtcdClusters
		//for _, etcdClusterSpec := range volumeInfo.EtcdClusters {
		//	glog.Infof("Found etcd cluster spec on volume: %v", etcdClusterSpec)
		//}

		//k.MasterID = volumeInfo.MasterID

		// TODO: Should we set up symlinks here?
	}

	if k.Master {
		if err := ApplyMasterTaints(k.Kubernetes); err != nil {
			glog.Warningf("error updating master taints: %v", err)
		}
	}

	// Ensure kubelet is running. We avoid doing this automatically so
	// that when kubelet comes up the first time, all volume mounts
	// and DNS are available, avoiding the scenario where
	// etcd/apiserver retry too many times and go into backoff.
	if err := enableKubelet(); err != nil {
		glog.Warningf("error ensuring kubelet started: %v", err)
	}

	for _, channel := range k.Channels {
		if err := ApplyChannel(channel); err != nil {
			glog.Warningf("error applying channel %q: %v", channel, err)
		}
	}

	return nil
}

// enableKubelet: Make sure kubelet is running.
func enableKubelet() error {
	// TODO: Check/log status of kubelet
	// (in particular, we want to avoid kubernetes/kubernetes#40123 )
	glog.V(2).Infof("ensuring that kubelet systemd service is running")
	cmd := exec.Command("systemctl", "start", "--no-block", "kubelet")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("error starting kubelet: %v\nOutput: %s", err, output)
	}
	return nil
}
<|endoftext|>


<commit_before>package integration_test

import (
	"fmt"
	"strings"

	integration "github.com/cloudfoundry/bosh-bootloader/integration-test"
	"github.com/cloudfoundry/bosh-bootloader/integration-test/actors"
	"github.com/cloudfoundry/bosh-bootloader/testhelpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("load balancer tests", func() {
	var (
		bbl     actors.BBL
		aws     actors.AWS
		bosh    actors.BOSH
		boshcli actors.BOSHCLI
		state   integration.State
	)

	BeforeEach(func() {
		var err error
		configuration, err := integration.LoadAWSConfig()
		Expect(err).NotTo(HaveOccurred())

		bbl = actors.NewBBL(configuration.StateFileDir, pathToBBL, configuration)
		aws = actors.NewAWS(configuration)
		bosh = actors.NewBOSH()
		boshcli = actors.NewBOSHCLI()
		state = integration.NewState(configuration.StateFileDir)

	})

	It("creates, updates and deletes an LB with the specified cert and key", func() {
		bbl.Up(actors.AWSIAAS)

		stackName := state.StackName()
		directorAddress := bbl.DirectorAddress()
		caCertPath := bbl.SaveDirectorCA()

		Expect(aws.StackExists(stackName)).To(BeTrue())
		Expect(aws.LoadBalancers(stackName)).To(BeEmpty())
		exists, err := boshcli.DirectorExists(directorAddress, caCertPath)
		Expect(err).NotTo(HaveOccurred())
		Expect(exists).To(BeTrue())

		natInstanceID := aws.GetPhysicalID(stackName, "NATInstance")
		Expect(natInstanceID).NotTo(BeEmpty())

		tags := aws.GetEC2InstanceTags(natInstanceID)
		Expect(tags["bbl-env-id"]).To(MatchRegexp(`bbl-env-([a-z]+-{1}){1,2}\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z`))

		certPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_CERT)
		Expect(err).NotTo(HaveOccurred())

		chainPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_CHAIN)
		Expect(err).NotTo(HaveOccurred())

		keyPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_KEY)
		Expect(err).NotTo(HaveOccurred())

		otherCertPath, err := testhelpers.WriteContentsToTempFile(testhelpers.OTHER_BBL_CERT)
		Expect(err).NotTo(HaveOccurred())

		otherKeyPath, err := testhelpers.WriteContentsToTempFile(testhelpers.OTHER_BBL_KEY)
		Expect(err).NotTo(HaveOccurred())

		bbl.CreateLB("concourse", certPath, keyPath, chainPath)

		Expect(aws.LoadBalancers(stackName)).To(HaveKey("ConcourseLoadBalancer"))
		Expect(strings.TrimSpace(aws.DescribeCertificate(state.CertificateName()).Body)).To(Equal(strings.TrimSpace(testhelpers.BBL_CERT)))

		bbl.UpdateLB(otherCertPath, otherKeyPath)
		Expect(aws.LoadBalancers(stackName)).To(HaveKey("ConcourseLoadBalancer"))

		certificateName := state.CertificateName()
		Expect(strings.TrimSpace(aws.DescribeCertificate(certificateName).Body)).To(Equal(strings.TrimSpace(string(testhelpers.OTHER_BBL_CERT))))

		session := bbl.LBs()
		stdout := session.Out.Contents()
		Expect(stdout).To(ContainSubstring(fmt.Sprintf("Concourse LB: %s", aws.LoadBalancers(stackName)["ConcourseLoadBalancer"])))

		bbl.DeleteLB()
		Expect(aws.LoadBalancers(stackName)).NotTo(HaveKey("ConcourseLoadBalancer"))
		Expect(strings.TrimSpace(aws.DescribeCertificate(certificateName).Body)).To(BeEmpty())

		bbl.Destroy()

		exists, _ = boshcli.DirectorExists(directorAddress, caCertPath)
		Expect(exists).To(BeFalse())

		Expect(aws.StackExists(stackName)).To(BeFalse())
	})
})
<commit_msg>Update regex in acceptance test<commit_after>package integration_test

import (
	"fmt"
	"strings"

	integration "github.com/cloudfoundry/bosh-bootloader/integration-test"
	"github.com/cloudfoundry/bosh-bootloader/integration-test/actors"
	"github.com/cloudfoundry/bosh-bootloader/testhelpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("load balancer tests", func() {
	var (
		bbl     actors.BBL
		aws     actors.AWS
		bosh    actors.BOSH
		boshcli actors.BOSHCLI
		state   integration.State
	)

	BeforeEach(func() {
		var err error
		configuration, err := integration.LoadAWSConfig()
		Expect(err).NotTo(HaveOccurred())

		bbl = actors.NewBBL(configuration.StateFileDir, pathToBBL, configuration)
		aws = actors.NewAWS(configuration)
		bosh = actors.NewBOSH()
		boshcli = actors.NewBOSHCLI()
		state = integration.NewState(configuration.StateFileDir)

	})

	It("creates, updates and deletes an LB with the specified cert and key", func() {
		bbl.Up(actors.AWSIAAS)

		stackName := state.StackName()
		directorAddress := bbl.DirectorAddress()
		caCertPath := bbl.SaveDirectorCA()

		Expect(aws.StackExists(stackName)).To(BeTrue())
		Expect(aws.LoadBalancers(stackName)).To(BeEmpty())
		exists, err := boshcli.DirectorExists(directorAddress, caCertPath)
		Expect(err).NotTo(HaveOccurred())
		Expect(exists).To(BeTrue())

		natInstanceID := aws.GetPhysicalID(stackName, "NATInstance")
		Expect(natInstanceID).NotTo(BeEmpty())

		tags := aws.GetEC2InstanceTags(natInstanceID)
		Expect(tags["bbl-env-id"]).To(MatchRegexp(`bbl-env-([a-z]+-{1}){1,2}\d{4}-\d{2}-\d{2}t\d{2}-\d{2}z`))

		certPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_CERT)
		Expect(err).NotTo(HaveOccurred())

		chainPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_CHAIN)
		Expect(err).NotTo(HaveOccurred())

		keyPath, err := testhelpers.WriteContentsToTempFile(testhelpers.BBL_KEY)
		Expect(err).NotTo(HaveOccurred())

		otherCertPath, err := testhelpers.WriteContentsToTempFile(testhelpers.OTHER_BBL_CERT)
		Expect(err).NotTo(HaveOccurred())

		otherKeyPath, err := testhelpers.WriteContentsToTempFile(testhelpers.OTHER_BBL_KEY)
		Expect(err).NotTo(HaveOccurred())

		bbl.CreateLB("concourse", certPath, keyPath, chainPath)

		Expect(aws.LoadBalancers(stackName)).To(HaveKey("ConcourseLoadBalancer"))
		Expect(strings.TrimSpace(aws.DescribeCertificate(state.CertificateName()).Body)).To(Equal(strings.TrimSpace(testhelpers.BBL_CERT)))

		bbl.UpdateLB(otherCertPath, otherKeyPath)
		Expect(aws.LoadBalancers(stackName)).To(HaveKey("ConcourseLoadBalancer"))

		certificateName := state.CertificateName()
		Expect(strings.TrimSpace(aws.DescribeCertificate(certificateName).Body)).To(Equal(strings.TrimSpace(string(testhelpers.OTHER_BBL_CERT))))

		session := bbl.LBs()
		stdout := session.Out.Contents()
		Expect(stdout).To(ContainSubstring(fmt.Sprintf("Concourse LB: %s", aws.LoadBalancers(stackName)["ConcourseLoadBalancer"])))

		bbl.DeleteLB()
		Expect(aws.LoadBalancers(stackName)).NotTo(HaveKey("ConcourseLoadBalancer"))
		Expect(strings.TrimSpace(aws.DescribeCertificate(certificateName).Body)).To(BeEmpty())

		bbl.Destroy()

		exists, _ = boshcli.DirectorExists(directorAddress, caCertPath)
		Expect(exists).To(BeFalse())

		Expect(aws.StackExists(stackName)).To(BeFalse())
	})
})
<|endoftext|>


<commit_before>package ogdat

import (
	"code.google.com/p/go-uuid/uuid"
	"encoding/json"
	"net/url"
	"strconv"
	"time"
)

const OGDTimeSpecifier = "2006-01-02T15:04:05" // RFC 3339 = ISO 8601 ohne Zeitzone
const (
	OGDTime2 = time.RFC3339Nano
	OGDTime3 = time.RFC3339
	OGDTime1 = OGDTimeSpecifier
	OGDTimeUnknow
)

type Kategorie struct {
	NumID       int `json:"-"`
	ID          string
	PrettyName  string `json:"-"`
	RDFProperty string `json:"-"`
}

func (kat *Kategorie) String() string {
	return kat.PrettyName
}

var (
	Arbeit           = Kategorie{NumID: 1, ID: "arbeit", PrettyName: "Arbeit", RDFProperty: ""}
	Bevoelkerung     = Kategorie{NumID: 2, ID: "bevölkerung", PrettyName: "Bevölkerung", RDFProperty: ""}
	BildungForschung = Kategorie{NumID: 3, ID: "bildung-und-forschung", PrettyName: "Bildung und Forschung", RDFProperty: ""}
	FinanzRW         = Kategorie{NumID: 4, ID: "finanzen-und-rechnungswesen", PrettyName: "Finanzen und Rechnungswesen", RDFProperty: ""}
	GeographPlanung  = Kategorie{NumID: 5, ID: "geographie-und-planung", PrettyName: "Geographie und Planung", RDFProperty: ""}
	GesellSoziales   = Kategorie{NumID: 6, ID: "gesellschaft-und-soziales", PrettyName: "Gesellschaft und Soziales", RDFProperty: ""}
	Gesundheit       = Kategorie{NumID: 7, ID: "gesundheit", PrettyName: "Gesundheit", RDFProperty: ""}
	KunstKultur      = Kategorie{NumID: 8, ID: "kunst-und-kultur", PrettyName: "Kunst und Kultur", RDFProperty: ""}
	LandFW           = Kategorie{NumID: 9, ID: "land-und-forstwirtschaft", PrettyName: "Land und Forstwirtschaft", RDFProperty: ""}
	SportFZ          = Kategorie{NumID: 10, ID: "sport-und-freizeit", PrettyName: "Sport und Freizeit", RDFProperty: ""}
	Umwelt           = Kategorie{NumID: 11, ID: "umwelt", PrettyName: "Umwelt", RDFProperty: ""}
	VerkehrTechnik   = Kategorie{NumID: 12, ID: "verkehr-und-technik", PrettyName: "Verkehr und Technik", RDFProperty: ""}
	VerwaltPol       = Kategorie{NumID: 13, ID: "verwaltung-und-politik", PrettyName: "Verwaltung und Politik", RDFProperty: ""}
	WirtTourism      = Kategorie{NumID: 14, ID: "wirtschaft-und-tourismus", PrettyName: "Wirtschaft und Tourismus", RDFProperty: ""}
)

var categories = []Kategorie{
	Arbeit,
	Bevoelkerung,
	BildungForschung,
	FinanzRW,
	GeographPlanung,
	GesellSoziales,
	Gesundheit,
	KunstKultur,
	LandFW,
	SportFZ,
	Umwelt,
	VerkehrTechnik,
	VerwaltPol,
	WirtTourism,
}

var categorymap = make(map[string]Kategorie)

type Tags string
type ResourceSpecifier string

type Cycle struct {
	NumID                       int
	DomainCode                  string
	MD_MaintenanceFrequencyCode string
	Name_DE                     string
}

var (
	CycCont     = Cycle{1, "001", "continual", "kontinuierlich"}
	CycDaily    = Cycle{2, "002", "daily", "täglich"}
	CycWeekly   = Cycle{3, "003", "weekly", "wöchentlich"}
	CycFortNly  = Cycle{4, "004", "fortnightly", "14-tägig"}
	CycMonthly  = Cycle{5, "005", "monthly", "monatlich"}
	CycQuart    = Cycle{6, "006", "quarterly", "quartalsweise"}
	CycBiAnn    = Cycle{7, "007", "biannually", "halbjährlich"}
	CycAnnually = Cycle{8, "008", "annually", "jährlich"}
	CycNeeded   = Cycle{9, "009", "asNeeded", "nach Bedarf"}
	CycIrreg    = Cycle{10, "010", "irregular", "unregelmäßig"}
	CycNP       = Cycle{11, "011", "notPlanned", "nicht geplant"}
	CycUnknown  = Cycle{12, "012", "unknown", "unbekannt"}
)

var cycles = []Cycle{
	CycCont,
	CycDaily,
	CycWeekly,
	CycFortNly,
	CycMonthly,
	CycQuart,
	CycBiAnn,
	CycAnnually,
	CycNeeded,
	CycIrreg,
	CycNP,
	CycUnknown,
}

type Url struct {
	*url.URL
	Raw string
}

type Identfier struct {
	*uuid.UUID
	Raw string
}

func (id *Identfier) String() string {
	return id.Raw
}

type Time struct {
	*time.Time
	Raw    string
	Format string
}

func (time *Time) String() string {
	return time.Raw
}

func (cyc *Cycle) String() string {
	return cyc.Name_DE
}

func cmpstrtocycle(raw string, cyc Cycle) bool {
	if raw == cyc.Name_DE || raw == cyc.DomainCode || raw == cyc.MD_MaintenanceFrequencyCode {
		return true
	}
	if len(raw) > 0 {
		if i, err := strconv.Atoi(raw); err == nil && i == cyc.NumID {
			return true
		}
	}
	return false
}

func (cyc *Cycle) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	var found bool
	var idx int
	var matchcyc Cycle

	for idx, matchcyc = range cycles {
		if found := cmpstrtocycle(raw, matchcyc); found == true {
			break
		}
	}

	if found {
		*cyc = cycles[idx]
	} else {
		cyc.NumID = -1
		cyc.Name_DE = "**** NON cycle spec **** - " + raw
		cyc.MD_MaintenanceFrequencyCode = cyc.Name_DE
	}
	return nil
}

func (ogdtime *Time) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	ogdtime.Raw = raw

	ogdtime.Format = OGDTime1
	t, err := time.Parse(ogdtime.Format, raw)
	if err != nil {
		ogdtime.Format = OGDTime2
		t, err = time.Parse(ogdtime.Format, raw)
		if err != nil {
			ogdtime.Format = OGDTime3
			t, err = time.Parse(ogdtime.Format, raw)
			if err != nil {
				ogdtime.Format = OGDTimeUnknow
			}
		}
	}
	ogdtime.Time = &t
	return nil
}

func (u *Url) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	u.Raw = raw
	url, _ := url.Parse(raw) // an actuall error is not important. If url can not be parsed, result will be nil, which is fine here
	u.URL = url
	return nil
}

func (id *Identfier) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	id.Raw = string(raw)
	if uuid := uuid.Parse(raw); uuid != nil {
		id.UUID = &uuid
	}
	return nil
}

func (kat *Kategorie) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	corecat, found := categorymap[raw]
	if !found {
		kat.NumID = -1
		kat.ID = raw
		kat.PrettyName = "**** NON core category **** - " + kat.ID
	} else {
		*kat = corecat
	}
	return nil
}

type Extras struct {
	// Core
	Metadata_Identifier Identfier   `json:"metadata_identifier"` // CKAN uses since API Version 2 a UUID V4, cf. https://github.com/okfn/ckan/blob/master/ckan/model/types.py
	Metadata_Modified   *Time       `json:"metadata_modified"`
	Categorization      []Kategorie `json:"categorization"`
	Begin_DateTime      *Time       `json:"begin_datetime"`

	// Optional
	Schema_Name           *string `json:"schema_name"`
	Schema_Language       *string `json:"schema_language"`     // always "ger"
	Schema_Characterset   *string `json:"schema_characterset"` // always "utf8", cf. https://www.ghrsst.org/files/download.php?m=documents&f=ISO%2019115%20.pdf
	MetaData_Linkage      []Url   `json:"metadata_linkage"`
	Attribute_Description *string `json:"attribute_description"`
	Maintainer_Link       *Url    `json:"maintainer_link"`
	Publisher             *string `json:"publisher"`
	Geographich_Toponym   *string `json:"geographic_toponym"`

	/*  ON/EN/ISO 19115:2003: westBL (344) & eastBL (345) & southBL (346) & northBL (347)
	 * TODO: Specifiaction says a WKT of POLYGON should be used, which would make a
	 * POLYGON ((-180.00 -90.00, 180.00 90.00)) but Example states
	 * POLYGON (-180.00 -90.00, 180.00 90.00)
	 * UNDER CLARIFICATION
	 */
	Geographic_BBox  *string `json:"geographic_bbox"`
	End_DateTime     *Time   `json:"end_datetime"`
	Update_Frequency *Cycle  `json:"update_frequency"`
	Lineage_Quality  *string `json:"lineage_quality"`
	EnTitleDesc      *string `json:"en_title_and_desc"`
}

type Resource struct {
	// Core
	URL    *Url              `json:"url"`
	Format ResourceSpecifier `json:"format"`

	// Optional
	Name         *string `json:"name"`
	Created      *Time   `json:"created"`
	LastModified *Time   `json:"last_modified"`

	/*
	 * dcat:bytes a rdf:Property, owl:DatatypeProperty;
	 * rdfs:isDefinedBy <http://www.w3.org/ns/dcat>;
	 * rdfs:label "size in bytes";
	 * rdfs:comment "describe size of resource in bytes";
	 * rdfs:domain dcat:Distribution;
	 * rdfs:range xsd:integer .
	 */
	Size             *string `json:"size"`
	License_Citation *string `json:"license_citation"`
	Language         *string `json:"language"`
	/* Here we have a problem in spec 2.1. which says "nach ISO\IEC 10646-1", which means utf-8, utf-16 and utf-32.
	 * We would certainly support more encodings, as eg.
	 * ISO 19115 / B.5.10 MD_CharacterSetCode<> or
	 * http://www.iana.org/assignments/character-sets/character-sets.xml
	 */
	Encoding *string `json:"characterset"`
}

type MetaData struct {
	// Core
	Title       string `json:"title"`
	Description string `json:"notes"`
	Schlagworte []Tags `json:"tags"`
	Maintainer  string `json:"maintainer"`
	License     string `json:"license"` // Sollte URI des Lizenzdokuments sein

	// nested structs
	Extras   `json:"extras"`
	Resource []Resource `json:"resources"`
}

func init() {
	for _, val := range categories {
		categorymap[val.ID] = val
	}
}
<commit_msg>do not reuse local variable to set a global array. local will get re-used or recycled and thus cause errors in global variable<commit_after>package ogdat

import (
	"code.google.com/p/go-uuid/uuid"
	"encoding/json"
	"net/url"
	"strconv"
	"time"
)

const OGDTimeSpecifier = "2006-01-02T15:04:05" // RFC 3339 = ISO 8601 ohne Zeitzone
const (
	OGDTime2 = time.RFC3339Nano
	OGDTime3 = time.RFC3339
	OGDTime1 = OGDTimeSpecifier
	OGDTimeUnknow
)

type Kategorie struct {
	NumID       int `json:"-"`
	ID          string
	PrettyName  string `json:"-"`
	RDFProperty string `json:"-"`
}

func (kat *Kategorie) String() string {
	return kat.PrettyName
}

var (
	Arbeit           = Kategorie{NumID: 1, ID: "arbeit", PrettyName: "Arbeit", RDFProperty: ""}
	Bevoelkerung     = Kategorie{NumID: 2, ID: "bevölkerung", PrettyName: "Bevölkerung", RDFProperty: ""}
	BildungForschung = Kategorie{NumID: 3, ID: "bildung-und-forschung", PrettyName: "Bildung und Forschung", RDFProperty: ""}
	FinanzRW         = Kategorie{NumID: 4, ID: "finanzen-und-rechnungswesen", PrettyName: "Finanzen und Rechnungswesen", RDFProperty: ""}
	GeographPlanung  = Kategorie{NumID: 5, ID: "geographie-und-planung", PrettyName: "Geographie und Planung", RDFProperty: ""}
	GesellSoziales   = Kategorie{NumID: 6, ID: "gesellschaft-und-soziales", PrettyName: "Gesellschaft und Soziales", RDFProperty: ""}
	Gesundheit       = Kategorie{NumID: 7, ID: "gesundheit", PrettyName: "Gesundheit", RDFProperty: ""}
	KunstKultur      = Kategorie{NumID: 8, ID: "kunst-und-kultur", PrettyName: "Kunst und Kultur", RDFProperty: ""}
	LandFW           = Kategorie{NumID: 9, ID: "land-und-forstwirtschaft", PrettyName: "Land und Forstwirtschaft", RDFProperty: ""}
	SportFZ          = Kategorie{NumID: 10, ID: "sport-und-freizeit", PrettyName: "Sport und Freizeit", RDFProperty: ""}
	Umwelt           = Kategorie{NumID: 11, ID: "umwelt", PrettyName: "Umwelt", RDFProperty: ""}
	VerkehrTechnik   = Kategorie{NumID: 12, ID: "verkehr-und-technik", PrettyName: "Verkehr und Technik", RDFProperty: ""}
	VerwaltPol       = Kategorie{NumID: 13, ID: "verwaltung-und-politik", PrettyName: "Verwaltung und Politik", RDFProperty: ""}
	WirtTourism      = Kategorie{NumID: 14, ID: "wirtschaft-und-tourismus", PrettyName: "Wirtschaft und Tourismus", RDFProperty: ""}
)

var categories = []Kategorie{
	Arbeit,
	Bevoelkerung,
	BildungForschung,
	FinanzRW,
	GeographPlanung,
	GesellSoziales,
	Gesundheit,
	KunstKultur,
	LandFW,
	SportFZ,
	Umwelt,
	VerkehrTechnik,
	VerwaltPol,
	WirtTourism,
}

var categorymap = make(map[string]Kategorie)

type Tags string
type ResourceSpecifier string

type Cycle struct {
	NumID                       int
	DomainCode                  string
	MD_MaintenanceFrequencyCode string
	Name_DE                     string
}

var (
	CycCont     = Cycle{1, "001", "continual", "kontinuierlich"}
	CycDaily    = Cycle{2, "002", "daily", "täglich"}
	CycWeekly   = Cycle{3, "003", "weekly", "wöchentlich"}
	CycFortNly  = Cycle{4, "004", "fortnightly", "14-tägig"}
	CycMonthly  = Cycle{5, "005", "monthly", "monatlich"}
	CycQuart    = Cycle{6, "006", "quarterly", "quartalsweise"}
	CycBiAnn    = Cycle{7, "007", "biannually", "halbjährlich"}
	CycAnnually = Cycle{8, "008", "annually", "jährlich"}
	CycNeeded   = Cycle{9, "009", "asNeeded", "nach Bedarf"}
	CycIrreg    = Cycle{10, "010", "irregular", "unregelmäßig"}
	CycNP       = Cycle{11, "011", "notPlanned", "nicht geplant"}
	CycUnknown  = Cycle{12, "012", "unknown", "unbekannt"}
)

var cycles = []Cycle{
	CycCont,
	CycDaily,
	CycWeekly,
	CycFortNly,
	CycMonthly,
	CycQuart,
	CycBiAnn,
	CycAnnually,
	CycNeeded,
	CycIrreg,
	CycNP,
	CycUnknown,
}

type Url struct {
	*url.URL
	Raw string
}

type Identfier struct {
	*uuid.UUID
	Raw string
}

func (id *Identfier) String() string {
	return id.Raw
}

type Time struct {
	*time.Time
	Raw    string
	Format string
}

func (time *Time) String() string {
	return time.Raw
}

func (cyc *Cycle) String() string {
	return cyc.Name_DE
}

func cmpstrtocycle(raw string, cyc Cycle) bool {
	if raw == cyc.Name_DE || raw == cyc.DomainCode || raw == cyc.MD_MaintenanceFrequencyCode {
		return true
	}
	if len(raw) > 0 {
		if i, err := strconv.Atoi(raw); err == nil && i == cyc.NumID {
			return true
		}
	}
	return false
}

func (cyc *Cycle) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	var found bool
	var idx int
	var matchcyc Cycle

	for idx, matchcyc = range cycles {
		if found := cmpstrtocycle(raw, matchcyc); found == true {
			break
		}
	}

	if found {
		*cyc = cycles[idx]
	} else {
		cyc.NumID = -1
		cyc.Name_DE = "**** NON cycle spec **** - " + raw
		cyc.MD_MaintenanceFrequencyCode = cyc.Name_DE
	}
	return nil
}

func (ogdtime *Time) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	ogdtime.Raw = raw

	ogdtime.Format = OGDTime1
	t, err := time.Parse(ogdtime.Format, raw)
	if err != nil {
		ogdtime.Format = OGDTime2
		t, err = time.Parse(ogdtime.Format, raw)
		if err != nil {
			ogdtime.Format = OGDTime3
			t, err = time.Parse(ogdtime.Format, raw)
			if err != nil {
				ogdtime.Format = OGDTimeUnknow
			}
		}
	}
	ogdtime.Time = &t
	return nil
}

func (u *Url) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	u.Raw = raw
	url, _ := url.Parse(raw) // an actuall error is not important. If url can not be parsed, result will be nil, which is fine here
	u.URL = url
	return nil
}

func (id *Identfier) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	id.Raw = string(raw)
	if uuid := uuid.Parse(raw); uuid != nil {
		id.UUID = &uuid
	}
	return nil
}

func (kat *Kategorie) UnmarshalJSON(data []byte) error {
	var raw string
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	corecat, found := categorymap[raw]
	if !found {
		kat.NumID = -1
		kat.ID = raw
		kat.PrettyName = "**** NON core category **** - " + kat.ID
	} else {
		*kat = corecat
	}
	return nil
}

type Extras struct {
	// Core
	Metadata_Identifier Identfier   `json:"metadata_identifier"` // CKAN uses since API Version 2 a UUID V4, cf. https://github.com/okfn/ckan/blob/master/ckan/model/types.py
	Metadata_Modified   *Time       `json:"metadata_modified"`
	Categorization      []Kategorie `json:"categorization"`
	Begin_DateTime      *Time       `json:"begin_datetime"`

	// Optional
	Schema_Name           *string `json:"schema_name"`
	Schema_Language       *string `json:"schema_language"`     // always "ger"
	Schema_Characterset   *string `json:"schema_characterset"` // always "utf8", cf. https://www.ghrsst.org/files/download.php?m=documents&f=ISO%2019115%20.pdf
	MetaData_Linkage      []Url   `json:"metadata_linkage"`
	Attribute_Description *string `json:"attribute_description"`
	Maintainer_Link       *Url    `json:"maintainer_link"`
	Publisher             *string `json:"publisher"`
	Geographich_Toponym   *string `json:"geographic_toponym"`

	/*  ON/EN/ISO 19115:2003: westBL (344) & eastBL (345) & southBL (346) & northBL (347)
	 * TODO: Specifiaction says a WKT of POLYGON should be used, which would make a
	 * POLYGON ((-180.00 -90.00, 180.00 90.00)) but Example states
	 * POLYGON (-180.00 -90.00, 180.00 90.00)
	 * UNDER CLARIFICATION
	 */
	Geographic_BBox  *string `json:"geographic_bbox"`
	End_DateTime     *Time   `json:"end_datetime"`
	Update_Frequency *Cycle  `json:"update_frequency"`
	Lineage_Quality  *string `json:"lineage_quality"`
	EnTitleDesc      *string `json:"en_title_and_desc"`
}

type Resource struct {
	// Core
	URL    *Url              `json:"url"`
	Format ResourceSpecifier `json:"format"`

	// Optional
	Name         *string `json:"name"`
	Created      *Time   `json:"created"`
	LastModified *Time   `json:"last_modified"`

	/*
	 * dcat:bytes a rdf:Property, owl:DatatypeProperty;
	 * rdfs:isDefinedBy <http://www.w3.org/ns/dcat>;
	 * rdfs:label "size in bytes";
	 * rdfs:comment "describe size of resource in bytes";
	 * rdfs:domain dcat:Distribution;
	 * rdfs:range xsd:integer .
	 */
	Size             *string `json:"size"`
	License_Citation *string `json:"license_citation"`
	Language         *string `json:"language"`
	/* Here we have a problem in spec 2.1. which says "nach ISO\IEC 10646-1", which means utf-8, utf-16 and utf-32.
	 * We would certainly support more encodings, as eg.
	 * ISO 19115 / B.5.10 MD_CharacterSetCode<> or
	 * http://www.iana.org/assignments/character-sets/character-sets.xml
	 */
	Encoding *string `json:"characterset"`
}

type MetaData struct {
	// Core
	Title       string `json:"title"`
	Description string `json:"notes"`
	Schlagworte []Tags `json:"tags"`
	Maintainer  string `json:"maintainer"`
	License     string `json:"license"` // Sollte URI des Lizenzdokuments sein

	// nested structs
	Extras   `json:"extras"`
	Resource []Resource `json:"resources"`
}

func init() {
	for idx, val := range categories {
		categorymap[val.ID] = categories[idx]
	}
}
<|endoftext|>


<commit_before>// Package influxdata implements the OAuth2 protocol for authenticating users through InfluxCloud.
// It is based off of the github implementation.
package influxcloud

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	// The hard coded domain is difficult here because influx cloud has an acceptance
	// domain that is different and we will need that for enterprise development.
	defaultDomain string = "cloud.influxdata.com"
	userAPIPath   string = "/api/v1/user"
	domainEnvKey  string = "INFLUXCLOUD_OAUTH_DOMAIN"
	authPath      string = "/oauth/authorize"
	tokenPath     string = "/oauth/token"
)

// New creates a new influx provider, and sets up important connection details.
// You should always call `influxcloud.New` to get a new Provider. Never try to create
// one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	domain := os.Getenv(domainEnvKey)
	if domain == "" {
		domain = defaultDomain
	}
	tokenURL := fmt.Sprintf("https://%s%s", domain, tokenPath)
	authURL := fmt.Sprintf("https://%s%s", domain, authPath)
	userAPIEndpoint := fmt.Sprintf("https://%s%s", domain, userAPIPath)

	p := &Provider{
		ClientKey:       clientKey,
		Secret:          secret,
		CallbackURL:     callbackURL,
		UserAPIEndpoint: userAPIEndpoint,
		Config: &oauth2.Config{
			ClientID:     clientKey,
			ClientSecret: secret,
			RedirectURL:  callbackURL,
			Endpoint: oauth2.Endpoint{
				AuthURL:  authURL,
				TokenURL: tokenURL,
			},
			Scopes: scopes,
		},
		providerName: "influxcloud",
	}
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Influx.
type Provider struct {
	ClientKey       string
	Secret          string
	CallbackURL     string
	UserAPIEndpoint string
	HTTPClient      *http.Client
	Config          *oauth2.Config
	providerName    string
}

// Name is the name used to retrieve this provider later.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers of 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is a no-op for the influxcloud package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Influx for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.Config.AuthCodeURL(state)
	session := &Session{
		AuthURL: url,
	}
	return session, nil
}

// FetchUser will go to Influx and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken: sess.AccessToken,
		Provider:    p.Name(),
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	response, err := p.Client().Get(p.UserAPIEndpoint + "?access_token=" + url.QueryEscape(sess.AccessToken))

	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, response.StatusCode)
	}

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}

	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func userFromReader(reader io.Reader, user *goth.User) error {
	u := struct {
		ID       int    `json:"id"`
		Email    string `json:"email"`
		Bio      string `json:"bio"`
		Name     string `json:"name"`
		Login    string `json:"login"`
		Picture  string `json:"avatar_url"`
		Location string `json:"location"`
	}{}

	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return err
	}

	user.Name = u.Name
	user.NickName = u.Login
	user.Email = u.Email
	user.Description = u.Bio
	user.AvatarURL = u.Picture
	user.UserID = strconv.Itoa(u.ID)
	user.Location = u.Location

	return err
}

//RefreshToken refresh token is not provided by influxcloud
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, errors.New("Refresh token is not provided by influxcloud")
}

//RefreshTokenAvailable refresh token is not provided by influxcloud
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}
<commit_msg>influxcloud add new customised url function<commit_after>// Package influxdata implements the OAuth2 protocol for authenticating users through InfluxCloud.
// It is based off of the github implementation.
package influxcloud

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	// The hard coded domain is difficult here because influx cloud has an acceptance
	// domain that is different and we will need that for enterprise development.
	defaultDomain string = "cloud.influxdata.com"
	userAPIPath   string = "/api/v1/user"
	domainEnvKey  string = "INFLUXCLOUD_OAUTH_DOMAIN"
	authPath      string = "/oauth/authorize"
	tokenPath     string = "/oauth/token"
)

// New creates a new influx provider, and sets up important connection details.
// You should always call `influxcloud.New` to get a new Provider. Never try to create
// one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	domain := os.Getenv(domainEnvKey)
	if domain == "" {
		domain = defaultDomain
	}
	tokenURL := fmt.Sprintf("https://%s%s", domain, tokenPath)
	authURL := fmt.Sprintf("https://%s%s", domain, authPath)
	userAPIEndpoint := fmt.Sprintf("https://%s%s", domain, userAPIPath)

	return NewCustomisedURL(clientKey, secret, callbackURL, authURL, tokenURL, userAPIEndpoint, scopes...)
}

// NewCustomisedURL is similar to New(...) but can be used to set custom URLs to connect to
func NewCustomisedURL(clientKey, secret, callbackURL, authURL, tokenURL, userAPIEndpoint string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:       clientKey,
		Secret:          secret,
		CallbackURL:     callbackURL,
		UserAPIEndpoint: userAPIEndpoint,
		Config: &oauth2.Config{
			ClientID:     clientKey,
			ClientSecret: secret,
			RedirectURL:  callbackURL,
			Endpoint: oauth2.Endpoint{
				AuthURL:  authURL,
				TokenURL: tokenURL,
			},
			Scopes: scopes,
		},
		providerName: "influxcloud",
	}
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Influx.
type Provider struct {
	ClientKey       string
	Secret          string
	CallbackURL     string
	UserAPIEndpoint string
	HTTPClient      *http.Client
	Config          *oauth2.Config
	providerName    string
}

// Name is the name used to retrieve this provider later.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers of 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is a no-op for the influxcloud package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Influx for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.Config.AuthCodeURL(state)
	session := &Session{
		AuthURL: url,
	}
	return session, nil
}

// FetchUser will go to Influx and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken: sess.AccessToken,
		Provider:    p.Name(),
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	response, err := p.Client().Get(p.UserAPIEndpoint + "?access_token=" + url.QueryEscape(sess.AccessToken))

	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, response.StatusCode)
	}

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}

	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func userFromReader(reader io.Reader, user *goth.User) error {
	u := struct {
		ID       int    `json:"id"`
		Email    string `json:"email"`
		Bio      string `json:"bio"`
		Name     string `json:"name"`
		Login    string `json:"login"`
		Picture  string `json:"avatar_url"`
		Location string `json:"location"`
	}{}

	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return err
	}

	user.Name = u.Name
	user.NickName = u.Login
	user.Email = u.Email
	user.Description = u.Bio
	user.AvatarURL = u.Picture
	user.UserID = strconv.Itoa(u.ID)
	user.Location = u.Location

	return err
}

//RefreshToken refresh token is not provided by influxcloud
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, errors.New("Refresh token is not provided by influxcloud")
}

//RefreshTokenAvailable refresh token is not provided by influxcloud
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}
<|endoftext|>


<commit_before>package ogdat

import (
	"encoding/csv"
	"io"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/
var specification = make(map[string]*OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        string
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

func (desc *Beschreibung) IsRequired() bool {
	return desc.occurrence == OccRequired
}

type OGDSet struct {
	Label        []string
	Beschreibung []*Beschreibung
}

func (set *OGDSet) GetBeschreibungForID(id int) (*Beschreibung, string) {
	if set != nil {
		for idx, elm := range set.Beschreibung {
			if elm.ID == id {
				return set.Beschreibung[idx], set.Label[idx]
			}
		}
	}
	return nil, ""
}

func RegisterFromCSVFile(version, specfile string) *OGDSet {
	set, _ := Loadogdatspec(version, specfile)
	specification[version] = set
	return set
}

func Register(version string, set *OGDSet) *OGDSet {
	specification[version] = set
	return set
}

func GetOGDSetForVersion(version string) *OGDSet {
	return specification[version]
}

func GetIDFromMetaDataStructField(val reflect.StructField) int {
	ids := val.Tag.Get("ogdat")
	if idx := strings.Index(ids, "ID"); idx > -1 {
		ids = ids[idx+1:]
		if idx = strings.IndexRune(ids, ','); idx > -1 {
			ids = ids[:idx]
		}
		if i, err := strconv.Atoi(ids); err == nil {
			return i
		}
	}
	return -1
}

func Loadogdatspec(version, filename string) (*OGDSet, error) {
	reader, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer reader.Close()

	csvreader := csv.NewReader(reader)
	csvreader.Comma = '|'
	csvreader.LazyQuotes = true

	// Read the first line and use it as the labels for the items to load
	record, err := csvreader.Read()
	if err != nil {
		return nil, err
	}

	set := &OGDSet{}
	set.Label = record

	spec := make([]*Beschreibung, 0)
	for record, err = csvreader.Read(); err != io.EOF; record, err = csvreader.Read() {
		id, _ := strconv.Atoi(record[0])
		var occ Occurrence
		switch record[12][0] {
		case 'R':
			occ = OccRequired
		case 'O':
			occ = OccOptional
		}
		descrecord := NewBeschreibung(id, occ, version)

		descrecord.Bezeichner = record[1]
		descrecord.OGD_Kurzname = record[2]
		descrecord.CKAN_Feld = record[3]
		descrecord.Anzahl = record[4]
		descrecord.Definition_DE = record[5]
		descrecord.Erlauterung = record[6]
		descrecord.Beispiel = record[7]
		descrecord.ONA2270 = record[8]
		descrecord.ISO19115 = record[9]
		descrecord.RDFProperty = record[10]
		descrecord.Definition_EN = record[11]

		spec = append(spec, descrecord)
	}
	set.Beschreibung = spec
	log.Printf("Info: Read %d %s specifiaction records", len(spec), version)

	return set, nil
}
<commit_msg>strings.Index returns the index to the beginning of an occurrence of sub-string, have to add the length<commit_after>package ogdat

import (
	"encoding/csv"
	"io"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/
var specification = make(map[string]*OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        string
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

func (desc *Beschreibung) IsRequired() bool {
	return desc.occurrence == OccRequired
}

type OGDSet struct {
	Label        []string
	Beschreibung []*Beschreibung
}

func (set *OGDSet) GetBeschreibungForID(id int) (*Beschreibung, string) {
	if set != nil {
		for idx, elm := range set.Beschreibung {
			if elm.ID == id {
				return set.Beschreibung[idx], set.Label[idx]
			}
		}
	}
	return nil, ""
}

func RegisterFromCSVFile(version, specfile string) *OGDSet {
	set, _ := Loadogdatspec(version, specfile)
	specification[version] = set
	return set
}

func Register(version string, set *OGDSet) *OGDSet {
	specification[version] = set
	return set
}

func GetOGDSetForVersion(version string) *OGDSet {
	return specification[version]
}

func GetIDFromMetaDataStructField(val reflect.StructField) int {
	ids := val.Tag.Get("ogdat")
	if idx := strings.Index(ids, "ID"); idx > -1 {
		ids = ids[idx+len("ID")+1:]
		if idx = strings.IndexRune(ids, ','); idx > -1 {
			ids = ids[:idx]
		}
		if i, err := strconv.Atoi(ids); err == nil {
			return i
		}
	}
	return -1
}

func Loadogdatspec(version, filename string) (*OGDSet, error) {
	reader, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer reader.Close()

	csvreader := csv.NewReader(reader)
	csvreader.Comma = '|'
	csvreader.LazyQuotes = true

	// Read the first line and use it as the labels for the items to load
	record, err := csvreader.Read()
	if err != nil {
		return nil, err
	}

	set := &OGDSet{}
	set.Label = record

	spec := make([]*Beschreibung, 0)
	for record, err = csvreader.Read(); err != io.EOF; record, err = csvreader.Read() {
		id, _ := strconv.Atoi(record[0])
		var occ Occurrence
		switch record[12][0] {
		case 'R':
			occ = OccRequired
		case 'O':
			occ = OccOptional
		}
		descrecord := NewBeschreibung(id, occ, version)

		descrecord.Bezeichner = record[1]
		descrecord.OGD_Kurzname = record[2]
		descrecord.CKAN_Feld = record[3]
		descrecord.Anzahl = record[4]
		descrecord.Definition_DE = record[5]
		descrecord.Erlauterung = record[6]
		descrecord.Beispiel = record[7]
		descrecord.ONA2270 = record[8]
		descrecord.ISO19115 = record[9]
		descrecord.RDFProperty = record[10]
		descrecord.Definition_EN = record[11]

		spec = append(spec, descrecord)
	}
	set.Beschreibung = spec
	log.Printf("Info: Read %d %s specifiaction records", len(spec), version)

	return set, nil
}
<|endoftext|>


<commit_before>package file

import (
	"bytes"
	"context"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/hashicorp/packer/packer"
)

func testConfig() map[string]interface{} {
	return map[string]interface{}{
		"destination": "something",
	}
}

func TestProvisioner_Impl(t *testing.T) {
	var raw interface{}
	raw = &Provisioner{}
	if _, ok := raw.(packer.Provisioner); !ok {
		t.Fatalf("must be a provisioner")
	}
}

func TestProvisionerPrepare_InvalidKey(t *testing.T) {
	var p Provisioner
	config := testConfig()

	// Add a random key
	config["i_should_not_be_valid"] = true
	err := p.Prepare(config)
	if err == nil {
		t.Fatal("should have error")
	}
}

func TestProvisionerPrepare_InvalidSource(t *testing.T) {
	var p Provisioner
	config := testConfig()
	config["source"] = "/this/should/not/exist"

	err := p.Prepare(config)
	if err == nil {
		t.Fatalf("should require existing file")
	}

	config["generated"] = false
	err = p.Prepare(config)
	if err == nil {
		t.Fatalf("should required existing file")
	}
}

func TestProvisionerPrepare_ValidSource(t *testing.T) {
	var p Provisioner

	tf, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	config := testConfig()
	config["source"] = tf.Name()
	err = p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow valid file: %s", err)
	}

	config["generated"] = false
	err = p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow valid file: %s", err)
	}
}

func TestProvisionerPrepare_GeneratedSource(t *testing.T) {
	var p Provisioner

	config := testConfig()
	config["source"] = "/this/should/not/exist"
	config["generated"] = true
	err := p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow non-existing file: %s", err)
	}
}

func TestProvisionerPrepare_EmptyDestination(t *testing.T) {
	var p Provisioner

	config := testConfig()
	delete(config, "destination")
	err := p.Prepare(config)
	if err == nil {
		t.Fatalf("should require destination path")
	}
}

func TestProvisionerProvision_SendsFile(t *testing.T) {
	var p Provisioner
	tf, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	if _, err = tf.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	config := map[string]interface{}{
		"source":      tf.Name(),
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), tf.Name()) {
		t.Fatalf("should print source filename")
	}

	if !strings.Contains(b.String(), "something") {
		t.Fatalf("should print destination filename")
	}

	if comm.UploadPath != "something" {
		t.Fatalf("should upload to configured destination")
	}

	if comm.UploadData != "hello" {
		t.Fatalf("should upload with source file's data")
	}
}

func TestProvisionerProvision_SendsFileMultipleFiles(t *testing.T) {
	var p Provisioner
	tf1, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf1.Name())

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	tf2, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf2.Name())

	if _, err = tf2.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	config := map[string]interface{}{
		"sources":      []string{tf1.Name(), tf2.Name()},
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), tf1.Name()) {
		t.Fatalf("should print first source filename")
	}

	if !strings.Contains(b.String(), tf2.Name()) {
		t.Fatalf("should print second source filename")
	}
}

func TestProvisionerProvision_SendsFileMultipleDirs(t *testing.T) {
	var p Provisioner

	// Prepare the first directory
	td1, err := ioutil.TempDir("", "packerdir")
	if err != nil {
		t.Fatalf("error temp folder 1: %s", err)
	}
	defer os.Remove(td1)

	tf1, err := ioutil.TempFile(td1, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	// Prepare the second directory
	td2, err := ioutil.TempDir("", "packerdir")
	if err != nil {
		t.Fatalf("error temp folder 1: %s", err)
	}
	defer os.Remove(td2)

	tf2, err := ioutil.TempFile(td2, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}

	if _, err = tf2.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	// Run Provision

	config := map[string]interface{}{
		"sources":      []string{td1, td2},
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), td1) {
		t.Fatalf("should print first directory")
	}

	if !strings.Contains(b.String(), td2) {
		t.Fatalf("should print second directory")
	}
}

func TestProvisionDownloadMkdirAll(t *testing.T) {
	tests := []struct {
		path string
	}{
		{"dir"},
		{"dir/"},
		{"dir/subdir"},
		{"dir/subdir/"},
		{"path/to/dir"},
		{"path/to/dir/"},
	}
	tmpDir, err := ioutil.TempDir("", "packer-file")
	if err != nil {
		t.Fatalf("error tempdir: %s", err)
	}
	defer os.RemoveAll(tmpDir)
	tf, err := ioutil.TempFile(tmpDir, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	config := map[string]interface{}{
		"source": tf.Name(),
	}
	var p Provisioner
	for _, test := range tests {
		path := filepath.Join(tmpDir, test.path)
		config["destination"] = filepath.Join(path, "something")
		if err := p.Prepare(config); err != nil {
			t.Fatalf("err: %s", err)
		}
		b := bytes.NewBuffer(nil)
		ui := &packer.BasicUi{
			Writer: b,
		}
		comm := &packer.MockCommunicator{}
		err = p.ProvisionDownload(ui, comm)
		if err != nil {
			t.Fatalf("should successfully provision: %s", err)
		}

		if !strings.Contains(b.String(), tf.Name()) {
			t.Fatalf("should print source filename")
		}

		if !strings.Contains(b.String(), "something") {
			t.Fatalf("should print destination filename")
		}

		if _, err := os.Stat(path); err != nil {
			t.Fatalf("stat of download dir should not error: %s", err)
		}

		if _, err := os.Stat(config["destination"].(string)); err != nil {
			t.Fatalf("stat of destination file should not error: %s", err)
		}
	}
}
<commit_msg>fix formatting<commit_after>package file

import (
	"bytes"
	"context"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/hashicorp/packer/packer"
)

func testConfig() map[string]interface{} {
	return map[string]interface{}{
		"destination": "something",
	}
}

func TestProvisioner_Impl(t *testing.T) {
	var raw interface{}
	raw = &Provisioner{}
	if _, ok := raw.(packer.Provisioner); !ok {
		t.Fatalf("must be a provisioner")
	}
}

func TestProvisionerPrepare_InvalidKey(t *testing.T) {
	var p Provisioner
	config := testConfig()

	// Add a random key
	config["i_should_not_be_valid"] = true
	err := p.Prepare(config)
	if err == nil {
		t.Fatal("should have error")
	}
}

func TestProvisionerPrepare_InvalidSource(t *testing.T) {
	var p Provisioner
	config := testConfig()
	config["source"] = "/this/should/not/exist"

	err := p.Prepare(config)
	if err == nil {
		t.Fatalf("should require existing file")
	}

	config["generated"] = false
	err = p.Prepare(config)
	if err == nil {
		t.Fatalf("should required existing file")
	}
}

func TestProvisionerPrepare_ValidSource(t *testing.T) {
	var p Provisioner

	tf, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	config := testConfig()
	config["source"] = tf.Name()
	err = p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow valid file: %s", err)
	}

	config["generated"] = false
	err = p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow valid file: %s", err)
	}
}

func TestProvisionerPrepare_GeneratedSource(t *testing.T) {
	var p Provisioner

	config := testConfig()
	config["source"] = "/this/should/not/exist"
	config["generated"] = true
	err := p.Prepare(config)
	if err != nil {
		t.Fatalf("should allow non-existing file: %s", err)
	}
}

func TestProvisionerPrepare_EmptyDestination(t *testing.T) {
	var p Provisioner

	config := testConfig()
	delete(config, "destination")
	err := p.Prepare(config)
	if err == nil {
		t.Fatalf("should require destination path")
	}
}

func TestProvisionerProvision_SendsFile(t *testing.T) {
	var p Provisioner
	tf, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	if _, err = tf.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	config := map[string]interface{}{
		"source":      tf.Name(),
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), tf.Name()) {
		t.Fatalf("should print source filename")
	}

	if !strings.Contains(b.String(), "something") {
		t.Fatalf("should print destination filename")
	}

	if comm.UploadPath != "something" {
		t.Fatalf("should upload to configured destination")
	}

	if comm.UploadData != "hello" {
		t.Fatalf("should upload with source file's data")
	}
}

func TestProvisionerProvision_SendsFileMultipleFiles(t *testing.T) {
	var p Provisioner
	tf1, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf1.Name())

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	tf2, err := ioutil.TempFile("", "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf2.Name())

	if _, err = tf2.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	config := map[string]interface{}{
		"sources":     []string{tf1.Name(), tf2.Name()},
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), tf1.Name()) {
		t.Fatalf("should print first source filename")
	}

	if !strings.Contains(b.String(), tf2.Name()) {
		t.Fatalf("should print second source filename")
	}
}

func TestProvisionerProvision_SendsFileMultipleDirs(t *testing.T) {
	var p Provisioner

	// Prepare the first directory
	td1, err := ioutil.TempDir("", "packerdir")
	if err != nil {
		t.Fatalf("error temp folder 1: %s", err)
	}
	defer os.Remove(td1)

	tf1, err := ioutil.TempFile(td1, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	// Prepare the second directory
	td2, err := ioutil.TempDir("", "packerdir")
	if err != nil {
		t.Fatalf("error temp folder 1: %s", err)
	}
	defer os.Remove(td2)

	tf2, err := ioutil.TempFile(td2, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}

	if _, err = tf2.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	if _, err = tf1.Write([]byte("hello")); err != nil {
		t.Fatalf("error writing tempfile: %s", err)
	}

	// Run Provision

	config := map[string]interface{}{
		"sources":     []string{td1, td2},
		"destination": "something",
	}

	if err := p.Prepare(config); err != nil {
		t.Fatalf("err: %s", err)
	}

	b := bytes.NewBuffer(nil)
	ui := &packer.BasicUi{
		Writer: b,
	}
	comm := &packer.MockCommunicator{}
	err = p.Provision(context.Background(), ui, comm, make(map[string]interface{}))
	if err != nil {
		t.Fatalf("should successfully provision: %s", err)
	}

	if !strings.Contains(b.String(), td1) {
		t.Fatalf("should print first directory")
	}

	if !strings.Contains(b.String(), td2) {
		t.Fatalf("should print second directory")
	}
}

func TestProvisionDownloadMkdirAll(t *testing.T) {
	tests := []struct {
		path string
	}{
		{"dir"},
		{"dir/"},
		{"dir/subdir"},
		{"dir/subdir/"},
		{"path/to/dir"},
		{"path/to/dir/"},
	}
	tmpDir, err := ioutil.TempDir("", "packer-file")
	if err != nil {
		t.Fatalf("error tempdir: %s", err)
	}
	defer os.RemoveAll(tmpDir)
	tf, err := ioutil.TempFile(tmpDir, "packer")
	if err != nil {
		t.Fatalf("error tempfile: %s", err)
	}
	defer os.Remove(tf.Name())

	config := map[string]interface{}{
		"source": tf.Name(),
	}
	var p Provisioner
	for _, test := range tests {
		path := filepath.Join(tmpDir, test.path)
		config["destination"] = filepath.Join(path, "something")
		if err := p.Prepare(config); err != nil {
			t.Fatalf("err: %s", err)
		}
		b := bytes.NewBuffer(nil)
		ui := &packer.BasicUi{
			Writer: b,
		}
		comm := &packer.MockCommunicator{}
		err = p.ProvisionDownload(ui, comm)
		if err != nil {
			t.Fatalf("should successfully provision: %s", err)
		}

		if !strings.Contains(b.String(), tf.Name()) {
			t.Fatalf("should print source filename")
		}

		if !strings.Contains(b.String(), "something") {
			t.Fatalf("should print destination filename")
		}

		if _, err := os.Stat(path); err != nil {
			t.Fatalf("stat of download dir should not error: %s", err)
		}

		if _, err := os.Stat(config["destination"].(string)); err != nil {
			t.Fatalf("stat of destination file should not error: %s", err)
		}
	}
}
<|endoftext|>


<commit_before>package coinbasepro

import (
	"fmt"
)

type Order struct {
	Type      string `json:"type"`
	Size      string `json:"size,omitempty"`
	Side      string `json:"side"`
	ProductID string `json:"product_id"`
	ClientOID string `json:"client_oid,omitempty"`
	Stp       string `json:"stp,omitempty"`
	Stop      string `json:"stop,omitempty"`
	StopPrice string `json:"stop_price,omitempty"`
	// Limit Order
	Price       string `json:"price,omitempty"`
	TimeInForce string `json:"time_in_force,omitempty"`
	PostOnly    bool   `json:"post_only,omitempty"`
	CancelAfter string `json:"cancel_after,omitempty"`
	// Market Order
	Funds string `json:"funds,omitempty"`
	// Response Fields
	ID            string `json:"id"`
	Status        string `json:"status,omitempty"`
	Settled       bool   `json:"settled,omitempty"`
	DoneReason    string `json:"done_reason,omitempty"`
	CreatedAt     Time   `json:"created_at,string,omitempty"`
	FillFees      string `json:"fill_fees,omitempty"`
	FilledSize    string `json:"filled_size,omitempty"`
	ExecutedValue string `json:"executed_value,omitempty"`
}

type CancelAllOrdersParams struct {
	ProductID string
}

type ListOrdersParams struct {
	Status     string
	ProductID  string
	Pagination PaginationParams
}

func (c *Client) CreateOrder(newOrder *Order) (Order, error) {
	var savedOrder Order

	if len(newOrder.Type) == 0 {
		newOrder.Type = "limit"
	}

	url := fmt.Sprintf("/orders")
	_, err := c.Request("POST", url, newOrder, &savedOrder)
	return savedOrder, err
}

func (c *Client) CancelOrder(id string) error {
	url := fmt.Sprintf("/orders/%s", id)
	_, err := c.Request("DELETE", url, nil, nil)
	return err
}

func (c *Client) CancelAllOrders(p ...CancelAllOrdersParams) ([]string, error) {
	var orderIDs []string
	url := "/orders"

	if len(p) > 0 && p[0].ProductID != "" {
		url = fmt.Sprintf("%s?product_id=%s", url, p[0].ProductID)
	}

	_, err := c.Request("DELETE", url, nil, &orderIDs)
	return orderIDs, err
}

func (c *Client) GetOrder(id string) (Order, error) {
	var savedOrder Order

	url := fmt.Sprintf("/orders/%s", id)
	_, err := c.Request("GET", url, nil, &savedOrder)
	return savedOrder, err
}

func (c *Client) ListOrders(p ...ListOrdersParams) *Cursor {
	paginationParams := PaginationParams{}
	if len(p) > 0 {
		paginationParams = p[0].Pagination
		if p[0].Status != "" {
			paginationParams.AddExtraParam("status", p[0].Status)
		}
		if p[0].ProductID != "" {
			paginationParams.AddExtraParam("product_id", p[0].ProductID)
		}
	}

	return NewCursor(c, "GET", fmt.Sprintf("/orders"),
		&paginationParams)
}
<commit_msg>Add fields to Order (#95)<commit_after>package coinbasepro

import (
	"fmt"
)

type Order struct {
	Type      string `json:"type"`
	Size      string `json:"size,omitempty"`
	Side      string `json:"side"`
	ProductID string `json:"product_id"`
	ClientOID string `json:"client_oid,omitempty"`
	Stp       string `json:"stp,omitempty"`
	Stop      string `json:"stop,omitempty"`
	StopPrice string `json:"stop_price,omitempty"`
	// Limit Order
	Price       string `json:"price,omitempty"`
	TimeInForce string `json:"time_in_force,omitempty"`
	PostOnly    bool   `json:"post_only,omitempty"`
	CancelAfter string `json:"cancel_after,omitempty"`
	// Market Order
	Funds          string `json:"funds,omitempty"`
	SpecifiedFunds string `json:"specified_funds,omitempty"`
	// Response Fields
	ID            string `json:"id"`
	Status        string `json:"status,omitempty"`
	Settled       bool   `json:"settled,omitempty"`
	DoneReason    string `json:"done_reason,omitempty"`
	DoneAt        Time   `json:"done_at,string,omitempty"`
	CreatedAt     Time   `json:"created_at,string,omitempty"`
	FillFees      string `json:"fill_fees,omitempty"`
	FilledSize    string `json:"filled_size,omitempty"`
	ExecutedValue string `json:"executed_value,omitempty"`
}

type CancelAllOrdersParams struct {
	ProductID string
}

type ListOrdersParams struct {
	Status     string
	ProductID  string
	Pagination PaginationParams
}

func (c *Client) CreateOrder(newOrder *Order) (Order, error) {
	var savedOrder Order

	if len(newOrder.Type) == 0 {
		newOrder.Type = "limit"
	}

	url := fmt.Sprintf("/orders")
	_, err := c.Request("POST", url, newOrder, &savedOrder)
	return savedOrder, err
}

func (c *Client) CancelOrder(id string) error {
	url := fmt.Sprintf("/orders/%s", id)
	_, err := c.Request("DELETE", url, nil, nil)
	return err
}

func (c *Client) CancelAllOrders(p ...CancelAllOrdersParams) ([]string, error) {
	var orderIDs []string
	url := "/orders"

	if len(p) > 0 && p[0].ProductID != "" {
		url = fmt.Sprintf("%s?product_id=%s", url, p[0].ProductID)
	}

	_, err := c.Request("DELETE", url, nil, &orderIDs)
	return orderIDs, err
}

func (c *Client) GetOrder(id string) (Order, error) {
	var savedOrder Order

	url := fmt.Sprintf("/orders/%s", id)
	_, err := c.Request("GET", url, nil, &savedOrder)
	return savedOrder, err
}

func (c *Client) ListOrders(p ...ListOrdersParams) *Cursor {
	paginationParams := PaginationParams{}
	if len(p) > 0 {
		paginationParams = p[0].Pagination
		if p[0].Status != "" {
			paginationParams.AddExtraParam("status", p[0].Status)
		}
		if p[0].ProductID != "" {
			paginationParams.AddExtraParam("product_id", p[0].ProductID)
		}
	}

	return NewCursor(c, "GET", fmt.Sprintf("/orders"),
		&paginationParams)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/md5"
	"encoding/json"
	"fmt"
	"github.com/golang/groupcache"
	"github.com/gorilla/mux"
	"io"
	"math/rand"
	"net/http"
	"os"
	"time"
	"vip/fetch"
)

type UploadResponse struct {
	Url string `json:"url"`
}

type verifyAuth func(http.ResponseWriter, *http.Request)

func (h verifyAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Enable cross-origin requests
	if origin := r.Header.Get("Origin"); origin != "" {
		w.Header().Set("Access-Control-Allow-Origin", origin)
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		w.Header().Set("Access-Control-Allow-Headers",
			"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	}

	if r.Method == "OPTIONS" {
		return
	}

	auth := r.Header.Get("X-Vip-Token")
	if auth != authToken {
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	h(w, r)
}

func fileKey(bucket string) string {
	seed := rand.New(rand.NewSource(time.Now().UnixNano()))
	key := fmt.Sprintf("%d-%s-%d", seed.Int63(), bucket, time.Now().UnixNano())

	hash := md5.New()
	io.WriteString(hash, key)
	return fmt.Sprintf("%x", hash.Sum(nil))
}

func handleImageRequest(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}

	w.Header().Set("Cache-Control", "public, max-age=31536000")

	// Client is checking for a cached URI, assume it is valid
	// and return a 304
	if r.Header.Get("If-Modified-Since") != "" {
		w.WriteHeader(http.StatusNotModified)
		return
	}

	gc := fetch.RequestContext(r)

	var data []byte
	err := cache.Get(gc, gc.CacheKey(), groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	w.Header().Set("Content-Type", http.DetectContentType(data))
	http.ServeContent(w, r, gc.ImageId, time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), bytes.NewReader(data))
}

func handleUpload(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}

	vars := mux.Vars(r)
	bucket := vars["bucket_id"]

	// Set a hard 5mb limit on files
	if r.ContentLength > 5<<20 {
		w.WriteHeader(http.StatusRequestEntityTooLarge)
		return
	}

	key := fileKey(bucket)
	err := storage.PutReader(bucket, key, r.Body,
		r.ContentLength, r.Header.Get("Content-Type"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	uri := r.URL

	if r.URL.Host == "" {
		uri.Host = os.Getenv("URI_HOSTNAME")
		uri.Scheme = "http"
	}

	uri.Path = fmt.Sprintf("%s/%s", bucket, key)

	w.Header().Set("Content-Type", "application/json")

	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(UploadResponse{
		Url: uri.String(),
	})
}

func handlePing(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "pong")
}
<commit_msg>Add docker publish<commit_after>package main

import (
	"bytes"
	"crypto/md5"
	"encoding/json"
	"fmt"
	"github.com/golang/groupcache"
	"github.com/gorilla/mux"
	"io"
	"math/rand"
	"net/http"
	"os"
	"time"
	"vip/fetch"
)

type UploadResponse struct {
	Url string `json:"url"`
}

type verifyAuth func(http.ResponseWriter, *http.Request)

func (h verifyAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Enable cross-origin requests
	// TODO: Whitelist the domain via an environment variable
	if origin := r.Header.Get("Origin"); origin != "" {
		w.Header().Set("Access-Control-Allow-Origin", origin)
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		w.Header().Set("Access-Control-Allow-Headers",
			"Accept, Content-Type, Content-Length, Accept-Encoding, X-Vip-Token, Authorization")
	}

	if r.Method == "OPTIONS" {
		return
	}

	auth := r.Header.Get("X-Vip-Token")
	if auth != authToken {
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	h(w, r)
}

func fileKey(bucket string) string {
	seed := rand.New(rand.NewSource(time.Now().UnixNano()))
	key := fmt.Sprintf("%d-%s-%d", seed.Int63(), bucket, time.Now().UnixNano())

	hash := md5.New()
	io.WriteString(hash, key)
	return fmt.Sprintf("%x", hash.Sum(nil))
}

func handleImageRequest(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}

	w.Header().Set("Cache-Control", "public, max-age=31536000")

	// Client is checking for a cached URI, assume it is valid
	// and return a 304
	if r.Header.Get("If-Modified-Since") != "" {
		w.WriteHeader(http.StatusNotModified)
		return
	}

	gc := fetch.RequestContext(r)

	var data []byte
	err := cache.Get(gc, gc.CacheKey(), groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	w.Header().Set("Content-Type", http.DetectContentType(data))
	http.ServeContent(w, r, gc.ImageId, time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), bytes.NewReader(data))
}

func handleUpload(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}

	vars := mux.Vars(r)
	bucket := vars["bucket_id"]

	// Set a hard 5mb limit on files
	if r.ContentLength > 5<<20 {
		w.WriteHeader(http.StatusRequestEntityTooLarge)
		return
	}

	key := fileKey(bucket)
	err := storage.PutReader(bucket, key, r.Body,
		r.ContentLength, r.Header.Get("Content-Type"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	uri := r.URL

	if r.URL.Host == "" {
		uri.Host = os.Getenv("URI_HOSTNAME")
		uri.Scheme = "http"
	}

	uri.Path = fmt.Sprintf("%s/%s", bucket, key)

	w.Header().Set("Content-Type", "application/json")

	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(UploadResponse{
		Url: uri.String(),
	})
}

func handlePing(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "pong")
}
<|endoftext|>


<commit_before>package logging

import (
	"bytes"
	"io"
	"sync"
	"text/template"
	"time"
)

const (
	DefaultTimeLayout = "2006-01-02 15:04:05"
	DefaultFormat     = "[{{.TimeString}}] {{.Level}} {{.Message}}\n"
	DefaultBufSize    = 1024
)

type Handler interface {
	SetLevel(LogLevel)
	SetLevelRange(LogLevel, LogLevel)
	SetTimeLayout(string)
	SetFormat(string) error
	SetFilter(func(*Record) bool)
	Emit(Record)
}

type Record struct {
	Time       time.Time
	TimeString string
	Level      LogLevel
	Message    string
}

type BaseHandler struct {
	Mutex      sync.Mutex
	Writer     io.WriteCloser
	Level      LogLevel
	LRange     *LevelRange
	TimeLayout string
	Tmpl       *template.Template
	RecordChan chan *Record
	Filter     func(*Record) bool
	PredoFunc  func(io.ReadWriter)
	WriteN     func(int64)
	GotError   func(error)
}

func NewBaseHandler(out io.WriteCloser, level LogLevel, layout, format string) (*BaseHandler, error) {
	h := &BaseHandler{
		Writer:     out,
		Level:      level,
		TimeLayout: layout,
	}
	if err := h.SetFormat(format); err != nil {
		return nil, err
	}
	h.RecordChan = make(chan *Record, DefaultBufSize)
	h.GotError = h.PanicError
	go h.BackendWriteRecord()
	return h, nil
}

func (h *BaseHandler) SetLevel(level LogLevel) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.Level = level
}

func (h *BaseHandler) SetLevelRange(min_level, max_level LogLevel) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.LRange = &LevelRange{min_level, max_level}
}

func (h *BaseHandler) SetTimeLayout(layout string) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.TimeLayout = layout
}

func (h *BaseHandler) SetFormat(format string) error {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	tmpl, err := template.New("tmpl").Parse(format)
	if err != nil {
		return err
	}
	h.Tmpl = tmpl
	return nil
}

func (h *BaseHandler) SetFilter(f func(*Record) bool) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.Filter = f
}

func (h *BaseHandler) Emit(rd Record) {
	if h.LRange != nil {
		if !h.LRange.Contain(rd.Level) {
			return
		}
	} else if h.Level > rd.Level {
		return
	}
	h.RecordChan <- &rd
}

func (h *BaseHandler) PanicError(err error) {
	if err != nil {
		panic(err)
	}
}

func (h *BaseHandler) BackendWriteRecord() {
	rd := &Record{}
	buf := bytes.NewBuffer(nil)
	for {
		rd = <-h.RecordChan
		if h.Filter != nil && h.Filter(rd) {
			continue
		}
		if h.Writer == nil {
			continue
		}
		buf.Reset()
		rd.TimeString = rd.Time.Format(h.TimeLayout)
		if err := h.Tmpl.Execute(buf, rd); err != nil {
			h.GotError(err)
			continue
		}
		if h.PredoFunc != nil {
			h.PredoFunc(buf)
		}
		n, err := io.Copy(h.Writer, buf)
		if err != nil {
			h.GotError(err)
		}
		if h.WriteN != nil {
			h.WriteN(int64(n))
		}
	}
}
<commit_msg>rename backend write record<commit_after>package logging

import (
	"bytes"
	"io"
	"sync"
	"text/template"
	"time"
)

const (
	DefaultTimeLayout = "2006-01-02 15:04:05"
	DefaultFormat     = "[{{.TimeString}}] {{.Level}} {{.Message}}\n"
	DefaultBufSize    = 1024
)

type Handler interface {
	SetLevel(LogLevel)
	SetLevelRange(LogLevel, LogLevel)
	SetTimeLayout(string)
	SetFormat(string) error
	SetFilter(func(*Record) bool)
	Emit(Record)
}

type Record struct {
	Time       time.Time
	TimeString string
	Level      LogLevel
	Message    string
}

type BaseHandler struct {
	Mutex      sync.Mutex
	Writer     io.WriteCloser
	Level      LogLevel
	LRange     *LevelRange
	TimeLayout string
	Tmpl       *template.Template
	RecordChan chan *Record
	Filter     func(*Record) bool
	PredoFunc  func(io.ReadWriter)
	WriteN     func(int64)
	GotError   func(error)
}

func NewBaseHandler(out io.WriteCloser, level LogLevel, layout, format string) (*BaseHandler, error) {
	h := &BaseHandler{
		Writer:     out,
		Level:      level,
		TimeLayout: layout,
	}
	if err := h.SetFormat(format); err != nil {
		return nil, err
	}
	h.RecordChan = make(chan *Record, DefaultBufSize)
	h.GotError = h.PanicError
	go h.WriteRecord()
	return h, nil
}

func (h *BaseHandler) SetLevel(level LogLevel) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.Level = level
}

func (h *BaseHandler) SetLevelRange(min_level, max_level LogLevel) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.LRange = &LevelRange{min_level, max_level}
}

func (h *BaseHandler) SetTimeLayout(layout string) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.TimeLayout = layout
}

func (h *BaseHandler) SetFormat(format string) error {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	tmpl, err := template.New("tmpl").Parse(format)
	if err != nil {
		return err
	}
	h.Tmpl = tmpl
	return nil
}

func (h *BaseHandler) SetFilter(f func(*Record) bool) {
	h.Mutex.Lock()
	defer h.Mutex.Unlock()
	h.Filter = f
}

func (h *BaseHandler) Emit(rd Record) {
	if h.LRange != nil {
		if !h.LRange.Contain(rd.Level) {
			return
		}
	} else if h.Level > rd.Level {
		return
	}
	h.RecordChan <- &rd
}

func (h *BaseHandler) PanicError(err error) {
	if err != nil {
		panic(err)
	}
}

func (h *BaseHandler) WriteRecord() {
	rd := &Record{}
	buf := bytes.NewBuffer(nil)
	for {
		rd = <-h.RecordChan
		if h.Filter != nil && h.Filter(rd) {
			continue
		}
		if h.Writer == nil {
			continue
		}
		buf.Reset()
		rd.TimeString = rd.Time.Format(h.TimeLayout)
		if err := h.Tmpl.Execute(buf, rd); err != nil {
			h.GotError(err)
			continue
		}
		if h.PredoFunc != nil {
			h.PredoFunc(buf)
		}
		n, err := io.Copy(h.Writer, buf)
		if err != nil {
			h.GotError(err)
		}
		if h.WriteN != nil {
			h.WriteN(int64(n))
		}
	}
}
<|endoftext|>