<commit_before>package libnetwork

import (
	"encoding/json"
	"fmt"
	"net"

	"github.com/docker/libnetwork/driverapi"
	"github.com/docker/libnetwork/types"
)

// EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
type EndpointInfo interface {
	// Iface returns InterfaceInfo, go interface that can be used
	// to get more information on the interface which was assigned to
	// the endpoint by the driver. This can be used after the
	// endpoint has been created.
	Iface() InterfaceInfo

	// Gateway returns the IPv4 gateway assigned by the driver.
	// This will only return a valid value if a container has joined the endpoint.
	Gateway() net.IP

	// GatewayIPv6 returns the IPv6 gateway assigned by the driver.
	// This will only return a valid value if a container has joined the endpoint.
	GatewayIPv6() net.IP

	// StaticRoutes returns the list of static routes configured by the network
	// driver when the container joins a network
	StaticRoutes() []*types.StaticRoute

	// Sandbox returns the attached sandbox if there, nil otherwise.
	Sandbox() Sandbox
}

// InterfaceInfo provides an interface to retrieve interface addresses bound to the endpoint.
type InterfaceInfo interface {
	// MacAddress returns the MAC address assigned to the endpoint.
	MacAddress() net.HardwareAddr

	// Address returns the IPv4 address assigned to the endpoint.
	Address() *net.IPNet

	// AddressIPv6 returns the IPv6 address assigned to the endpoint.
	AddressIPv6() *net.IPNet

	// LinkLocalAddresses returns the list of link-local (IPv4/IPv6) addresses assigned to the endpoint.
	LinkLocalAddresses() []*net.IPNet
}

type endpointInterface struct {
	mac       net.HardwareAddr
	addr      *net.IPNet
	addrv6    *net.IPNet
	llAddrs   []*net.IPNet
	srcName   string
	dstPrefix string
	routes    []*net.IPNet
	v4PoolID  string
	v6PoolID  string
}

func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
	epMap := make(map[string]interface{})
	if epi.mac != nil {
		epMap["mac"] = epi.mac.String()
	}
	if epi.addr != nil {
		epMap["addr"] = epi.addr.String()
	}
	if epi.addrv6 != nil {
		epMap["addrv6"] = epi.addrv6.String()
	}
	if len(epi.llAddrs) != 0 {
		list := make([]string, 0, len(epi.llAddrs))
		for _, ll := range epi.llAddrs {
			list = append(list, ll.String())
		}
		epMap["llAddrs"] = list
	}
	epMap["srcName"] = epi.srcName
	epMap["dstPrefix"] = epi.dstPrefix
	var routes []string
	for _, route := range epi.routes {
		routes = append(routes, route.String())
	}
	epMap["routes"] = routes
	epMap["v4PoolID"] = epi.v4PoolID
	epMap["v6PoolID"] = epi.v6PoolID
	return json.Marshal(epMap)
}

func (epi *endpointInterface) UnmarshalJSON(b []byte) error {
	var (
		err   error
		epMap map[string]interface{}
	)
	if err = json.Unmarshal(b, &epMap); err != nil {
		return err
	}
	if v, ok := epMap["mac"]; ok {
		if epi.mac, err = net.ParseMAC(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
		}
	}
	if v, ok := epMap["addr"]; ok {
		if epi.addr, err = types.ParseCIDR(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
		}
	}
	if v, ok := epMap["addrv6"]; ok {
		if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err)
		}
	}
	if v, ok := epMap["llAddrs"]; ok {
		list := v.([]interface{})
		epi.llAddrs = make([]*net.IPNet, 0, len(list))
		for _, llS := range list {
			ll, err := types.ParseCIDR(llS.(string))
			if err != nil {
				return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err)
			}
			epi.llAddrs = append(epi.llAddrs, ll)
		}
	}
	epi.srcName = epMap["srcName"].(string)
	epi.dstPrefix = epMap["dstPrefix"].(string)

	rb, _ := json.Marshal(epMap["routes"])
	var routes []string
	json.Unmarshal(rb, &routes)
	epi.routes = make([]*net.IPNet, 0)
	for _, route := range routes {
		ip, ipr, err := net.ParseCIDR(route)
		if err == nil {
			ipr.IP = ip
			epi.routes = append(epi.routes, ipr)
		}
	}
	epi.v4PoolID = epMap["v4PoolID"].(string)
	epi.v6PoolID = epMap["v6PoolID"].(string)

	return nil
}

func (epi *endpointInterface) CopyTo(dstEpi *endpointInterface) error {
	dstEpi.mac = types.GetMacCopy(epi.mac)
	dstEpi.addr = types.GetIPNetCopy(epi.addr)
	dstEpi.addrv6 = types.GetIPNetCopy(epi.addrv6)
	dstEpi.srcName = epi.srcName
	dstEpi.dstPrefix = epi.dstPrefix
	dstEpi.v4PoolID = epi.v4PoolID
	dstEpi.v6PoolID = epi.v6PoolID
	if len(epi.llAddrs) != 0 {
		dstEpi.llAddrs = make([]*net.IPNet, 0, len(epi.llAddrs))
		dstEpi.llAddrs = append(dstEpi.llAddrs, epi.llAddrs...)
	}

	for _, route := range epi.routes {
		dstEpi.routes = append(dstEpi.routes, types.GetIPNetCopy(route))
	}

	return nil
}

type endpointJoinInfo struct {
	gw                    net.IP
	gw6                   net.IP
	StaticRoutes          []*types.StaticRoute
	driverTableEntries    []*tableEntry
	disableGatewayService bool
}

type tableEntry struct {
	tableName string
	key       string
	value     []byte
}

func (ep *endpoint) Info() EndpointInfo {
	if ep.sandboxID != "" {
		return ep
	}
	n, err := ep.getNetworkFromStore()
	if err != nil {
		return nil
	}

	ep, err = n.getEndpointFromStore(ep.ID())
	if err != nil {
		return nil
	}

	sb, ok := ep.getSandbox()
	if !ok {
		// endpoint hasn't joined any sandbox.
		// Just return the endpoint
		return ep
	}

	if epi := sb.getEndpoint(ep.ID()); epi != nil {
		return epi
	}

	return nil
}

func (ep *endpoint) Iface() InterfaceInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (ep *endpoint) Interface() driverapi.InterfaceInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (epi *endpointInterface) SetMacAddress(mac net.HardwareAddr) error {
	if epi.mac != nil {
		return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", epi.mac, mac)
	}
	if mac == nil {
		return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
	}
	epi.mac = types.GetMacCopy(mac)
	return nil
}

func (epi *endpointInterface) SetIPAddress(address *net.IPNet) error {
	if address.IP == nil {
		return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
	}
	if address.IP.To4() == nil {
		return setAddress(&epi.addrv6, address)
	}
	return setAddress(&epi.addr, address)
}

func setAddress(ifaceAddr **net.IPNet, address *net.IPNet) error {
	if *ifaceAddr != nil {
		return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
	}
	*ifaceAddr = types.GetIPNetCopy(address)
	return nil
}

func (epi *endpointInterface) MacAddress() net.HardwareAddr {
	return types.GetMacCopy(epi.mac)
}

func (epi *endpointInterface) Address() *net.IPNet {
	return types.GetIPNetCopy(epi.addr)
}

func (epi *endpointInterface) AddressIPv6() *net.IPNet {
	return types.GetIPNetCopy(epi.addrv6)
}

func (epi *endpointInterface) LinkLocalAddresses() []*net.IPNet {
	return epi.llAddrs
}

func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
	epi.srcName = srcName
	epi.dstPrefix = dstPrefix
	return nil
}

func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}

	if routeType == types.NEXTHOP {
		// If the route specifies a next-hop, then it's loosely routed (i.e. not bound to a particular interface).
		ep.joinInfo.StaticRoutes = append(ep.joinInfo.StaticRoutes, &r)
	} else {
		// If the route doesn't specify a next-hop, it must be a connected route, bound to an interface.
		ep.iface.routes = append(ep.iface.routes, r.Destination)
	}
	return nil
}

func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.driverTableEntries = append(ep.joinInfo.driverTableEntries, &tableEntry{
		tableName: tableName,
		key:       key,
		value:     value,
	})

	return nil
}

func (ep *endpoint) Sandbox() Sandbox {
	cnt, ok := ep.getSandbox()
	if !ok {
		return nil
	}
	return cnt
}

func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return nil
	}

	return ep.joinInfo.StaticRoutes
}

func (ep *endpoint) Gateway() net.IP {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return net.IP{}
	}

	return types.GetIPCopy(ep.joinInfo.gw)
}

func (ep *endpoint) GatewayIPv6() net.IP {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return net.IP{}
	}

	return types.GetIPCopy(ep.joinInfo.gw6)
}

func (ep *endpoint) SetGateway(gw net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.gw = types.GetIPCopy(gw)
	return nil
}

func (ep *endpoint) SetGatewayIPv6(gw6 net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.gw6 = types.GetIPCopy(gw6)
	return nil
}

func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
	n, err := ep.getNetworkFromStore()
	if err != nil {
		return nil, fmt.Errorf("could not find network in store to get latest endpoint %s: %v", ep.Name(), err)
	}
	return n.getEndpointFromStore(ep.ID())
}

func (ep *endpoint) DisableGatewayService() {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.disableGatewayService = true
}

func (epj *endpointJoinInfo) MarshalJSON() ([]byte, error) {
	epMap := make(map[string]interface{})
	if epj.gw != nil {
		epMap["gw"] = epj.gw.String()
	}
	if epj.gw6 != nil {
		epMap["gw6"] = epj.gw6.String()
	}
	epMap["disableGatewayService"] = epj.disableGatewayService
	epMap["StaticRoutes"] = epj.StaticRoutes
	return json.Marshal(epMap)
}

func (epj *endpointJoinInfo) UnmarshalJSON(b []byte) error {
	var (
		err   error
		epMap map[string]interface{}
	)
	if err = json.Unmarshal(b, &epMap); err != nil {
		return err
	}
	if v, ok := epMap["gw"]; ok {
		epj.gw6 = net.ParseIP(v.(string))
	}
	if v, ok := epMap["gw6"]; ok {
		epj.gw6 = net.ParseIP(v.(string))
	}
	epj.disableGatewayService = epMap["disableGatewayService"].(bool)

	var tStaticRoute []types.StaticRoute
	if v, ok := epMap["StaticRoutes"]; ok {
		tb, _ := json.Marshal(v)
		var tStaticRoute []types.StaticRoute
		json.Unmarshal(tb, &tStaticRoute)
	}
	var StaticRoutes []*types.StaticRoute
	for _, r := range tStaticRoute {
		StaticRoutes = append(StaticRoutes, &r)
	}
	epj.StaticRoutes = StaticRoutes

	return nil
}

func (epj *endpointJoinInfo) CopyTo(dstEpj *endpointJoinInfo) error {
	dstEpj.disableGatewayService = epj.disableGatewayService
	dstEpj.StaticRoutes = make([]*types.StaticRoute, len(epj.StaticRoutes))
	copy(dstEpj.StaticRoutes, epj.StaticRoutes)
	dstEpj.driverTableEntries = make([]*tableEntry, len(epj.driverTableEntries))
	copy(dstEpj.driverTableEntries, epj.driverTableEntries)
	dstEpj.gw = types.GetIPCopy(epj.gw)
	dstEpj.gw = types.GetIPCopy(epj.gw6)
	return nil
}
<commit_msg>Fixes bug which makes restoring endpoint mess<commit_after>package libnetwork

import (
	"encoding/json"
	"fmt"
	"net"

	"github.com/docker/libnetwork/driverapi"
	"github.com/docker/libnetwork/types"
)

// EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
type EndpointInfo interface {
	// Iface returns InterfaceInfo, go interface that can be used
	// to get more information on the interface which was assigned to
	// the endpoint by the driver. This can be used after the
	// endpoint has been created.
	Iface() InterfaceInfo

	// Gateway returns the IPv4 gateway assigned by the driver.
	// This will only return a valid value if a container has joined the endpoint.
	Gateway() net.IP

	// GatewayIPv6 returns the IPv6 gateway assigned by the driver.
	// This will only return a valid value if a container has joined the endpoint.
	GatewayIPv6() net.IP

	// StaticRoutes returns the list of static routes configured by the network
	// driver when the container joins a network
	StaticRoutes() []*types.StaticRoute

	// Sandbox returns the attached sandbox if there, nil otherwise.
	Sandbox() Sandbox
}

// InterfaceInfo provides an interface to retrieve interface addresses bound to the endpoint.
type InterfaceInfo interface {
	// MacAddress returns the MAC address assigned to the endpoint.
	MacAddress() net.HardwareAddr

	// Address returns the IPv4 address assigned to the endpoint.
	Address() *net.IPNet

	// AddressIPv6 returns the IPv6 address assigned to the endpoint.
	AddressIPv6() *net.IPNet

	// LinkLocalAddresses returns the list of link-local (IPv4/IPv6) addresses assigned to the endpoint.
	LinkLocalAddresses() []*net.IPNet
}

type endpointInterface struct {
	mac       net.HardwareAddr
	addr      *net.IPNet
	addrv6    *net.IPNet
	llAddrs   []*net.IPNet
	srcName   string
	dstPrefix string
	routes    []*net.IPNet
	v4PoolID  string
	v6PoolID  string
}

func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
	epMap := make(map[string]interface{})
	if epi.mac != nil {
		epMap["mac"] = epi.mac.String()
	}
	if epi.addr != nil {
		epMap["addr"] = epi.addr.String()
	}
	if epi.addrv6 != nil {
		epMap["addrv6"] = epi.addrv6.String()
	}
	if len(epi.llAddrs) != 0 {
		list := make([]string, 0, len(epi.llAddrs))
		for _, ll := range epi.llAddrs {
			list = append(list, ll.String())
		}
		epMap["llAddrs"] = list
	}
	epMap["srcName"] = epi.srcName
	epMap["dstPrefix"] = epi.dstPrefix
	var routes []string
	for _, route := range epi.routes {
		routes = append(routes, route.String())
	}
	epMap["routes"] = routes
	epMap["v4PoolID"] = epi.v4PoolID
	epMap["v6PoolID"] = epi.v6PoolID
	return json.Marshal(epMap)
}

func (epi *endpointInterface) UnmarshalJSON(b []byte) error {
	var (
		err   error
		epMap map[string]interface{}
	)
	if err = json.Unmarshal(b, &epMap); err != nil {
		return err
	}
	if v, ok := epMap["mac"]; ok {
		if epi.mac, err = net.ParseMAC(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
		}
	}
	if v, ok := epMap["addr"]; ok {
		if epi.addr, err = types.ParseCIDR(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
		}
	}
	if v, ok := epMap["addrv6"]; ok {
		if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil {
			return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err)
		}
	}
	if v, ok := epMap["llAddrs"]; ok {
		list := v.([]interface{})
		epi.llAddrs = make([]*net.IPNet, 0, len(list))
		for _, llS := range list {
			ll, err := types.ParseCIDR(llS.(string))
			if err != nil {
				return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err)
			}
			epi.llAddrs = append(epi.llAddrs, ll)
		}
	}
	epi.srcName = epMap["srcName"].(string)
	epi.dstPrefix = epMap["dstPrefix"].(string)

	rb, _ := json.Marshal(epMap["routes"])
	var routes []string
	json.Unmarshal(rb, &routes)
	epi.routes = make([]*net.IPNet, 0)
	for _, route := range routes {
		ip, ipr, err := net.ParseCIDR(route)
		if err == nil {
			ipr.IP = ip
			epi.routes = append(epi.routes, ipr)
		}
	}
	epi.v4PoolID = epMap["v4PoolID"].(string)
	epi.v6PoolID = epMap["v6PoolID"].(string)

	return nil
}

func (epi *endpointInterface) CopyTo(dstEpi *endpointInterface) error {
	dstEpi.mac = types.GetMacCopy(epi.mac)
	dstEpi.addr = types.GetIPNetCopy(epi.addr)
	dstEpi.addrv6 = types.GetIPNetCopy(epi.addrv6)
	dstEpi.srcName = epi.srcName
	dstEpi.dstPrefix = epi.dstPrefix
	dstEpi.v4PoolID = epi.v4PoolID
	dstEpi.v6PoolID = epi.v6PoolID
	if len(epi.llAddrs) != 0 {
		dstEpi.llAddrs = make([]*net.IPNet, 0, len(epi.llAddrs))
		dstEpi.llAddrs = append(dstEpi.llAddrs, epi.llAddrs...)
	}

	for _, route := range epi.routes {
		dstEpi.routes = append(dstEpi.routes, types.GetIPNetCopy(route))
	}

	return nil
}

type endpointJoinInfo struct {
	gw                    net.IP
	gw6                   net.IP
	StaticRoutes          []*types.StaticRoute
	driverTableEntries    []*tableEntry
	disableGatewayService bool
}

type tableEntry struct {
	tableName string
	key       string
	value     []byte
}

func (ep *endpoint) Info() EndpointInfo {
	if ep.sandboxID != "" {
		return ep
	}
	n, err := ep.getNetworkFromStore()
	if err != nil {
		return nil
	}

	ep, err = n.getEndpointFromStore(ep.ID())
	if err != nil {
		return nil
	}

	sb, ok := ep.getSandbox()
	if !ok {
		// endpoint hasn't joined any sandbox.
		// Just return the endpoint
		return ep
	}

	if epi := sb.getEndpoint(ep.ID()); epi != nil {
		return epi
	}

	return nil
}

func (ep *endpoint) Iface() InterfaceInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (ep *endpoint) Interface() driverapi.InterfaceInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (epi *endpointInterface) SetMacAddress(mac net.HardwareAddr) error {
	if epi.mac != nil {
		return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", epi.mac, mac)
	}
	if mac == nil {
		return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
	}
	epi.mac = types.GetMacCopy(mac)
	return nil
}

func (epi *endpointInterface) SetIPAddress(address *net.IPNet) error {
	if address.IP == nil {
		return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
	}
	if address.IP.To4() == nil {
		return setAddress(&epi.addrv6, address)
	}
	return setAddress(&epi.addr, address)
}

func setAddress(ifaceAddr **net.IPNet, address *net.IPNet) error {
	if *ifaceAddr != nil {
		return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
	}
	*ifaceAddr = types.GetIPNetCopy(address)
	return nil
}

func (epi *endpointInterface) MacAddress() net.HardwareAddr {
	return types.GetMacCopy(epi.mac)
}

func (epi *endpointInterface) Address() *net.IPNet {
	return types.GetIPNetCopy(epi.addr)
}

func (epi *endpointInterface) AddressIPv6() *net.IPNet {
	return types.GetIPNetCopy(epi.addrv6)
}

func (epi *endpointInterface) LinkLocalAddresses() []*net.IPNet {
	return epi.llAddrs
}

func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
	epi.srcName = srcName
	epi.dstPrefix = dstPrefix
	return nil
}

func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
	ep.Lock()
	defer ep.Unlock()

	if ep.iface != nil {
		return ep.iface
	}

	return nil
}

func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}

	if routeType == types.NEXTHOP {
		// If the route specifies a next-hop, then it's loosely routed (i.e. not bound to a particular interface).
		ep.joinInfo.StaticRoutes = append(ep.joinInfo.StaticRoutes, &r)
	} else {
		// If the route doesn't specify a next-hop, it must be a connected route, bound to an interface.
		ep.iface.routes = append(ep.iface.routes, r.Destination)
	}
	return nil
}

func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.driverTableEntries = append(ep.joinInfo.driverTableEntries, &tableEntry{
		tableName: tableName,
		key:       key,
		value:     value,
	})

	return nil
}

func (ep *endpoint) Sandbox() Sandbox {
	cnt, ok := ep.getSandbox()
	if !ok {
		return nil
	}
	return cnt
}

func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return nil
	}

	return ep.joinInfo.StaticRoutes
}

func (ep *endpoint) Gateway() net.IP {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return net.IP{}
	}

	return types.GetIPCopy(ep.joinInfo.gw)
}

func (ep *endpoint) GatewayIPv6() net.IP {
	ep.Lock()
	defer ep.Unlock()

	if ep.joinInfo == nil {
		return net.IP{}
	}

	return types.GetIPCopy(ep.joinInfo.gw6)
}

func (ep *endpoint) SetGateway(gw net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.gw = types.GetIPCopy(gw)
	return nil
}

func (ep *endpoint) SetGatewayIPv6(gw6 net.IP) error {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.gw6 = types.GetIPCopy(gw6)
	return nil
}

func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
	n, err := ep.getNetworkFromStore()
	if err != nil {
		return nil, fmt.Errorf("could not find network in store to get latest endpoint %s: %v", ep.Name(), err)
	}
	return n.getEndpointFromStore(ep.ID())
}

func (ep *endpoint) DisableGatewayService() {
	ep.Lock()
	defer ep.Unlock()

	ep.joinInfo.disableGatewayService = true
}

func (epj *endpointJoinInfo) MarshalJSON() ([]byte, error) {
	epMap := make(map[string]interface{})
	if epj.gw != nil {
		epMap["gw"] = epj.gw.String()
	}
	if epj.gw6 != nil {
		epMap["gw6"] = epj.gw6.String()
	}
	epMap["disableGatewayService"] = epj.disableGatewayService
	epMap["StaticRoutes"] = epj.StaticRoutes
	return json.Marshal(epMap)
}

func (epj *endpointJoinInfo) UnmarshalJSON(b []byte) error {
	var (
		err   error
		epMap map[string]interface{}
	)
	if err = json.Unmarshal(b, &epMap); err != nil {
		return err
	}
	if v, ok := epMap["gw"]; ok {
		epj.gw = net.ParseIP(v.(string))
	}
	if v, ok := epMap["gw6"]; ok {
		epj.gw6 = net.ParseIP(v.(string))
	}
	epj.disableGatewayService = epMap["disableGatewayService"].(bool)

	var tStaticRoute []types.StaticRoute
	if v, ok := epMap["StaticRoutes"]; ok {
		tb, _ := json.Marshal(v)
		var tStaticRoute []types.StaticRoute
		json.Unmarshal(tb, &tStaticRoute)
	}
	var StaticRoutes []*types.StaticRoute
	for _, r := range tStaticRoute {
		StaticRoutes = append(StaticRoutes, &r)
	}
	epj.StaticRoutes = StaticRoutes

	return nil
}

func (epj *endpointJoinInfo) CopyTo(dstEpj *endpointJoinInfo) error {
	dstEpj.disableGatewayService = epj.disableGatewayService
	dstEpj.StaticRoutes = make([]*types.StaticRoute, len(epj.StaticRoutes))
	copy(dstEpj.StaticRoutes, epj.StaticRoutes)
	dstEpj.driverTableEntries = make([]*tableEntry, len(epj.driverTableEntries))
	copy(dstEpj.driverTableEntries, epj.driverTableEntries)
	dstEpj.gw = types.GetIPCopy(epj.gw)
	dstEpj.gw6 = types.GetIPCopy(epj.gw6)
	return nil
}
<|endoftext|>


<commit_before>//  Copyright (c) 2019 Cisco and/or its affiliates.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

// tlsconfig provides more convenient way to create tls.Config
//
// Usage:
// 		package main
//
// 		import "fmt"
//		import "go.ligato.io/vpp-agent/v2/cmd/agentctl/client/tlsconfig"
//
// 		func main() {
// 			tc, err := tlsconfig.New(
// 				tlsconfig.CA("/path/to/ca.crt"),
// 				tlsconfig.CertKey("/path/to/server.crt", "/path/to/server.key"),
// 			)
//
// 			if err != nil {
// 				fmt.Printf("Error while creating TLS config: %v\n", err)
// 				return
// 			}
// 			fmt.Println("TLS config is ready to use")
//
// 			// `tc` usage
// 		}
//

package tlsconfig

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
)

// New returns tls.Config with all options applied.
func New(options ...Option) (*tls.Config, error) {
	config := &tls.Config{
		MinVersion: tls.VersionTLS12,
	}

	for _, op := range options {
		if err := op(config); err != nil {
			return nil, err
		}
	}

	return config, nil
}

// Option applies a modification on a tls.Config.
type Option func(config *tls.Config) error

// CA adds CA certificate from file to tls.Config.
// If not using this Option, then TLS will be using the host's root CA set.
func CA(path string) Option {
	return func(config *tls.Config) error {
		if config.RootCAs == nil {
			config.RootCAs = x509.NewCertPool()
		}

		cert, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}

		ok := config.RootCAs.AppendCertsFromPEM(cert)
		if !ok {
			return fmt.Errorf("unable to add CA from '%s' file", path)
		}

		return nil
	}
}

// CertKey adds certificate with key to tls.Config.
func CertKey(certPath, keyPath string) Option {
	return func(config *tls.Config) error {
		cert, err := tls.LoadX509KeyPair(certPath, keyPath)
		if err != nil {
			return err
		}
		config.Certificates = append(config.Certificates, cert)
		return err
	}
}

// SkipServerVerification turns off verification of server's certificate chain and host name.
func SkipServerVerification() Option {
	return func(config *tls.Config) error {
		config.InsecureSkipVerify = true
		return nil
	}
}
<commit_msg>Fix documentation for tlsconfig package<commit_after>//  Copyright (c) 2019 Cisco and/or its affiliates.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

// Package tlsconfig provides more convenient way to create "tls.Config".
//
// Usage:
// 		package main
//
// 		import "fmt"
//		import "go.ligato.io/vpp-agent/v2/cmd/agentctl/client/tlsconfig"
//
// 		func main() {
// 			tc, err := tlsconfig.New(
// 				tlsconfig.CA("/path/to/ca.crt"),
// 				tlsconfig.CertKey("/path/to/server.crt", "/path/to/server.key"),
// 			)
//
// 			if err != nil {
// 				fmt.Printf("Error while creating TLS config: %v\n", err)
// 				return
// 			}
// 			fmt.Println("TLS config is ready to use")
//
// 			// `tc` usage
// 		}
//
package tlsconfig

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
)

// New returns tls.Config with all options applied.
func New(options ...Option) (*tls.Config, error) {
	config := &tls.Config{
		MinVersion: tls.VersionTLS12,
	}

	for _, op := range options {
		if err := op(config); err != nil {
			return nil, err
		}
	}

	return config, nil
}

// Option applies a modification on a tls.Config.
type Option func(config *tls.Config) error

// CA adds CA certificate from file to tls.Config.
// If not using this Option, then TLS will be using the host's root CA set.
func CA(path string) Option {
	return func(config *tls.Config) error {
		if config.RootCAs == nil {
			config.RootCAs = x509.NewCertPool()
		}

		cert, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}

		ok := config.RootCAs.AppendCertsFromPEM(cert)
		if !ok {
			return fmt.Errorf("unable to add CA from '%s' file", path)
		}

		return nil
	}
}

// CertKey adds certificate with key to tls.Config.
func CertKey(certPath, keyPath string) Option {
	return func(config *tls.Config) error {
		cert, err := tls.LoadX509KeyPair(certPath, keyPath)
		if err != nil {
			return err
		}
		config.Certificates = append(config.Certificates, cert)
		return err
	}
}

// SkipServerVerification turns off verification of server's certificate chain and host name.
func SkipServerVerification() Option {
	return func(config *tls.Config) error {
		config.InsecureSkipVerify = true
		return nil
	}
}
<|endoftext|>


<commit_before>package filelog

import (
	"bufio"
	"compress/gzip"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/gempir/go-twitch-irc"
	log "github.com/sirupsen/logrus"
)

type Logger struct {
	logPath string
}

func NewFileLogger(logPath string) Logger {
	return Logger{
		logPath: logPath,
	}
}

func (l *Logger) LogMessageForUser(channel string, user twitch.User, message twitch.Message) error {
	year := message.Time.Year()
	month := int(message.Time.Month())

	err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%d/", message.Tags["room-id"], year, month), 0750)
	if err != nil {
		return err
	}
	filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", message.Tags["room-id"], year, month, user.UserID)

	file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0640)
	if err != nil {
		return err
	}
	defer file.Close()

	if _, err = file.WriteString(message.Raw + "\n"); err != nil {
		return err
	}
	return nil
}

func (l *Logger) ReadLogForUser(channelID string, userID string, year int, month int) ([]string, error) {
	filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", channelID, year, month, userID)

	if _, err := os.Stat(filename); err != nil {
		filename = filename + ".gz"
	}

	log.Debug("Opening " + filename)
	f, err := os.Open(filename)
	if err != nil {
		return []string{}, errors.New("file not found: " + filename)
	}
	defer f.Close()

	var reader io.Reader

	if strings.HasSuffix(filename, ".gz") {
		gz, err := gzip.NewReader(f)
		if err != nil {
			return []string{}, errors.New("file gzip not readable")
		}
		reader = gz
	} else {
		reader = f
	}

	scanner := bufio.NewScanner(reader)
	if err != nil {
		return []string{}, errors.New("file not readable")
	}

	content := []string{}

	for scanner.Scan() {
		line := scanner.Text()
		content = append(content, line)
	}

	return content, nil
}
<commit_msg>catch invalid userID/channelId<commit_after>package filelog

import (
	"bufio"
	"compress/gzip"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/gempir/go-twitch-irc"
	log "github.com/sirupsen/logrus"
)

type Logger struct {
	logPath string
}

func NewFileLogger(logPath string) Logger {
	return Logger{
		logPath: logPath,
	}
}

func (l *Logger) LogMessageForUser(channel string, user twitch.User, message twitch.Message) error {
	year := message.Time.Year()
	month := int(message.Time.Month())

	err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%d/", message.Tags["room-id"], year, month), 0750)
	if err != nil {
		return err
	}
	filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", message.Tags["room-id"], year, month, user.UserID)

	file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0640)
	if err != nil {
		return err
	}
	defer file.Close()

	if _, err = file.WriteString(message.Raw + "\n"); err != nil {
		return err
	}
	return nil
}

func (l *Logger) ReadLogForUser(channelID string, userID string, year int, month int) ([]string, error) {
	if channelID == "" || userID == "" {
		return []string{}, fmt.Errorf("Invalid channelID: %s or userID: %s", channelID, userID)
	}

	filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", channelID, year, month, userID)

	if _, err := os.Stat(filename); err != nil {
		filename = filename + ".gz"
	}

	log.Debug("Opening " + filename)
	f, err := os.Open(filename)
	if err != nil {
		return []string{}, errors.New("file not found: " + filename)
	}
	defer f.Close()

	var reader io.Reader

	if strings.HasSuffix(filename, ".gz") {
		gz, err := gzip.NewReader(f)
		if err != nil {
			return []string{}, errors.New("file gzip not readable")
		}
		reader = gz
	} else {
		reader = f
	}

	scanner := bufio.NewScanner(reader)
	if err != nil {
		return []string{}, errors.New("file not readable")
	}

	content := []string{}

	for scanner.Scan() {
		line := scanner.Text()
		content = append(content, line)
	}

	return content, nil
}
<|endoftext|>


<commit_before>package util

import (
	"testing"
	"time"
)

// TestLimiterConn
// Ensure that the maximum connections may not be exceeded.
func TestLimiterConn(t *testing.T) {
	limiter, _ := NewLimiter(100, 100, 5)
	limiter.Connect()
	limiter.Connect()
	limiter.Connect()
	limiter.Connect()
	limiter.Connect()
	connected := false
	go func() {
		limiter.Connect()
		connected = true
	}()
	time.Sleep(1 * time.Second)
	if connected {
		t.Error("connection was not blocked by limiter")
	}
	limiter.Disconnect()
	// Ensure connected has a chance to be set to true before checking.
	time.Sleep(1 * time.Second)
	if !connected {
		t.Error("failed to connect once a connection was made available")
	}
}

// TestLimiterError
// Ensure errors are returned for invalid values.
// TODO - Hit all possible combinations of values.
func TestLimiterError(t *testing.T) {
	var err error
	if _, err = NewLimiter(0, 0, 0); err == nil {
		t.Error("expected error for 0/0/0 but got nil")
	}
	if _, err = NewLimiter(1, 0, 0); err == nil {
		t.Error("expected error for 0/1/1 but got nil")
	}
	if _, err = NewLimiter(1, 1, 0); err == nil {
		t.Error("expected error for 1/1/0 but got nil")
	}
}
<commit_msg>disabled limiter test that is causing timeout with CI for unkown reason<commit_after>package util

import (
	"testing"
)

// TestLimiterConn
// Ensure that the maximum connections may not be exceeded.
// TODO - Figure out why Codeship is timing this out, even though it passes
// in other environments.
//
// func TestLimiterConn(t *testing.T) {
// 	limiter, _ := NewLimiter(100, 100, 5)
// 	limiter.Connect()
// 	limiter.Connect()
// 	limiter.Connect()
// 	limiter.Connect()
// 	limiter.Connect()
// 	connected := false
// 	go func() {
// 		limiter.Connect()
// 		connected = true
// 	}()
// 	time.Sleep(1 * time.Second)
// 	if connected {
// 		t.Error("connection was not blocked by limiter")
// 	}
// 	limiter.Disconnect()
// 	// Ensure connected has a chance to be set to true before checking.
// 	time.Sleep(1 * time.Second)
// 	if !connected {
// 		t.Error("failed to connect once a connection was made available")
// 	}
// }

// TestLimiterError
// Ensure errors are returned for invalid values.
// TODO - Hit all possible combinations of values.
func TestLimiterError(t *testing.T) {
	var err error
	if _, err = NewLimiter(0, 0, 0); err == nil {
		t.Error("expected error for 0/0/0 but got nil")
	}
	if _, err = NewLimiter(1, 0, 0); err == nil {
		t.Error("expected error for 0/1/1 but got nil")
	}
	if _, err = NewLimiter(1, 1, 0); err == nil {
		t.Error("expected error for 1/1/0 but got nil")
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2016 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package templates

const (
	/**** Configuration template ****/
	ConfigurationTemplate = `
# bitmark-cli.conf -*- mode: libucl -*-

port = "{{.Port}}"
password = "{{.Password}}"
enable_https = "{{.EnableHttps}}"
bitmark_config_file = "{{.BitmarkConfigFile}}"
`

	BitmarkConfigTemplate = `
  {{.Field}} = {{.Value}}`

	BitmarkConnectTemplate = `
  connect = {public_key = "{{.PublicKey}}", address = "{{.Address}}"}`

	WebpagesConfigTemplate = `
app.value("ApiHost", {
    host: "{{.Host}}",
    port: "{{.Port}}",
    enableHttps: {{.EnableHttps}}
});
`
)
<commit_msg>modify template code<commit_after>// Copyright (c) 2014-2016 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package templates

const (
	/**** Configuration template ****/
	ConfigurationTemplate = `
# bitmark-mgmt.conf -*- mode: libucl -*-

port = "{{.Port}}"
password = "{{.Password}}"
enable_https = "{{.EnableHttps}}"
bitmark_config_file = "{{.BitmarkConfigFile}}"
`

	BitmarkConfigTemplate = `
  {{.Field}} = {{.Value}}`

	BitmarkConnectTemplate = `
  connect = {public_key = "{{.PublicKey}}", address = "{{.Address}}"}`

	WebpagesConfigTemplate = `
app.value("ApiHost", {
    host: "{{.Host}}",
    port: "{{.Port}}",
    enableHttps: {{.EnableHttps}}
});
`
)
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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 main

import (
	"context"
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"

	"github.com/GoogleCloudPlatform/api-proxy/src/go/configmanager"
	"github.com/GoogleCloudPlatform/api-proxy/src/go/configmanager/flags"
	"github.com/GoogleCloudPlatform/api-proxy/src/go/metadata"
	"github.com/golang/glog"
	"google.golang.org/grpc"

	v2grpc "github.com/envoyproxy/go-control-plane/envoy/api/v2"
	discoverygrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2"
	xds "github.com/envoyproxy/go-control-plane/pkg/server"
)

var (
	DiscoveryPort = flag.Int("discovery_port", 8790, "Port that configmanager should serve ADS")
)

func main() {
	flag.Parse()
	opts := flags.EnvoyConfigOptionsFromFlags()

	// Create context that allows cancellation.
	// Allows shutting down downstream servers gracefully.
	ctx, cancel := context.WithCancel(context.Background())

	var mf *metadata.MetadataFetcher
	if !opts.NonGCP {
		glog.Info("running on GCP, initializing metadata fetcher")
		mf = metadata.NewMetadataFetcher(opts.CommonOptions)
	}

	m, err := configmanager.NewConfigManager(mf, opts)
	if err != nil {
		glog.Exitf("fail to initialize config manager: %v", err)
	}
	server := xds.NewServer(ctx, m.Cache(), nil)
	grpcServer := grpc.NewServer()
	lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", *DiscoveryPort))
	if err != nil {
		glog.Exitf("Server failed to listen: %v", err)
	}

	// Register Envoy discovery services.
	discoverygrpc.RegisterAggregatedDiscoveryServiceServer(grpcServer, server)
	v2grpc.RegisterEndpointDiscoveryServiceServer(grpcServer, server)
	v2grpc.RegisterClusterDiscoveryServiceServer(grpcServer, server)
	v2grpc.RegisterRouteDiscoveryServiceServer(grpcServer, server)
	v2grpc.RegisterListenerDiscoveryServiceServer(grpcServer, server)
	fmt.Printf("config manager server is running at %s .......\n", lis.Addr())

	// Handle signals gracefully
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-signalChan
		glog.Warningf("Server got signal %v, stopping", sig)
		cancel()
		grpcServer.Stop()
	}()

	if err := grpcServer.Serve(lis); err != nil {
		glog.Exitf("Server fail to serve: %v", err)
	}
}
<commit_msg>delete unused discovery service<commit_after>// Copyright 2019 Google LLC
//
// 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 main

import (
	"context"
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"

	"github.com/GoogleCloudPlatform/api-proxy/src/go/configmanager"
	"github.com/GoogleCloudPlatform/api-proxy/src/go/configmanager/flags"
	"github.com/GoogleCloudPlatform/api-proxy/src/go/metadata"
	"github.com/golang/glog"
	"google.golang.org/grpc"

	v2grpc "github.com/envoyproxy/go-control-plane/envoy/api/v2"
	discoverygrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2"
	xds "github.com/envoyproxy/go-control-plane/pkg/server"
)

var (
	DiscoveryPort = flag.Int("discovery_port", 8790, "Port that configmanager should serve ADS")
)

func main() {
	flag.Parse()
	opts := flags.EnvoyConfigOptionsFromFlags()

	// Create context that allows cancellation.
	// Allows shutting down downstream servers gracefully.
	ctx, cancel := context.WithCancel(context.Background())

	var mf *metadata.MetadataFetcher
	if !opts.NonGCP {
		glog.Info("running on GCP, initializing metadata fetcher")
		mf = metadata.NewMetadataFetcher(opts.CommonOptions)
	}

	m, err := configmanager.NewConfigManager(mf, opts)
	if err != nil {
		glog.Exitf("fail to initialize config manager: %v", err)
	}
	server := xds.NewServer(ctx, m.Cache(), nil)
	grpcServer := grpc.NewServer()
	lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", *DiscoveryPort))
	if err != nil {
		glog.Exitf("Server failed to listen: %v", err)
	}

	// Register Envoy discovery services.
	discoverygrpc.RegisterAggregatedDiscoveryServiceServer(grpcServer, server)

	fmt.Printf("config manager server is running at %s .......\n", lis.Addr())

	// Handle signals gracefully
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-signalChan
		glog.Warningf("Server got signal %v, stopping", sig)
		cancel()
		grpcServer.Stop()
	}()

	if err := grpcServer.Serve(lis); err != nil {
		glog.Exitf("Server fail to serve: %v", err)
	}
}
<|endoftext|>


<commit_before>package filters

import (
	"encoding/json"
	"encoding/xml"
	"github.com/gophergala/yaag/middleware"
	"github.com/gophergala/yaag/yaag"
	"github.com/revel/revel"
	"net/http/httptest"
	"strings"
)

func FilterForApiDoc(c *revel.Controller, fc []revel.Filter) {

	if record, _ := revel.Config.Bool("yaag.record"); !record {
		log.Printf("record %v ", record)
		fc[0](c, fc[1:])
		return
	}

	w := httptest.NewRecorder()
	c.Response = revel.NewResponse(w)
	httpVerb := c.Request.Method
	customParams := make(map[string]interface{})
	headers := make(map[string]string)
	hasJson := false
	hasXml := false

	body := middleware.ReadBody(c.Request.Request)
	log.Println(*body)

	if c.Request.ContentType == "application/json" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := json.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		} else {
			err := json.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		}

	} else if c.Request.ContentType == "application/xml" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := xml.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Xml Error ! ", err)
			} else {
				hasXml = true
			}
		} else {
			err := xml.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasXml = true
			}
		}
	}
	// call remaiing filters
	fc[0](c, fc[1:])

	c.Result.Apply(c.Request, c.Response)

	// get headers
	for k, v := range c.Request.Header {
		headers[k] = strings.Join(v, " ")
	}

	htmlValues := yaag
	htmlValues.BaseLink = c.Request.URL.Host
	htmlValues.MethodType = httpVerb
	htmlValues.CurrentPath = c.Request.URL.Path
	htmlValues.PostForm = make(map[string]striing)
	for k, v := range c.Params.Form {
		htmlValues.PostForm[k] = strings.Join(v, " ")
	}
	htmlValues.RequestBody = *body
	htmlValues.RequestHeader = headers
	htmlValues.RequestUrlParams = make(map[string]string)
	for k, v := range c.Request.URL.Query() {
		htmlValues.RequestUrlParams[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseHeader = make(map[string]string)
	htmlValues.ResponseBody = w.Body.String()
	for k, v := range w.Header() {
		htmlValues.ResponseHeader[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseCode = w.Code
	yaag.GenerateHtml(&htmlValues)
}
<commit_msg>integrated with yaag package<commit_after>package filters

import (
	"encoding/json"
	"encoding/xml"
	"github.com/gophergala/yaag/middleware"
	"github.com/gophergala/yaag/yaag"
	"github.com/revel/revel"
	"log"
	"net/http/httptest"
	"strings"
)

func FilterForApiDoc(c *revel.Controller, fc []revel.Filter) {

	if record, _ := revel.Config.Bool("yaag.record"); !record {
		log.Printf("record %v ", record)
		fc[0](c, fc[1:])
		return
	}

	w := httptest.NewRecorder()
	c.Response = revel.NewResponse(w)
	httpVerb := c.Request.Method
	customParams := make(map[string]interface{})
	headers := make(map[string]string)
	hasJson := false
	hasXml := false

	body := middleware.ReadBody(c.Request.Request)
	log.Println(*body)

	if c.Request.ContentType == "application/json" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := json.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		} else {
			err := json.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasJson = true
			}
		}

	} else if c.Request.ContentType == "application/xml" {
		if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" {
			err := xml.Unmarshal([]byte(*body), &customParams)
			if err != nil {
				log.Println("Xml Error ! ", err)
			} else {
				hasXml = true
			}
		} else {
			err := xml.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams)
			if err != nil {
				log.Println("Json Error ! ", err)
			} else {
				hasXml = true
			}
		}
	}
	log.Println(hasXml, hasJson)
	// call remaiing filters
	fc[0](c, fc[1:])

	c.Result.Apply(c.Request, c.Response)

	// get headers
	for k, v := range c.Request.Header {
		headers[k] = strings.Join(v, " ")
	}

	htmlValues := yaag.APICall{}
	htmlValues.MethodType = httpVerb
	htmlValues.CurrentPath = c.Request.URL.Path
	htmlValues.PostForm = make(map[string]string)
	for k, v := range c.Params.Form {
		htmlValues.PostForm[k] = strings.Join(v, " ")
	}
	htmlValues.RequestBody = *body
	htmlValues.RequestHeader = headers
	htmlValues.RequestUrlParams = make(map[string]string)
	for k, v := range c.Request.URL.Query() {
		htmlValues.RequestUrlParams[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseHeader = make(map[string]string)
	htmlValues.ResponseBody = w.Body.String()
	for k, v := range w.Header() {
		htmlValues.ResponseHeader[k] = strings.Join(v, " ")
	}
	htmlValues.ResponseCode = w.Code
	apicallValue := yaag.ApiCallValue{}
	apicallValue.BaseLink = c.Request.URL.Host
	apicallValue.HtmlValues = make([]yaag.APICall, 1)
	apicallValue.HtmlValues[0] = htmlValues
	config := yaag.Config{Init: false, DocPath: "html/home.html"}
	yaag.GenerateHtml(&apicallValue, &config)
}
<|endoftext|>


<commit_before>// Copyright 2015 Luke Shumaker
// Copyright 2015 Davis Webb

package store

import (
	"database/sql"
	he "httpentity"
	"net/url"
	"math/rand"
)

var _ he.Entity = &ShortUrl{}
var dirShortUrls he.Entity = newDirShortUrls()

// Model /////////////////////////////////////////////////////////////

type ShortUrl struct {
	Id   string
	Dest *url.URL
}

func newShortURL(u *url.URL) *ShortUrl{
	s := &ShortUrl {
		Id: string(rand.Intn(128)),
		Dest: u,
	}
	// TODO implement Save()
	// err := s.Save()
	// if err != nil {
	// 	return nil
	// }
	return s
}

func GetShortUrlById(con DB, id string) *ShortUrl {
	var s ShortUrl
	err := con.QueryRow("SELECT shortURL FROM shortURL WHERE id=?", id).Scan(&s);
	switch {
		case err == sql.ErrNoRows:
			return nil
		case err != nil:
			panic(err)
		default:
			return &s
	}
}

func (o *ShortUrl) Subentity(name string, req he.Request) he.Entity {
	return nil
}

func (o *ShortUrl) Methods() map[string]he.Handler {
	panic("not implemented")
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirShortUrls struct {
	methods map[string]he.Handler
}

func newDirShortUrls() t_dirShortUrls {
	r := t_dirShortUrls{}
	r.methods = map[string]he.Handler{}
	return r
}

func (d t_dirShortUrls) Methods() map[string]he.Handler {
	return d.methods
}

func (d t_dirShortUrls) Subentity(name string, request he.Request) he.Entity {
	return GetShortUrlById(nil /*TODO*/, name)
}
<commit_msg>gofmt<commit_after>// Copyright 2015 Luke Shumaker
// Copyright 2015 Davis Webb

package store

import (
	"database/sql"
	he "httpentity"
	"math/rand"
	"net/url"
)

var _ he.Entity = &ShortUrl{}
var dirShortUrls he.Entity = newDirShortUrls()

// Model /////////////////////////////////////////////////////////////

type ShortUrl struct {
	Id   string
	Dest *url.URL
}

func newShortURL(u *url.URL) *ShortUrl {
	s := &ShortUrl{
		Id:   string(rand.Intn(128)),
		Dest: u,
	}
	// TODO implement Save()
	// err := s.Save()
	// if err != nil {
	// 	return nil
	// }
	return s
}

func GetShortUrlById(con DB, id string) *ShortUrl {
	var s ShortUrl
	err := con.QueryRow("SELECT shortURL FROM shortURL WHERE id=?", id).Scan(&s)
	switch {
	case err == sql.ErrNoRows:
		return nil
	case err != nil:
		panic(err)
	default:
		return &s
	}
}

func (o *ShortUrl) Subentity(name string, req he.Request) he.Entity {
	return nil
}

func (o *ShortUrl) Methods() map[string]he.Handler {
	panic("not implemented")
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirShortUrls struct {
	methods map[string]he.Handler
}

func newDirShortUrls() t_dirShortUrls {
	r := t_dirShortUrls{}
	r.methods = map[string]he.Handler{}
	return r
}

func (d t_dirShortUrls) Methods() map[string]he.Handler {
	return d.methods
}

func (d t_dirShortUrls) Subentity(name string, request he.Request) he.Entity {
	return GetShortUrlById(nil /*TODO*/, name)
}
<|endoftext|>


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

package multipart

import (
	"bytes"
	"crypto/rand"
	"errors"
	"fmt"
	"io"
	"net/textproto"
	"strings"
)

// A Writer generates multipart messages.
type Writer struct {
	w        io.Writer
	boundary string
	lastpart *part
}

// NewWriter returns a new multipart Writer with a random boundary,
// writing to w.
func NewWriter(w io.Writer) *Writer {
	return &Writer{
		w: w,
	}
}

// Boundary returns the Writer's boundary.
func (w *Writer) Boundary() string {
	if w.boundary == "" {
		w.boundary = randomBoundary()
	}
	return w.boundary
}

// SetBoundary overrides the Writer's default randomly-generated
// boundary separator with an explicit value.
//
// SetBoundary must be called before any parts are created, may only
// contain certain ASCII characters, and must be 1-69 bytes long.
func (w *Writer) SetBoundary(boundary string) error {
	if w.lastpart != nil {
		return errors.New("mime: SetBoundary called after write")
	}
	// rfc2046#section-5.1.1
	if len(boundary) < 1 || len(boundary) > 69 {
		return errors.New("mime: invalid boundary length")
	}
	for _, b := range boundary {
		if 'A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' {
			continue
		}
		switch b {
		case '\'', '(', ')', '+', '_', ',', '-', '.', '/', ':', '=', '?':
			continue
		}
		return errors.New("mime: invalid boundary character")
	}
	w.boundary = boundary
	return nil
}

// FormDataContentType returns the Content-Type for an HTTP
// multipart/form-data with this Writer's Boundary.
func (w *Writer) FormDataContentType() string {
	return "multipart/form-data; boundary=" + w.Boundary()
}

func randomBoundary() string {
	var buf [30]byte
	_, err := io.ReadFull(rand.Reader, buf[:])
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", buf[:])
}

// CreatePart creates a new multipart section with the provided
// header. The body of the part should be written to the returned
// Writer. After calling CreatePart, any previous part may no longer
// be written to.
func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) {
	if w.lastpart != nil {
		if err := w.lastpart.close(); err != nil {
			return nil, err
		}
	}
	var b bytes.Buffer
	if w.lastpart != nil {
		fmt.Fprintf(&b, "\r\n--%s\r\n", w.Boundary())
	} else {
		fmt.Fprintf(&b, "--%s\r\n", w.Boundary())
	}
	// TODO(bradfitz): move this to textproto.MimeHeader.Write(w), have it sort
	// and clean, like http.Header.Write(w) does.
	for k, vv := range header {
		for _, v := range vv {
			fmt.Fprintf(&b, "%s: %s\r\n", k, v)
		}
	}
	fmt.Fprintf(&b, "\r\n")
	_, err := io.Copy(w.w, &b)
	if err != nil {
		return nil, err
	}
	p := &part{
		mw: w,
	}
	w.lastpart = p
	return p, nil
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
	return quoteEscaper.Replace(s)
}

// CreateFormFile is a convenience wrapper around CreatePart. It creates
// a new form-data header with the provided field name and file name.
func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
			escapeQuotes(fieldname), escapeQuotes(filename)))
	h.Set("Content-Type", "application/octet-stream")
	return w.CreatePart(h)
}

// CreateFormField calls CreatePart with a header using the
// given field name.
func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"`, escapeQuotes(fieldname)))
	return w.CreatePart(h)
}

// WriteField calls CreateFormField and then writes the given value.
func (w *Writer) WriteField(fieldname, value string) error {
	p, err := w.CreateFormField(fieldname)
	if err != nil {
		return err
	}
	_, err = p.Write([]byte(value))
	return err
}

// Close finishes the multipart message and writes the trailing
// boundary end line to the output.
func (w *Writer) Close() error {
	if w.lastpart != nil {
		if err := w.lastpart.close(); err != nil {
			return err
		}
		w.lastpart = nil
	}
	_, err := fmt.Fprintf(w.w, "\r\n--%s--\r\n", w.Boundary())
	return err
}

type part struct {
	mw     *Writer
	closed bool
	we     error // last error that occurred writing
}

func (p *part) close() error {
	p.closed = true
	return p.we
}

func (p *part) Write(d []byte) (n int, err error) {
	if p.closed {
		return 0, errors.New("multipart: can't write to finished part")
	}
	n, err = p.mw.w.Write(d)
	if err != nil {
		p.we = err
	}
	return
}
<commit_msg>undo CL 95760043 / b2131d729e52<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package multipart

import (
	"bytes"
	"crypto/rand"
	"errors"
	"fmt"
	"io"
	"net/textproto"
	"strings"
)

// A Writer generates multipart messages.
type Writer struct {
	w        io.Writer
	boundary string
	lastpart *part
}

// NewWriter returns a new multipart Writer with a random boundary,
// writing to w.
func NewWriter(w io.Writer) *Writer {
	return &Writer{
		w:        w,
		boundary: randomBoundary(),
	}
}

// Boundary returns the Writer's boundary.
func (w *Writer) Boundary() string {
	return w.boundary
}

// SetBoundary overrides the Writer's default randomly-generated
// boundary separator with an explicit value.
//
// SetBoundary must be called before any parts are created, may only
// contain certain ASCII characters, and must be 1-69 bytes long.
func (w *Writer) SetBoundary(boundary string) error {
	if w.lastpart != nil {
		return errors.New("mime: SetBoundary called after write")
	}
	// rfc2046#section-5.1.1
	if len(boundary) < 1 || len(boundary) > 69 {
		return errors.New("mime: invalid boundary length")
	}
	for _, b := range boundary {
		if 'A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' {
			continue
		}
		switch b {
		case '\'', '(', ')', '+', '_', ',', '-', '.', '/', ':', '=', '?':
			continue
		}
		return errors.New("mime: invalid boundary character")
	}
	w.boundary = boundary
	return nil
}

// FormDataContentType returns the Content-Type for an HTTP
// multipart/form-data with this Writer's Boundary.
func (w *Writer) FormDataContentType() string {
	return "multipart/form-data; boundary=" + w.boundary
}

func randomBoundary() string {
	var buf [30]byte
	_, err := io.ReadFull(rand.Reader, buf[:])
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", buf[:])
}

// CreatePart creates a new multipart section with the provided
// header. The body of the part should be written to the returned
// Writer. After calling CreatePart, any previous part may no longer
// be written to.
func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) {
	if w.lastpart != nil {
		if err := w.lastpart.close(); err != nil {
			return nil, err
		}
	}
	var b bytes.Buffer
	if w.lastpart != nil {
		fmt.Fprintf(&b, "\r\n--%s\r\n", w.boundary)
	} else {
		fmt.Fprintf(&b, "--%s\r\n", w.boundary)
	}
	// TODO(bradfitz): move this to textproto.MimeHeader.Write(w), have it sort
	// and clean, like http.Header.Write(w) does.
	for k, vv := range header {
		for _, v := range vv {
			fmt.Fprintf(&b, "%s: %s\r\n", k, v)
		}
	}
	fmt.Fprintf(&b, "\r\n")
	_, err := io.Copy(w.w, &b)
	if err != nil {
		return nil, err
	}
	p := &part{
		mw: w,
	}
	w.lastpart = p
	return p, nil
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
	return quoteEscaper.Replace(s)
}

// CreateFormFile is a convenience wrapper around CreatePart. It creates
// a new form-data header with the provided field name and file name.
func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
			escapeQuotes(fieldname), escapeQuotes(filename)))
	h.Set("Content-Type", "application/octet-stream")
	return w.CreatePart(h)
}

// CreateFormField calls CreatePart with a header using the
// given field name.
func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"`, escapeQuotes(fieldname)))
	return w.CreatePart(h)
}

// WriteField calls CreateFormField and then writes the given value.
func (w *Writer) WriteField(fieldname, value string) error {
	p, err := w.CreateFormField(fieldname)
	if err != nil {
		return err
	}
	_, err = p.Write([]byte(value))
	return err
}

// Close finishes the multipart message and writes the trailing
// boundary end line to the output.
func (w *Writer) Close() error {
	if w.lastpart != nil {
		if err := w.lastpart.close(); err != nil {
			return err
		}
		w.lastpart = nil
	}
	_, err := fmt.Fprintf(w.w, "\r\n--%s--\r\n", w.boundary)
	return err
}

type part struct {
	mw     *Writer
	closed bool
	we     error // last error that occurred writing
}

func (p *part) close() error {
	p.closed = true
	return p.we
}

func (p *part) Write(d []byte) (n int, err error) {
	if p.closed {
		return 0, errors.New("multipart: can't write to finished part")
	}
	n, err = p.mw.w.Write(d)
	if err != nil {
		p.we = err
	}
	return
}
<|endoftext|>


<commit_before>package protofix

import(
        "fmt"
	"bytes"
	"strings"
	"go/printer"
        "go/parser"
        "go/token"
	"go/ast"
	"io/ioutil"
	"path/filepath"
	"os"
	"os/exec"
)

func FixAllPBGOFilesInDirectory(rootPath string) {

	filepath.Walk(rootPath, func (path string, f os.FileInfo, err error) error {
		if strings.HasSuffix(f.Name(), ".pb.go") {
			fmt.Printf("Repairing %v\n", path)
			repairFile(path)
		}
		return nil
	})

}

func RevertAllPBGOFilesInDirectory(rootPath string) {

	filepath.Walk(rootPath, func (path string, f os.FileInfo, err error) error {
		if f == nil {
			return nil
		}
		if strings.HasSuffix(f.Name(), ".pb.go") {
			fmt.Printf("Reverting %v\n", path)
			args := []string{"checkout", path}
			_, err := exec.Command("git", args... ).Output()
			if err != nil {
				fmt.Printf("Error reverting %v : %v\n", path, err)
				os.Exit(1)
			}
		}
		return nil
	})

}

func repairedFileBytes(filename string) []byte {
	fset := token.NewFileSet()

	f, err := parser.ParseFile(fset, filename, nil, parser.DeclarationErrors)

	if err != nil {
		fmt.Println(err)
		return nil
	}

	n := &lukeNodeWalker{}

	ast.Walk(n, f)

	var buf bytes.Buffer
	printer.Fprint(&buf, fset, f)

	return buf.Bytes()
}

func repairFile(filename string) {
	newFileContents := repairedFileBytes(filename)
	ioutil.WriteFile(filename, newFileContents, 0644)
}

func repairDeclaration(node ast.Node) {
	switch node := node.(type) {
	case *ast.Field:
		if len(node.Names) > 0 {
			declName := node.Names[0].Name
			if strings.HasSuffix(declName, "Id") {
				normalized := strings.TrimSuffix(declName, "Id")
				node.Names[0] = ast.NewIdent(fmt.Sprintf("%vID", normalized))
			}
		}

//	default:
//		fmt.Printf("the type is (%T)\n", node)
	}

}

type lukeNodeWalker struct {
}

func (w *lukeNodeWalker) Visit(node ast.Node) (ast.Visitor) {
	repairDeclaration(node)
	return w
}
<commit_msg>Keep comments when emitting new pb files. Also fix the whitespace so the diffs are nice :-)<commit_after>package protofix

import(
        "fmt"
	"bytes"
	"strings"
	"go/printer"
        "go/parser"
        "go/token"
	"go/ast"
	"io/ioutil"
	"path/filepath"
	"os"
	"os/exec"
)

func FixAllPBGOFilesInDirectory(rootPath string) {

	filepath.Walk(rootPath, func (path string, f os.FileInfo, err error) error {
		if strings.HasSuffix(f.Name(), ".pb.go") {
			fmt.Printf("Repairing %v\n", path)
			repairFile(path)
		}
		return nil
	})

}

func RevertAllPBGOFilesInDirectory(rootPath string) {

	filepath.Walk(rootPath, func (path string, f os.FileInfo, err error) error {
		if f == nil {
			return nil
		}
		if strings.HasSuffix(f.Name(), ".pb.go") {
			fmt.Printf("Reverting %v\n", path)
			args := []string{"checkout", path}
			_, err := exec.Command("git", args... ).Output()
			if err != nil {
				fmt.Printf("Error reverting %v : %v\n", path, err)
				os.Exit(1)
			}
		}
		return nil
	})

}

func repairedFileBytes(filename string) []byte {
	fset := token.NewFileSet()

	f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)

	if err != nil {
		fmt.Println(err)
		return nil
	}

	n := &lukeNodeWalker{}

	ast.Walk(n, f)

	var buf bytes.Buffer

	config := &printer.Config{ Mode: printer.UseSpaces + printer.TabIndent, Tabwidth: 8, Indent: 0}
	config.Fprint(&buf, fset, f)

	return buf.Bytes()
}

func repairFile(filename string) {
	newFileContents := repairedFileBytes(filename)
	ioutil.WriteFile(filename, newFileContents, 0644)
}

func repairDeclaration(node ast.Node) {
	switch node := node.(type) {
	case *ast.Field:
		if len(node.Names) > 0 {
			declName := node.Names[0].Name
			if strings.HasSuffix(declName, "Id") {
				normalized := strings.TrimSuffix(declName, "Id")
				node.Names[0] = ast.NewIdent(fmt.Sprintf("%vID", normalized))
			}
		}

//	default:
//		fmt.Printf("the type is (%T)\n", node)
	}

}

type lukeNodeWalker struct {
}

func (w *lukeNodeWalker) Visit(node ast.Node) (ast.Visitor) {
	repairDeclaration(node)
	return w
}
<|endoftext|>


<commit_before>package filters

import (
	"encoding/json"
	"fmt"
	"github.com/abesto/easyssh/from_sexp"
	"github.com/abesto/easyssh/interfaces"
	"github.com/abesto/easyssh/target"
	"github.com/abesto/easyssh/util"
	"os/exec"
	"regexp"
)

func Make(input string) interfaces.TargetFilter {
	return from_sexp.MakeFromString(input, nil, makeByName).(interfaces.TargetFilter)
}

func SupportedFilterNames() []string {
	var keys = make([]string, len(filterMakerMap))
	var i = 0
	for key := range filterMakerMap {
		keys[i] = key
		i += 1
	}
	return keys
}

func makeFromSExp(data []interface{}) interfaces.TargetFilter {
	return from_sexp.Make(data, nil, makeByName).(interfaces.TargetFilter)
}

const (
	nameEc2InstanceId = "ec2-instance-id"
	nameList          = "list"
	nameId            = "id"
	nameFirst         = "first"
)

var filterMakerMap = map[string]func() interfaces.TargetFilter{
	nameEc2InstanceId: func() interfaces.TargetFilter { return &ec2InstanceIdLookup{} },
	nameList:          func() interfaces.TargetFilter { return &list{} },
	nameId:            func() interfaces.TargetFilter { return &id{} },
	nameFirst:         func() interfaces.TargetFilter { return &first{} },
}

func makeByName(name string) interface{} {
	var d interfaces.TargetFilter
	for key, maker := range filterMakerMap {
		if key == name {
			d = maker()
		}
	}
	if d == nil {
		util.Abort("filter \"%s\" is not known", name)
	}
	return d
}

type ec2InstanceIdLookup struct {
	region string
}

func (f *ec2InstanceIdLookup) Filter(targets []target.Target) []target.Target {
	if f.region == "" {
		util.Abort("ec2-instance-id requires exactly one argument, the region name to use for looking up instances")
	}
	var re = regexp.MustCompile("i-[0-9a-f]{8}")
	for idx, t := range targets {
		var instanceId = re.FindString(t.Host)
		if len(instanceId) > 0 {
			var cmd = exec.Command("aws", "ec2", "describe-instances", "--instance-id", instanceId, "--region", f.region)
			util.Logger.Infof("EC2 Instance lookup: %s", cmd.Args)
			var output, _ = cmd.Output()
			var data map[string]interface{}
			json.Unmarshal(output, &data)

			var reservations = data["Reservations"]
			if reservations == nil {
				util.Logger.Infof("EC2 instance lookup failed for %s (%s) in region %s", t.Host, instanceId, f.region)
				continue
			}
			targets[idx].Host = reservations.([]interface{})[0].(map[string]interface{})["Instances"].([]interface{})[0].(map[string]interface{})["PublicIpAddress"].(string)
		} else {
			util.Logger.Debugf("Target %s looks like it doesn't have EC2 instance ID, skipping lookup for region %s", t, f.region)
		}
	}
	return targets
}
func (f *ec2InstanceIdLookup) SetArgs(args []interface{}) {
	if len(args) != 1 {
		util.Abort("ec2-instance-id requires exactly one argument, the region name to use for looking up instances")
	}
	f.region = string(args[0].([]byte))
}
func (f *ec2InstanceIdLookup) String() string {
	return fmt.Sprintf("<%s %s>", nameEc2InstanceId, f.region)
}

type list struct {
	children []interfaces.TargetFilter
}

func (f *list) Filter(targets []target.Target) []target.Target {
	for _, child := range f.children {
		targets = child.Filter(targets)
		util.Logger.Debugf("Targets after filter %s: %s", child, targets)
	}
	return targets
}
func (f *list) SetArgs(args []interface{}) {
	for _, def := range args {
		f.children = append(f.children, makeFromSExp(def.([]interface{})))
	}
}
func (f *list) String() string {
	return fmt.Sprintf("<%s %s>", nameList, f.children)
}

type id struct{}

func (f *id) Filter(targets []target.Target) []target.Target {
	return targets
}
func (f *id) SetArgs(args []interface{}) {
	util.RequireNoArguments(f, args)
}
func (f *id) String() string {
	return fmt.Sprintf("<%s>", nameId)
}

type first struct{}

func (f *first) Filter(targets []target.Target) []target.Target {
	if len(targets) > 0 {
		return targets[1:]
	}
	return targets
}
func (f *first) SetArgs(args []interface{}) {
	util.RequireNoArguments(f, args)
}
func (f *first) String() string {
	return fmt.Sprintf("<%s>", nameFirst)
}
<commit_msg>Fix (first) filter<commit_after>package filters

import (
	"encoding/json"
	"fmt"
	"github.com/abesto/easyssh/from_sexp"
	"github.com/abesto/easyssh/interfaces"
	"github.com/abesto/easyssh/target"
	"github.com/abesto/easyssh/util"
	"os/exec"
	"regexp"
)

func Make(input string) interfaces.TargetFilter {
	return from_sexp.MakeFromString(input, nil, makeByName).(interfaces.TargetFilter)
}

func SupportedFilterNames() []string {
	var keys = make([]string, len(filterMakerMap))
	var i = 0
	for key := range filterMakerMap {
		keys[i] = key
		i += 1
	}
	return keys
}

func makeFromSExp(data []interface{}) interfaces.TargetFilter {
	return from_sexp.Make(data, nil, makeByName).(interfaces.TargetFilter)
}

const (
	nameEc2InstanceId = "ec2-instance-id"
	nameList          = "list"
	nameId            = "id"
	nameFirst         = "first"
)

var filterMakerMap = map[string]func() interfaces.TargetFilter{
	nameEc2InstanceId: func() interfaces.TargetFilter { return &ec2InstanceIdLookup{} },
	nameList:          func() interfaces.TargetFilter { return &list{} },
	nameId:            func() interfaces.TargetFilter { return &id{} },
	nameFirst:         func() interfaces.TargetFilter { return &first{} },
}

func makeByName(name string) interface{} {
	var d interfaces.TargetFilter
	for key, maker := range filterMakerMap {
		if key == name {
			d = maker()
		}
	}
	if d == nil {
		util.Abort("filter \"%s\" is not known", name)
	}
	return d
}

type ec2InstanceIdLookup struct {
	region string
}

func (f *ec2InstanceIdLookup) Filter(targets []target.Target) []target.Target {
	if f.region == "" {
		util.Abort("ec2-instance-id requires exactly one argument, the region name to use for looking up instances")
	}
	var re = regexp.MustCompile("i-[0-9a-f]{8}")
	for idx, t := range targets {
		var instanceId = re.FindString(t.Host)
		if len(instanceId) > 0 {
			var cmd = exec.Command("aws", "ec2", "describe-instances", "--instance-id", instanceId, "--region", f.region)
			util.Logger.Infof("EC2 Instance lookup: %s", cmd.Args)
			var output, _ = cmd.Output()
			var data map[string]interface{}
			json.Unmarshal(output, &data)

			var reservations = data["Reservations"]
			if reservations == nil {
				util.Logger.Infof("EC2 instance lookup failed for %s (%s) in region %s", t.Host, instanceId, f.region)
				continue
			}
			targets[idx].Host = reservations.([]interface{})[0].(map[string]interface{})["Instances"].([]interface{})[0].(map[string]interface{})["PublicIpAddress"].(string)
		} else {
			util.Logger.Debugf("Target %s looks like it doesn't have EC2 instance ID, skipping lookup for region %s", t, f.region)
		}
	}
	return targets
}
func (f *ec2InstanceIdLookup) SetArgs(args []interface{}) {
	if len(args) != 1 {
		util.Abort("ec2-instance-id requires exactly one argument, the region name to use for looking up instances")
	}
	f.region = string(args[0].([]byte))
}
func (f *ec2InstanceIdLookup) String() string {
	return fmt.Sprintf("<%s %s>", nameEc2InstanceId, f.region)
}

type list struct {
	children []interfaces.TargetFilter
}

func (f *list) Filter(targets []target.Target) []target.Target {
	for _, child := range f.children {
		targets = child.Filter(targets)
		util.Logger.Debugf("Targets after filter %s: %s", child, targets)
	}
	return targets
}
func (f *list) SetArgs(args []interface{}) {
	for _, def := range args {
		f.children = append(f.children, makeFromSExp(def.([]interface{})))
	}
}
func (f *list) String() string {
	return fmt.Sprintf("<%s %s>", nameList, f.children)
}

type id struct{}

func (f *id) Filter(targets []target.Target) []target.Target {
	return targets
}
func (f *id) SetArgs(args []interface{}) {
	util.RequireNoArguments(f, args)
}
func (f *id) String() string {
	return fmt.Sprintf("<%s>", nameId)
}

type first struct{}

func (f *first) Filter(targets []target.Target) []target.Target {
	if len(targets) > 0 {
		return targets[0:1]
	}
	return targets
}
func (f *first) SetArgs(args []interface{}) {
	util.RequireNoArguments(f, args)
}
func (f *first) String() string {
	return fmt.Sprintf("<%s>", nameFirst)
}
<|endoftext|>


<commit_before>package yara

/*
#include <stdio.h>
#include <yara.h>
#include "cgoyara.h"
*/
import "C"

import (
	"fmt"
	"log"
	"unsafe"
)

func init() {
	code := C.yr_initialize()
	if code != C.ERROR_SUCCESS {
		log.Fatalf("failed to initialize libyara!")
	}
}

func Finalize() error {
	code := C.yr_finalize()
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func newError(code C.int) error {
	return fmt.Errorf("libyara: %d", code)
}

type Compiler struct {
	handle *C.YR_COMPILER
}

func NewCompiler() (*Compiler, error) {
	var handle *C.YR_COMPILER
	code := C.yr_compiler_create(&handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Compiler{handle}, nil
}

func (c *Compiler) Destroy() {
	C.yr_compiler_destroy(c.handle)
}

func (c *Compiler) AddFile(ns, path string) error {
	cpath := C.CString(path)
	cmode := C.CString("r")
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(cpath))
	defer C.free(unsafe.Pointer(cmode))
	defer C.free(unsafe.Pointer(cns))

	fd := C.fopen(cpath, cmode)
	if fd == nil {
		return fmt.Errorf("libyara: failed to open %q", path)
	}

	defer C.fclose(fd)

	errors := C.yr_compiler_add_file(c.handle, fd, nil, cpath)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile %q", path)
	}

	return nil
}

func (c *Compiler) AddString(ns, rule string) error {
	crule := C.CString(rule)
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(crule))
	defer C.free(unsafe.Pointer(cns))

	errors := C.yr_compiler_add_string(c.handle, crule, cns)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile rule")
	}

	return nil
}

func (c *Compiler) Rules() (*Rules, error) {
	var handle *C.YR_RULES
	code := C.yr_compiler_get_rules(c.handle, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Rules{handle}, nil
}

type Rules struct {
	handle *C.YR_RULES
}

func LoadFromFile(path string) (*Rules, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	var handle *C.YR_RULES
	code := C.yr_rules_load(cpath, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Rules{handle}, nil
}

func (r *Rules) Save(path string) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	code := C.yr_rules_save(r.handle, cpath)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func (r *Rules) ScanMemory(buffer []byte, fn Callback) error {
	data := (*C.uint8_t)(unsafe.Pointer(&buffer[0]))
	size := C.size_t(len(buffer))
	code := C.yr_rules_scan_mem(r.handle, data, size, 0, callback, unsafe.Pointer(&fn), 0)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func (r *Rules) ScanFile(path string, fn Callback) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	code := C.yr_rules_scan_file(r.handle, cpath, 0, callback, unsafe.Pointer(&fn), 0)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

type Rule struct {
	Identifier string
	Tags       []string
	Metadata   map[string]string
}

func NewRule() *Rule {
	return &Rule{
		Metadata: make(map[string]string),
	}
}

type Callback func(rule *Rule)
<commit_msg>added destroy fn for rules<commit_after>package yara

/*
#include <stdio.h>
#include <yara.h>
#include "cgoyara.h"
*/
import "C"

import (
	"fmt"
	"log"
	"unsafe"
)

func init() {
	code := C.yr_initialize()
	if code != C.ERROR_SUCCESS {
		log.Fatalf("failed to initialize libyara!")
	}
}

func Finalize() error {
	code := C.yr_finalize()
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func newError(code C.int) error {
	return fmt.Errorf("libyara: %d", code)
}

type Compiler struct {
	handle *C.YR_COMPILER
}

func NewCompiler() (*Compiler, error) {
	var handle *C.YR_COMPILER
	code := C.yr_compiler_create(&handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Compiler{handle}, nil
}

func (c *Compiler) Destroy() {
	C.yr_compiler_destroy(c.handle)
}

func (c *Compiler) AddFile(ns, path string) error {
	cpath := C.CString(path)
	cmode := C.CString("r")
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(cpath))
	defer C.free(unsafe.Pointer(cmode))
	defer C.free(unsafe.Pointer(cns))

	fd := C.fopen(cpath, cmode)
	if fd == nil {
		return fmt.Errorf("libyara: failed to open %q", path)
	}

	defer C.fclose(fd)

	errors := C.yr_compiler_add_file(c.handle, fd, nil, cpath)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile %q", path)
	}

	return nil
}

func (c *Compiler) AddString(ns, rule string) error {
	crule := C.CString(rule)
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(crule))
	defer C.free(unsafe.Pointer(cns))

	errors := C.yr_compiler_add_string(c.handle, crule, cns)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile rule")
	}

	return nil
}

func (c *Compiler) Rules() (*Rules, error) {
	var handle *C.YR_RULES
	code := C.yr_compiler_get_rules(c.handle, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Rules{handle}, nil
}

type Rules struct {
	handle *C.YR_RULES
}

func LoadFromFile(path string) (*Rules, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	var handle *C.YR_RULES
	code := C.yr_rules_load(cpath, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, newError(code)
	}

	return &Rules{handle}, nil
}

func (r *Rules) Destroy() {
	C.yr_rules_destroy(r.handle)
}

func (r *Rules) Save(path string) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	code := C.yr_rules_save(r.handle, cpath)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func (r *Rules) ScanMemory(buffer []byte, fn Callback) error {
	data := (*C.uint8_t)(unsafe.Pointer(&buffer[0]))
	size := C.size_t(len(buffer))
	code := C.yr_rules_scan_mem(r.handle, data, size, 0, callback, unsafe.Pointer(&fn), 0)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

func (r *Rules) ScanFile(path string, fn Callback) error {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	code := C.yr_rules_scan_file(r.handle, cpath, 0, callback, unsafe.Pointer(&fn), 0)
	if code != C.ERROR_SUCCESS {
		return newError(code)
	}

	return nil
}

type Rule struct {
	Identifier string
	Tags       []string
	Metadata   map[string]string
}

func NewRule() *Rule {
	return &Rule{
		Metadata: make(map[string]string),
	}
}

type Callback func(rule *Rule)
<|endoftext|>


<commit_before>package utils

import (
	"reflect"
	"testing"
)

func TestDomainCreation(t *testing.T) {
	var tests = map[string]string{
		"foo":           "foo",
		"foo.":          "foo",
		".foo.docker.":  "foo.docker",
		".foo..docker.": "foo.docker",
		"foo.docker..":  "foo.docker",
	}

	for input, expected := range tests {
		t.Log(input)
		d := NewDomain(input)
		if actual := d.String(); actual != expected {
			t.Error(input, "Expected:", expected, "Got:", actual)
		}
	}
	input := "127.0.0.1,127.0.0.2"
	expected := nameservers{input}
	if actual := []string{"127.0.0.1", "127.0.0.2"}; reflect.DeepEqual(actual, expected) {
		t.Error(input, "Expected:", expected, "Got:", actual)
	}
}

func TestNewConfig(t *testing.T){
	config := NewConfig()
	if !reflect.DeepEqual(config.DnsAddr,":53") {
		t.Error("DnsAddr error")
	}
}
<commit_msg>style: fix<commit_after>package utils

import (
	"reflect"
	"testing"
)

func TestDomainCreation(t *testing.T) {
	var tests = map[string]string{
		"foo":           "foo",
		"foo.":          "foo",
		".foo.docker.":  "foo.docker",
		".foo..docker.": "foo.docker",
		"foo.docker..":  "foo.docker",
	}

	for input, expected := range tests {
		t.Log(input)
		d := NewDomain(input)
		if actual := d.String(); actual != expected {
			t.Error(input, "Expected:", expected, "Got:", actual)
		}
	}
	input := "127.0.0.1,127.0.0.2"
	expected := nameservers{input}
	if actual := []string{"127.0.0.1", "127.0.0.2"}; reflect.DeepEqual(actual, expected) {
		t.Error(input, "Expected:", expected, "Got:", actual)
	}
}

func TestNewConfig(t *testing.T) {
	config := NewConfig()
	if !reflect.DeepEqual(config.DnsAddr, ":53") {
		t.Error("DnsAddr error")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"github.com/google/go-cmp/cmp"
	"github.com/google/gonids"
	"log"
	"os"
)

func commentFail(r *gonids.Rule) bool {
	if r.SID == 0 && r.Revision == 0 && r.Description == "" {
		return true
	}
	return false
}

func main() {
	test := "/home/duane/Downloads/rules/emerging-trojan.rules"
	s1 := []byte(`Content-Disposition`)
	var b1 byte = 0x3a
	s2 := []byte(` form-data`)
	var b2 byte = 0x3b
	s3 := []byte(`name=`)
	var b3 byte = 0x22
	s4 := []byte(` file`)
	b4 := []byte{0x22, 0x3b}
	s5 := []byte(`filename=`)
	var b5 byte = 0x22
	s6 := []byte(`C`)
	var b6 byte = 0x3a
	s7 := []byte(`\`)
	bslice := append(s1, b1)
	bslice = append(bslice, s2...)
	bslice = append(bslice, b2)
	bslice = append(bslice, s3...)
	bslice = append(bslice, b3)
	bslice = append(bslice, s4...)
	bslice = append(bslice, b4...)
	bslice = append(bslice, s5...)
	bslice = append(bslice, b5)
	bslice = append(bslice, s6...)
	bslice = append(bslice, b6)
	bslice = append(bslice, s7...)

	fmt.Println(fmt.Sprintf("% 02x ", bslice))
	return
	fmt.Println(fmt.Sprintf("reading from: %s", test))
	file, err := os.Open(test)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	good := 0
	bad := 0
	for scanner.Scan() {
		t := scanner.Text()
		r1, err := gonids.ParseRule(t)
		if err != nil {
			fmt.Println(fmt.Sprintf("error parsing: %v", err))
			continue
		}
		if commentFail(r1) {
			// fmt.Println(fmt.Sprintf("%v", t))
			continue
		}

		r2, err := gonids.ParseRule(r1.String())
		if err != nil {
			fmt.Println(fmt.Sprintf("fail to parse rule2.\n%s", t))
			bad++
			continue
		}

		if !cmp.Equal(r1, r2) {
			fmt.Println(fmt.Sprintf("failed on:\n%s", r1))
			bad++
			continue
		}
		good++
	}
	fmt.Println(fmt.Sprintf("good:%d\nbad: %d", good, bad))

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

}
<commit_msg>this hack shouldn't be commited<commit_after><|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"strconv"
	"testing"

	elektra "go.libelektra.org/kdb"
)

func stringReader(body string) []byte {
	return []byte(body)
}

func jsonReader(body interface{}) []byte {
	b, err := json.Marshal(body)

	if err != nil {
		panic("could not marshal json")
	}

	return b
}

func Benchmark(b *testing.B) {
	s := testServer(b)
	defer s.Close()

	world := "world"

	benchmarks := []struct {
		verb   string
		path   string
		bodyv1 []byte
		bodyv2 []byte
	}{
		{verb: "GET", path: "/version"},
		{verb: "GET", path: "/kdb/user/tests/go/elektrad/benchmark/dataset"},
		{verb: "GET", path: "/kdbFind/user/tests/go/elektrad/benchmark/dataset/001"},
		{verb: "POST", path: "/kdbMv/user/tests/go/elektrad/benchmark/temp/from", bodyv1: stringReader("user/tests/go/elektrad/benchmark/temp/to"), bodyv2: jsonReader("user/tests/go/elektrad/benchmark/temp/to")},
		{verb: "PUT", path: "/kdb/user/tests/go/elektrad/benchmark/temp/to/001", bodyv1: stringReader("value"), bodyv2: jsonReader("value")},
		{verb: "POST", path: "/kdbMeta/user/tests/go/elektrad/benchmark/temp/from/001", bodyv1: jsonReader(keyValueBody{Key: "hello", Value: &world}), bodyv2: jsonReader(keyValueBody{Key: "hello", Value: &world})},
		// {verb: "DELETE", path: "/kdb/user/tests/go/elektrad/benchmark/temp/from/001", bodyv1: stringReader("value"), bodyv2: jsonReader("value")},
	}

	resetKdb := prepareBenchmark(b, 1000)

	for _, bt := range benchmarks {
		run := func(b *testing.B, url string, v2 bool) {
			b.StopTimer()

			body := bt.bodyv1

			if v2 {
				body = bt.bodyv2
			}

			r := benchRequest(b, bt.verb, url, bt.path, body)

			for n := 0; n < b.N; n++ {
				if bt.verb != "GET" {
					resetKdb()
				}

				b.StartTimer()
				resp, err := http.DefaultClient.Do(r)
				b.StopTimer()

				body, _ := ioutil.ReadAll(resp.Body)

				Assertf(b, resp.StatusCode >= 200 && resp.StatusCode < 300, "unexpected status code: %d, %s", resp.StatusCode, body)

				Check(b, err, "request failed")

				defer resp.Body.Close()
			}
		}

		b.Run(fmt.Sprintf("%s%s", bt.verb, bt.path), func(b *testing.B) {
			b.Run("v1", func(b *testing.B) {
				run(b, "http://localhost:33333", false)
			})

			b.Run("v2", func(b *testing.B) {
				run(b, s.URL, true)
			})
		})
	}
}

func getTestHandle(t testing.TB) elektra.KDB {
	handle := elektra.New()
	err := handle.Open()

	if err != nil {
		t.Fatal(err)
	}

	return handle
}

func testServer(t testing.TB) *httptest.Server {
	t.Helper()

	router := setupRouter()

	ts := httptest.NewServer(router)

	return ts
}

func benchRequest(b *testing.B, verb, url, path string, body []byte) *http.Request {
	b.Helper()

	r, err := http.NewRequest(verb, url+path, bytes.NewBuffer(body))

	// the old javascript server needs this to work
	r.Header.Add("Content-Type", "application/json")
	r.Header.Add("Content-Length", strconv.Itoa(len(body)))

	Check(b, err, "error creating request")

	return r
}

func prepareBenchmark(b testing.TB, dataSize int) func() {
	b.Helper()

	namespace := "user/tests/go/elektrad/benchmark"
	data := namespace + "/dataset"
	temp := namespace + "/temp"
	tempFrom := temp + "/from"
	tempTo := temp + "/to"

	handle := getTestHandle(b)

	ks := elektra.NewKeySet()

	parentKey, err := elektra.NewKey(namespace)
	Check(b, err, "could not create parent key")

	clear := func(keyName string) {
		key, err := elektra.NewKey(keyName)
		Check(b, err, "could not create clear key")

		ks.Cut(key)
	}

	get := func() {
		_, err = handle.Get(ks, parentKey)
		Check(b, err, "could not get test dataset")
	}

	persist := func() {
		_, err = handle.Set(ks, parentKey)
		Check(b, err, "could not create test dataset")
	}

	create := func(keyName string) {
		doesExist := ks.LookupByName(keyName + "/001")

		if doesExist != nil {
			return
		}

		for n := 0; n < dataSize; n++ {
			k, err := elektra.NewKey(fmt.Sprintf(keyName+"/%03d", n))

			Check(b, err, "could not create data key")

			ks.AppendKey(k)
		}
	}

	get()
	clear(data)
	create(data)
	create(tempFrom)
	persist()

	return func() {
		get()
		clear(tempTo)
		create(tempFrom)
		persist()
	}
}
<commit_msg>elektrad: all benchmark tests are green now<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"

	elektra "go.libelektra.org/kdb"
)

func Benchmark(b *testing.B) {
	s := testServer(b)
	defer s.Close()

	world := "world"

	benchmarks := []struct {
		verb string
		path string
		body interface{}
	}{
		{verb: "GET", path: "/version"},
		{verb: "GET", path: "/kdb/user/tests/go/elektrad/benchmark/dataset"},
		{verb: "GET", path: "/kdbFind/user/tests/go/elektrad/benchmark/dataset/001"},
		{verb: "POST", path: "/kdbMv/user/tests/go/elektrad/benchmark/temp/from", body: "user/tests/go/elektrad/benchmark/temp/to"},
		{verb: "PUT", path: "/kdb/user/tests/go/elektrad/benchmark/temp/to/001", body: "value"},
		{verb: "POST", path: "/kdbMeta/user/tests/go/elektrad/benchmark/temp/from/001", body: keyValueBody{Key: "hello", Value: &world}},
		{verb: "DELETE", path: "/kdb/user/tests/go/elektrad/benchmark/temp/from/001", body: "value"},
	}

	resetKdb := prepareBenchmark(b, 1000)

	for _, bt := range benchmarks {
		run := func(b *testing.B, url string, v2 bool) {

			r := benchRequest(b, bt.verb, url, bt.path, bt.body, v2)

			b.StopTimer()
			b.ResetTimer()

			for n := 0; n < b.N; n++ {
				if bt.verb != "GET" {
					resetKdb()
				}

				b.StartTimer()
				resp, err := http.DefaultClient.Do(r)
				b.StopTimer()

				body, _ := ioutil.ReadAll(resp.Body)

				Assertf(b, resp.StatusCode >= 200 && resp.StatusCode < 300, "unexpected status code: %d, %s", resp.StatusCode, body)

				Check(b, err, "request failed")

				resp.Body.Close()
			}
		}

		b.Run(fmt.Sprintf("%s%s", bt.verb, bt.path), func(b *testing.B) {
			b.Run("v1", func(b *testing.B) {
				run(b, "http://localhost:33333", false)
			})

			b.Run("v2", func(b *testing.B) {
				run(b, s.URL, true)
			})
		})
	}
}

func stringReader(body string) io.Reader {
	return bytes.NewBuffer([]byte(body))
}

func jsonReader(body interface{}) io.Reader {
	b, err := json.Marshal(body)

	if err != nil {
		panic("could not marshal json")
	}

	return bytes.NewBuffer(b)
}

func getTestHandle(t testing.TB) elektra.KDB {
	handle := elektra.New()
	err := handle.Open()

	if err != nil {
		t.Fatal(err)
	}

	return handle
}

func testServer(t testing.TB) *httptest.Server {
	t.Helper()

	router := setupRouter()

	ts := httptest.NewServer(router)

	return ts
}

func benchRequest(b *testing.B, verb, url, path string, body interface{}, v2 bool) *http.Request {
	b.Helper()

	contentType := "application/json"
	var bodyReader io.Reader

	if body != nil {
		switch b := body.(type) {
		case string:
			if v2 {
				bodyReader = jsonReader(body)
			} else {
				// the old elektra doesn't like JSON strings in the body
				contentType = "text/plain"
				bodyReader = stringReader(b)
			}
		default:
			bodyReader = jsonReader(body)
		}
	}

	r, err := http.NewRequest(verb, url+path, bodyReader)

	r.Header.Add("Content-Type", contentType)

	Check(b, err, "error creating request")

	return r
}

func prepareBenchmark(b testing.TB, dataSize int) func() {
	b.Helper()

	namespace := "user/tests/go/elektrad/benchmark"
	data := namespace + "/dataset"
	temp := namespace + "/temp"
	tempFrom := temp + "/from"
	tempTo := temp + "/to"

	handle := getTestHandle(b)

	ks := elektra.NewKeySet()

	parentKey, err := elektra.NewKey(namespace)
	Check(b, err, "could not create parent key")

	clear := func(keyName string) {
		key, err := elektra.NewKey(keyName)
		Check(b, err, "could not create clear key")

		ks.Cut(key)
	}

	get := func() {
		_, err = handle.Get(ks, parentKey)
		Check(b, err, "could not get test dataset")
	}

	persist := func() {
		_, err = handle.Set(ks, parentKey)
		Check(b, err, "could not create test dataset")
	}

	create := func(keyName string) {
		doesExist := ks.LookupByName(keyName + "/001")

		if doesExist != nil {
			return
		}

		for n := 0; n < dataSize; n++ {
			k, err := elektra.NewKey(fmt.Sprintf(keyName+"/%03d", n))

			Check(b, err, "could not create data key")

			ks.AppendKey(k)
		}
	}

	get()
	clear(data)
	create(data)
	create(tempFrom)
	persist()

	return func() {
		get()
		clear(tempTo)
		create(tempFrom)
		persist()
	}
}
<|endoftext|>


<commit_before>package main

// go generate script for generating mocks for all interfaces
// Uses mockery (https://github.com/vektra/mockery) to generate the actual mocks.
// Install mockery using 'go get github.com/vektra/mockery/.../'

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
)

func main() {
	directories, err := glideNoVendor()
	if err != nil {
		os.Stderr.WriteString(fmt.Sprintf("Could not run 'glide nv': %s\n", err))
		os.Exit(1)
	}

	var wg sync.WaitGroup
	wg.Add(len(directories))
	for _, d := range directories {
		dir := d
		go func() {
			defer wg.Done()
			fmt.Printf("Generating mocks for '%s'...\n", dir)
			err = generateMocks(dir)
			if err != nil {
				os.Stderr.WriteString(fmt.Sprintf("Could not generate mocks for directory '%s': %s\n", dir, err))
				os.Exit(2)
			}
		}()
	}
	wg.Wait()
}

func glideNoVendor() ([]string, error) {
	cmd := exec.Command("glide", "nv")
	bytes, err := cmd.Output()
	if err != nil {
		return nil, err
	}

	lines := strings.Split(string(bytes), "\n")
	filtered := make([]string, 0, len(lines))
	for _, l := range lines {
		line := strings.TrimSuffix(l, "...")
		if line != "" && line != "." && line != "./mocks/" {
			filtered = append(filtered, line)
		}
	}
	return filtered, err
}

func generateMocks(dir string) error {
	args := []string{"-dir", dir, "-recursive", "-all", "-inpkg"}
	cmd := exec.Command("mockery", args...)
	return cmd.Run()
}
<commit_msg>Be verbose during generating mocks<commit_after>package main

// go generate script for generating mocks for all interfaces
// Uses mockery (https://github.com/vektra/mockery) to generate the actual mocks.
// Install mockery using 'go get github.com/vektra/mockery/.../'

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
)

func main() {
	directories, err := glideNoVendor()
	if err != nil {
		os.Stderr.WriteString(fmt.Sprintf("Could not run 'glide nv': %s\n", err))
		os.Exit(1)
	}

	var wg sync.WaitGroup
	wg.Add(len(directories))
	for _, d := range directories {
		dir := d
		go func() {
			defer wg.Done()
			fmt.Printf("Generating mocks for '%s'...\n", dir)
			err = generateMocks(dir)
			if err != nil {
				os.Stderr.WriteString(fmt.Sprintf("Could not generate mocks for directory '%s': %s\n", dir, err))
				os.Exit(2)
			}
		}()
	}
	wg.Wait()
}

func glideNoVendor() ([]string, error) {
	cmd := exec.Command("glide", "nv")
	bytes, err := cmd.Output()
	if err != nil {
		return nil, err
	}

	lines := strings.Split(string(bytes), "\n")
	filtered := make([]string, 0, len(lines))
	for _, l := range lines {
		line := strings.TrimSuffix(l, "...")
		if line != "" && line != "." && line != "./mocks/" {
			filtered = append(filtered, line)
		}
	}
	return filtered, err
}

func generateMocks(dir string) error {
	args := []string{"-dir", dir, "-recursive", "-all", "-inpkg"}
	cmd := exec.Command("mockery", args...)
	buf, err := cmd.CombinedOutput()
	fmt.Println(string(buf))
	return err
}
<|endoftext|>