<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"strings"

	"github.com/docker/docker/pkg/integration/checker"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/go-check/check"
)

func (s *DockerSuite) TestApiNetworkGetDefaults(c *check.C) {
	// By default docker daemon creates 3 networks. check if they are present
	defaults := []string{"bridge", "host", "none"}
	for _, nn := range defaults {
		c.Assert(isNetworkAvailable(c, nn), checker.Equals, true)
	}
}

func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) {
	// Create a network
	name := "testnetwork"
	config := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	id := createNetwork(c, config, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)

	// delete the network and make sure it is deleted
	deleteNetwork(c, id, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, false)
}

func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) {
	name := "testcheckduplicate"
	configOnCheck := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	configNotCheck := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: false,
	}

	// Creating a new network first
	createNetwork(c, configOnCheck, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)

	// Creating another network with same name and CheckDuplicate must fail
	createNetwork(c, configOnCheck, false)

	// Creating another network with same name and not CheckDuplicate must succeed
	createNetwork(c, configNotCheck, true)
}

func (s *DockerSuite) TestApiNetworkFilter(c *check.C) {
	nr := getNetworkResource(c, getNetworkIDByName(c, "bridge"))
	c.Assert(nr.Name, checker.Equals, "bridge")
}

func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
	// Inspect default bridge network
	nr := getNetworkResource(c, "bridge")
	c.Assert(nr.Name, checker.Equals, "bridge")

	// run a container and attach it to the default bridge network
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)
	containerIP := findContainerIP(c, "test", "bridge")

	// inspect default bridge network again and make sure the container is connected
	nr = getNetworkResource(c, nr.ID)
	c.Assert(nr.Driver, checker.Equals, "bridge")
	c.Assert(nr.Scope, checker.Equals, "local")
	c.Assert(nr.IPAM.Driver, checker.Equals, "default")
	c.Assert(len(nr.Containers), checker.Equals, 1)
	c.Assert(nr.Containers[containerID], checker.NotNil)

	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	c.Assert(err, checker.IsNil)
	c.Assert(ip.String(), checker.Equals, containerIP)

	// IPAM configuration inspect
	ipam := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
	}
	config := types.NetworkCreate{
		Name:    "br0",
		Driver:  "bridge",
		IPAM:    ipam,
		Options: map[string]string{"foo": "bar", "opts": "dopts"},
	}
	id0 := createNetwork(c, config, true)
	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)

	nr = getNetworkResource(c, id0)
	c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
	c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
	c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
	c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254")
	c.Assert(nr.Options["foo"], checker.Equals, "bar")
	c.Assert(nr.Options["opts"], checker.Equals, "dopts")

	// delete the network and make sure it is deleted
	deleteNetwork(c, id0, true)
	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, false)
}

func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
	// Create test network
	name := "testnetwork"
	config := types.NetworkCreate{
		Name: name,
	}
	id := createNetwork(c, config, true)
	nr := getNetworkResource(c, id)
	c.Assert(nr.Name, checker.Equals, name)
	c.Assert(nr.ID, checker.Equals, id)
	c.Assert(len(nr.Containers), checker.Equals, 0)

	// run a container
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)

	// connect the container to the test network
	connectNetwork(c, nr.ID, containerID)

	// inspect the network to make sure container is connected
	nr = getNetworkResource(c, nr.ID)
	c.Assert(len(nr.Containers), checker.Equals, 1)
	c.Assert(nr.Containers[containerID], checker.NotNil)

	// check if container IP matches network inspect
	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	c.Assert(err, checker.IsNil)
	containerIP := findContainerIP(c, "test", "testnetwork")
	c.Assert(ip.String(), checker.Equals, containerIP)

	// disconnect container from the network
	disconnectNetwork(c, nr.ID, containerID)
	nr = getNetworkResource(c, nr.ID)
	c.Assert(nr.Name, checker.Equals, name)
	c.Assert(len(nr.Containers), checker.Equals, 0)

	// delete the network
	deleteNetwork(c, nr.ID, true)
}

func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
	// test0 bridge network
	ipam0 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
	}
	config0 := types.NetworkCreate{
		Name:   "test0",
		Driver: "bridge",
		IPAM:   ipam0,
	}
	id0 := createNetwork(c, config0, true)
	c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true)

	ipam1 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
	}
	// test1 bridge network overlaps with test0
	config1 := types.NetworkCreate{
		Name:   "test1",
		Driver: "bridge",
		IPAM:   ipam1,
	}
	createNetwork(c, config1, false)
	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false)

	ipam2 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
	}
	// test2 bridge network does not overlap
	config2 := types.NetworkCreate{
		Name:   "test2",
		Driver: "bridge",
		IPAM:   ipam2,
	}
	createNetwork(c, config2, true)
	c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true)

	// remove test0 and retry to create test1
	deleteNetwork(c, id0, true)
	createNetwork(c, config1, true)
	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)

	// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
	createNetwork(c, types.NetworkCreate{Name: "test3"}, true)
	c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true)
	createNetwork(c, types.NetworkCreate{Name: "test4"}, true)
	c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true)
	createNetwork(c, types.NetworkCreate{Name: "test5"}, true)
	c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)

	for i := 1; i < 6; i++ {
		deleteNetwork(c, fmt.Sprintf("test%d", i), true)
	}
}

func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
	createDeletePredefinedNetwork(c, "bridge")
	createDeletePredefinedNetwork(c, "none")
	createDeletePredefinedNetwork(c, "host")
}

func createDeletePredefinedNetwork(c *check.C, name string) {
	// Create pre-defined network
	config := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	shouldSucceed := false
	createNetwork(c, config, shouldSucceed)
	deleteNetwork(c, name, shouldSucceed)
}

func isNetworkAvailable(c *check.C, name string) bool {
	status, body, err := sockRequest("GET", "/networks", nil)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)

	nJSON := []types.NetworkResource{}
	err = json.Unmarshal(body, &nJSON)
	c.Assert(err, checker.IsNil)

	for _, n := range nJSON {
		if n.Name == name {
			return true
		}
	}
	return false
}

func getNetworkIDByName(c *check.C, name string) string {
	var (
		v          = url.Values{}
		filterArgs = filters.NewArgs()
	)
	filterArgs.Add("name", name)
	filterJSON, err := filters.ToParam(filterArgs)
	c.Assert(err, checker.IsNil)
	v.Set("filters", filterJSON)

	status, body, err := sockRequest("GET", "/networks?"+v.Encode(), nil)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)

	nJSON := []types.NetworkResource{}
	err = json.Unmarshal(body, &nJSON)
	c.Assert(err, checker.IsNil)
	c.Assert(len(nJSON), checker.Equals, 1)

	return nJSON[0].ID
}

func getNetworkResource(c *check.C, id string) *types.NetworkResource {
	_, obj, err := sockRequest("GET", "/networks/"+id, nil)
	c.Assert(err, checker.IsNil)

	nr := types.NetworkResource{}
	err = json.Unmarshal(obj, &nr)
	c.Assert(err, checker.IsNil)

	return &nr
}

func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string {
	status, resp, err := sockRequest("POST", "/networks/create", config)
	if !shouldSucceed {
		c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)
		return ""
	}

	c.Assert(status, checker.Equals, http.StatusCreated)
	c.Assert(err, checker.IsNil)

	var nr types.NetworkCreateResponse
	err = json.Unmarshal(resp, &nr)
	c.Assert(err, checker.IsNil)

	return nr.ID
}

func connectNetwork(c *check.C, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	status, _, err := sockRequest("POST", "/networks/"+nid+"/connect", config)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}

func disconnectNetwork(c *check.C, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	status, _, err := sockRequest("POST", "/networks/"+nid+"/disconnect", config)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}

func deleteNetwork(c *check.C, id string, shouldSucceed bool) {
	status, _, err := sockRequest("DELETE", "/networks/"+id, nil)
	if !shouldSucceed {
		c.Assert(status, checker.Not(checker.Equals), http.StatusOK)
		return
	}
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}
<commit_msg>Windows CI: Turn off network API tests<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"strings"

	"github.com/docker/docker/pkg/integration/checker"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/go-check/check"
)

func (s *DockerSuite) TestApiNetworkGetDefaults(c *check.C) {
	testRequires(c, DaemonIsLinux)
	// By default docker daemon creates 3 networks. check if they are present
	defaults := []string{"bridge", "host", "none"}
	for _, nn := range defaults {
		c.Assert(isNetworkAvailable(c, nn), checker.Equals, true)
	}
}

func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) {
	testRequires(c, DaemonIsLinux)
	// Create a network
	name := "testnetwork"
	config := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	id := createNetwork(c, config, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)

	// delete the network and make sure it is deleted
	deleteNetwork(c, id, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, false)
}

func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) {
	testRequires(c, DaemonIsLinux)
	name := "testcheckduplicate"
	configOnCheck := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	configNotCheck := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: false,
	}

	// Creating a new network first
	createNetwork(c, configOnCheck, true)
	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)

	// Creating another network with same name and CheckDuplicate must fail
	createNetwork(c, configOnCheck, false)

	// Creating another network with same name and not CheckDuplicate must succeed
	createNetwork(c, configNotCheck, true)
}

func (s *DockerSuite) TestApiNetworkFilter(c *check.C) {
	testRequires(c, DaemonIsLinux)
	nr := getNetworkResource(c, getNetworkIDByName(c, "bridge"))
	c.Assert(nr.Name, checker.Equals, "bridge")
}

func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
	testRequires(c, DaemonIsLinux)
	// Inspect default bridge network
	nr := getNetworkResource(c, "bridge")
	c.Assert(nr.Name, checker.Equals, "bridge")

	// run a container and attach it to the default bridge network
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)
	containerIP := findContainerIP(c, "test", "bridge")

	// inspect default bridge network again and make sure the container is connected
	nr = getNetworkResource(c, nr.ID)
	c.Assert(nr.Driver, checker.Equals, "bridge")
	c.Assert(nr.Scope, checker.Equals, "local")
	c.Assert(nr.IPAM.Driver, checker.Equals, "default")
	c.Assert(len(nr.Containers), checker.Equals, 1)
	c.Assert(nr.Containers[containerID], checker.NotNil)

	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	c.Assert(err, checker.IsNil)
	c.Assert(ip.String(), checker.Equals, containerIP)

	// IPAM configuration inspect
	ipam := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
	}
	config := types.NetworkCreate{
		Name:    "br0",
		Driver:  "bridge",
		IPAM:    ipam,
		Options: map[string]string{"foo": "bar", "opts": "dopts"},
	}
	id0 := createNetwork(c, config, true)
	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)

	nr = getNetworkResource(c, id0)
	c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
	c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
	c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
	c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254")
	c.Assert(nr.Options["foo"], checker.Equals, "bar")
	c.Assert(nr.Options["opts"], checker.Equals, "dopts")

	// delete the network and make sure it is deleted
	deleteNetwork(c, id0, true)
	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, false)
}

func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
	testRequires(c, DaemonIsLinux)
	// Create test network
	name := "testnetwork"
	config := types.NetworkCreate{
		Name: name,
	}
	id := createNetwork(c, config, true)
	nr := getNetworkResource(c, id)
	c.Assert(nr.Name, checker.Equals, name)
	c.Assert(nr.ID, checker.Equals, id)
	c.Assert(len(nr.Containers), checker.Equals, 0)

	// run a container
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)

	// connect the container to the test network
	connectNetwork(c, nr.ID, containerID)

	// inspect the network to make sure container is connected
	nr = getNetworkResource(c, nr.ID)
	c.Assert(len(nr.Containers), checker.Equals, 1)
	c.Assert(nr.Containers[containerID], checker.NotNil)

	// check if container IP matches network inspect
	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	c.Assert(err, checker.IsNil)
	containerIP := findContainerIP(c, "test", "testnetwork")
	c.Assert(ip.String(), checker.Equals, containerIP)

	// disconnect container from the network
	disconnectNetwork(c, nr.ID, containerID)
	nr = getNetworkResource(c, nr.ID)
	c.Assert(nr.Name, checker.Equals, name)
	c.Assert(len(nr.Containers), checker.Equals, 0)

	// delete the network
	deleteNetwork(c, nr.ID, true)
}

func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
	testRequires(c, DaemonIsLinux)
	// test0 bridge network
	ipam0 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
	}
	config0 := types.NetworkCreate{
		Name:   "test0",
		Driver: "bridge",
		IPAM:   ipam0,
	}
	id0 := createNetwork(c, config0, true)
	c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true)

	ipam1 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
	}
	// test1 bridge network overlaps with test0
	config1 := types.NetworkCreate{
		Name:   "test1",
		Driver: "bridge",
		IPAM:   ipam1,
	}
	createNetwork(c, config1, false)
	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false)

	ipam2 := network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
	}
	// test2 bridge network does not overlap
	config2 := types.NetworkCreate{
		Name:   "test2",
		Driver: "bridge",
		IPAM:   ipam2,
	}
	createNetwork(c, config2, true)
	c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true)

	// remove test0 and retry to create test1
	deleteNetwork(c, id0, true)
	createNetwork(c, config1, true)
	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)

	// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
	createNetwork(c, types.NetworkCreate{Name: "test3"}, true)
	c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true)
	createNetwork(c, types.NetworkCreate{Name: "test4"}, true)
	c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true)
	createNetwork(c, types.NetworkCreate{Name: "test5"}, true)
	c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)

	for i := 1; i < 6; i++ {
		deleteNetwork(c, fmt.Sprintf("test%d", i), true)
	}
}

func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
	testRequires(c, DaemonIsLinux)
	createDeletePredefinedNetwork(c, "bridge")
	createDeletePredefinedNetwork(c, "none")
	createDeletePredefinedNetwork(c, "host")
}

func createDeletePredefinedNetwork(c *check.C, name string) {
	// Create pre-defined network
	config := types.NetworkCreate{
		Name:           name,
		CheckDuplicate: true,
	}
	shouldSucceed := false
	createNetwork(c, config, shouldSucceed)
	deleteNetwork(c, name, shouldSucceed)
}

func isNetworkAvailable(c *check.C, name string) bool {
	status, body, err := sockRequest("GET", "/networks", nil)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)

	nJSON := []types.NetworkResource{}
	err = json.Unmarshal(body, &nJSON)
	c.Assert(err, checker.IsNil)

	for _, n := range nJSON {
		if n.Name == name {
			return true
		}
	}
	return false
}

func getNetworkIDByName(c *check.C, name string) string {
	var (
		v          = url.Values{}
		filterArgs = filters.NewArgs()
	)
	filterArgs.Add("name", name)
	filterJSON, err := filters.ToParam(filterArgs)
	c.Assert(err, checker.IsNil)
	v.Set("filters", filterJSON)

	status, body, err := sockRequest("GET", "/networks?"+v.Encode(), nil)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)

	nJSON := []types.NetworkResource{}
	err = json.Unmarshal(body, &nJSON)
	c.Assert(err, checker.IsNil)
	c.Assert(len(nJSON), checker.Equals, 1)

	return nJSON[0].ID
}

func getNetworkResource(c *check.C, id string) *types.NetworkResource {
	_, obj, err := sockRequest("GET", "/networks/"+id, nil)
	c.Assert(err, checker.IsNil)

	nr := types.NetworkResource{}
	err = json.Unmarshal(obj, &nr)
	c.Assert(err, checker.IsNil)

	return &nr
}

func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string {
	status, resp, err := sockRequest("POST", "/networks/create", config)
	if !shouldSucceed {
		c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)
		return ""
	}

	c.Assert(status, checker.Equals, http.StatusCreated)
	c.Assert(err, checker.IsNil)

	var nr types.NetworkCreateResponse
	err = json.Unmarshal(resp, &nr)
	c.Assert(err, checker.IsNil)

	return nr.ID
}

func connectNetwork(c *check.C, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	status, _, err := sockRequest("POST", "/networks/"+nid+"/connect", config)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}

func disconnectNetwork(c *check.C, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	status, _, err := sockRequest("POST", "/networks/"+nid+"/disconnect", config)
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}

func deleteNetwork(c *check.C, id string, shouldSucceed bool) {
	status, _, err := sockRequest("DELETE", "/networks/"+id, nil)
	if !shouldSucceed {
		c.Assert(status, checker.Not(checker.Equals), http.StatusOK)
		return
	}
	c.Assert(status, checker.Equals, http.StatusOK)
	c.Assert(err, checker.IsNil)
}
<|endoftext|>


<commit_before>package container // import "github.com/docker/docker/integration/container"

import (
	"context"
	"strconv"
	"strings"
	"testing"
	"time"

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/integration/internal/container"
	"github.com/docker/docker/integration/internal/request"
	"github.com/gotestyourself/gotestyourself/poll"
	"github.com/gotestyourself/gotestyourself/skip"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestUpdateMemory(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	skip.If(t, !testEnv.DaemonInfo.MemoryLimit)
	skip.If(t, !testEnv.DaemonInfo.SwapLimit)

	defer setupTest(t)()
	client := request.NewAPIClient(t)
	ctx := context.Background()

	cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
		c.HostConfig.Resources = containertypes.Resources{
			Memory: 200 * 1024 * 1024,
		}
	})

	poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))

	const (
		setMemory     int64 = 314572800
		setMemorySwap       = 524288000
	)

	_, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
		Resources: containertypes.Resources{
			Memory:     setMemory,
			MemorySwap: setMemorySwap,
		},
	})
	require.NoError(t, err)

	inspect, err := client.ContainerInspect(ctx, cID)
	require.NoError(t, err)
	assert.Equal(t, setMemory, inspect.HostConfig.Memory)
	assert.Equal(t, setMemorySwap, inspect.HostConfig.MemorySwap)

	res, err := container.Exec(ctx, client, cID,
		[]string{"cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"})
	require.NoError(t, err)
	require.Empty(t, res.Stderr())
	require.Equal(t, 0, res.ExitCode)
	assert.Equal(t, strconv.FormatInt(setMemory, 10), strings.TrimSpace(res.Stdout()))

	res, err = container.Exec(ctx, client, cID,
		[]string{"cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"})
	require.NoError(t, err)
	require.Empty(t, res.Stderr())
	require.Equal(t, 0, res.ExitCode)
	assert.Equal(t, strconv.FormatInt(setMemorySwap, 10), strings.TrimSpace(res.Stdout()))
}

func TestUpdateCPUQUota(t *testing.T) {
	t.Parallel()

	defer setupTest(t)()
	client := request.NewAPIClient(t)
	ctx := context.Background()

	cID := container.Run(t, ctx, client)

	for _, test := range []struct {
		desc   string
		update int64
	}{
		{desc: "some random value", update: 15000},
		{desc: "a higher value", update: 20000},
		{desc: "a lower value", update: 10000},
		{desc: "unset value", update: -1},
	} {
		if _, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
			Resources: containertypes.Resources{
				CPUQuota: test.update,
			},
		}); err != nil {
			t.Fatal(err)
		}

		inspect, err := client.ContainerInspect(ctx, cID)
		require.NoError(t, err)
		assert.Equal(t, test.update, inspect.HostConfig.CPUQuota)

		res, err := container.Exec(ctx, client, cID,
			[]string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
		require.NoError(t, err)
		require.Empty(t, res.Stderr())
		require.Equal(t, 0, res.ExitCode)

		assert.Equal(t, strconv.FormatInt(test.update, 10), strings.TrimSpace(res.Stdout()))
	}
}
<commit_msg>integration/TestUpdateMemory: fix false failure<commit_after>package container // import "github.com/docker/docker/integration/container"

import (
	"context"
	"strconv"
	"strings"
	"testing"
	"time"

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/integration/internal/container"
	"github.com/docker/docker/integration/internal/request"
	"github.com/gotestyourself/gotestyourself/poll"
	"github.com/gotestyourself/gotestyourself/skip"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestUpdateMemory(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	skip.If(t, !testEnv.DaemonInfo.MemoryLimit)
	skip.If(t, !testEnv.DaemonInfo.SwapLimit)

	defer setupTest(t)()
	client := request.NewAPIClient(t)
	ctx := context.Background()

	cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
		c.HostConfig.Resources = containertypes.Resources{
			Memory: 200 * 1024 * 1024,
		}
	})

	poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))

	const (
		setMemory     int64 = 314572800
		setMemorySwap int64 = 524288000
	)

	_, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
		Resources: containertypes.Resources{
			Memory:     setMemory,
			MemorySwap: setMemorySwap,
		},
	})
	require.NoError(t, err)

	inspect, err := client.ContainerInspect(ctx, cID)
	require.NoError(t, err)
	assert.Equal(t, setMemory, inspect.HostConfig.Memory)
	assert.Equal(t, setMemorySwap, inspect.HostConfig.MemorySwap)

	res, err := container.Exec(ctx, client, cID,
		[]string{"cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"})
	require.NoError(t, err)
	require.Empty(t, res.Stderr())
	require.Equal(t, 0, res.ExitCode)
	assert.Equal(t, strconv.FormatInt(setMemory, 10), strings.TrimSpace(res.Stdout()))

	res, err = container.Exec(ctx, client, cID,
		[]string{"cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"})
	require.NoError(t, err)
	require.Empty(t, res.Stderr())
	require.Equal(t, 0, res.ExitCode)
	assert.Equal(t, strconv.FormatInt(setMemorySwap, 10), strings.TrimSpace(res.Stdout()))
}

func TestUpdateCPUQUota(t *testing.T) {
	t.Parallel()

	defer setupTest(t)()
	client := request.NewAPIClient(t)
	ctx := context.Background()

	cID := container.Run(t, ctx, client)

	for _, test := range []struct {
		desc   string
		update int64
	}{
		{desc: "some random value", update: 15000},
		{desc: "a higher value", update: 20000},
		{desc: "a lower value", update: 10000},
		{desc: "unset value", update: -1},
	} {
		if _, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
			Resources: containertypes.Resources{
				CPUQuota: test.update,
			},
		}); err != nil {
			t.Fatal(err)
		}

		inspect, err := client.ContainerInspect(ctx, cID)
		require.NoError(t, err)
		assert.Equal(t, test.update, inspect.HostConfig.CPUQuota)

		res, err := container.Exec(ctx, client, cID,
			[]string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
		require.NoError(t, err)
		require.Empty(t, res.Stderr())
		require.Equal(t, 0, res.ExitCode)

		assert.Equal(t, strconv.FormatInt(test.update, 10), strings.TrimSpace(res.Stdout()))
	}
}
<|endoftext|>


<commit_before>// Copyright 2020 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
//
//     https://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 (
	"bytes"
	"context"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
	"time"

	"cloud.google.com/go/firestore"
	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

var duration time.Duration = 6 * time.Second

func setup(ctx context.Context, t *testing.T) (*firestore.Client, string, string) {
	tc := testutil.SystemTest(t)
	projectID := os.Getenv("GOLANG_SAMPLES_FIRESTORE_PROJECT")
	if projectID == "" {
		t.Skip("Skipping firestore test. Set GOLANG_SAMPLES_FIRESTORE_PROJECT.")
	}
	collection := tc.ProjectID + "-collection-cities"

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		t.Fatalf("firestore.NewClient: %v", err)
	}
	return client, projectID, collection
}

func TestListen(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	// Delete all docs first to make sure setup works.
	docs, err := client.Collection(collection).Documents(ctx).GetAll()
	if err == nil {
		for _, doc := range docs {
			doc.Ref.Delete(ctx)
		}
	}
	cityCollection := []struct {
		city, name, state string
	}{
		{city: "SF", name: "San Francisco", state: "CA"},
		{city: "LA", name: "Los Angeles", state: "CA"},
		{city: "DC", name: "Washington D.C."},
	}

	for _, c := range cityCollection {
		if _, err := client.Collection(collection).Doc(c.city).Set(ctx, map[string]string{
			"name":  c.name,
			"state": c.state,
		}); err != nil {
			t.Fatalf("Set: %v", err)
		}
	}
	if err := listenDocument(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenDocument: %v", err)
	}
}
func TestListenMultiple(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	if err := listenMultiple(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenMultiple: %v", err)
	}
}

func TestListenChanges(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	buf := &bytes.Buffer{}
	c := make(chan *bytes.Buffer)
	go func() {
		defer close(c)
		err := listenChanges(ctx, buf, projectID, collection)
		if err != nil {
			t.Errorf("listenChanges: %v", err)
		}
		c <- buf
	}()
	// Add some changes to data in parallel.
	time.Sleep(time.Second)
	var pop int64 = 3900000
	if _, err := client.Collection(collection).Doc("LA").Update(ctx, []firestore.Update{
		{Path: "population", Value: pop},
	}); err != nil {
		log.Fatalf("Doc.Update: %v", err)
	}
	<-c
	want := "population:3900000"
	if got := buf.String(); !strings.Contains(got, want) {
		t.Errorf("listenChanges got\n----\n%s\n----\nWant to contain:\n----\n%s\n----", got, want)
	}
}

func TestListenErrors(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	if err := listenErrors(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenErrors: %v", err)
	}
}
<commit_msg>fix(firestore): increase timeout for TestListenChanges (#1793)<commit_after>// Copyright 2020 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
//
//     https://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 (
	"bytes"
	"context"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
	"time"

	"cloud.google.com/go/firestore"
	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

var duration time.Duration = 15 * time.Second

func setup(ctx context.Context, t *testing.T) (*firestore.Client, string, string) {
	tc := testutil.SystemTest(t)
	projectID := os.Getenv("GOLANG_SAMPLES_FIRESTORE_PROJECT")
	if projectID == "" {
		t.Skip("Skipping firestore test. Set GOLANG_SAMPLES_FIRESTORE_PROJECT.")
	}
	collection := tc.ProjectID + "-collection-cities"

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		t.Fatalf("firestore.NewClient: %v", err)
	}
	return client, projectID, collection
}

func TestListen(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	// Delete all docs first to make sure setup works.
	docs, err := client.Collection(collection).Documents(ctx).GetAll()
	if err == nil {
		for _, doc := range docs {
			doc.Ref.Delete(ctx)
		}
	}
	cityCollection := []struct {
		city, name, state string
	}{
		{city: "SF", name: "San Francisco", state: "CA"},
		{city: "LA", name: "Los Angeles", state: "CA"},
		{city: "DC", name: "Washington D.C."},
	}

	for _, c := range cityCollection {
		if _, err := client.Collection(collection).Doc(c.city).Set(ctx, map[string]string{
			"name":  c.name,
			"state": c.state,
		}); err != nil {
			t.Fatalf("Set: %v", err)
		}
	}
	if err := listenDocument(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenDocument: %v", err)
	}
}
func TestListenMultiple(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	if err := listenMultiple(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenMultiple: %v", err)
	}
}

func TestListenChanges(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	buf := &bytes.Buffer{}
	c := make(chan *bytes.Buffer)
	go func() {
		defer close(c)
		err := listenChanges(ctx, buf, projectID, collection)
		if err != nil {
			t.Errorf("listenChanges: %v", err)
		}
		c <- buf
	}()
	// Add some changes to data in parallel.
	time.Sleep(time.Second)
	var pop int64 = 3900000
	if _, err := client.Collection(collection).Doc("LA").Update(ctx, []firestore.Update{
		{Path: "population", Value: pop},
	}); err != nil {
		log.Fatalf("Doc.Update: %v", err)
	}
	<-c
	want := "population:3900000"
	if got := buf.String(); !strings.Contains(got, want) {
		t.Errorf("listenChanges got\n----\n%s\n----\nWant to contain:\n----\n%s\n----", got, want)
	}
}

func TestListenErrors(t *testing.T) {
	ctx := context.Background()
	client, projectID, collection := setup(ctx, t)
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, duration)
	defer cancel()

	if err := listenErrors(ctx, ioutil.Discard, projectID, collection); err != nil {
		t.Errorf("listenErrors: %v", err)
	}
}
<|endoftext|>


<commit_before>package api

import (
	"bufio"
	"bytes"
	"compress/flate"
	"compress/gzip"
	"crypto/md5"
	"fmt"
	"html"
	"io"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/zyxar/ed2k"
)

func readBody(resp *http.Response) ([]byte, error) {
	buffer := bytes.NewBuffer(make([]byte, 0, 1024))
	var rd io.ReadCloser
	var err error
	switch resp.Header.Get("Content-Encoding") {
	case "gzip":
		rd, _ = gzip.NewReader(resp.Body)
		defer rd.Close()
	case "deflate":
		rd = flate.NewReader(resp.Body)
		defer rd.Close()
	default:
		rd = resp.Body
	}
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
			err = panicErr
		} else {
			panic(e)
		}
	}()
	_, err = buffer.ReadFrom(rd)
	return buffer.Bytes(), err
}

func current_timestamp() int {
	return int(time.Now().UnixNano() / 1000000)
}

func current_random() string {
	return fmt.Sprintf("%d%v", current_timestamp(), rand.Float64()*1000000)
}

func hashPass(pass, vcode string) string {
	h := md5.New()
	v := EncryptPass(pass)
	io.WriteString(h, v)
	io.WriteString(h, vcode)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func EncryptPass(pass string) string {
	if len(pass) == 32 {
		if ok, _ := regexp.MatchString(`[a-f0-9]{32,32}`, pass); ok {
			return pass
		}
	}
	h := md5.New()
	v := pass
	io.WriteString(h, v)
	v = fmt.Sprintf("%x", h.Sum(nil))
	h.Reset()
	io.WriteString(h, v)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func md5sum(raw interface{}) []byte {
	h := md5.New()
	switch raw.(type) {
	case []byte:
		h.Write(raw.([]byte))
	case string:
		io.WriteString(h, raw.(string))
	default:
		io.WriteString(h, fmt.Sprintf("%s", raw))
	}
	return h.Sum(nil)
}

func getTaskPre(resp []byte) (*_task_pre, error) {
	exp := regexp.MustCompile(`queryCid\((.*)\)`)
	s := exp.FindSubmatch(resp)
	if s == nil {
		return nil, invalidResponseErr
	}
	ss := bytes.Split(s[1], []byte(","))
	j := 0
	if len(ss) >= 10 {
		j = 1
	}
	ret := _task_pre{}
	ret.Cid = string(bytes.Trim(ss[0], "' "))
	ret.GCid = string(bytes.Trim(ss[1], "' "))
	ret.SizeCost = string(bytes.Trim(ss[2], "' "))
	ret.FileName = string(bytes.Trim(ss[j+3], "' "))
	ret.Goldbean = string(bytes.Trim(ss[j+4], "' "))
	ret.Silverbean = string(bytes.Trim(ss[j+5], "' "))
	var err error
	if ret.Goldbean != "0" || ret.Silverbean != "0" {
		err = fmt.Errorf("Task need bean: %s:%s", ret.Goldbean, ret.Silverbean)
	}
	return &ret, err
}

func evalParse(queryUrl []byte) *_bt_qtask {
	exp := regexp.MustCompile(`'([0-9A-Za-z]{40,40})','(\d+)','(.*)','(\d)',new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),'([\d\.]+)','(\d)'`)
	s := exp.FindSubmatch(queryUrl)
	if s == nil {
		return nil
	}
	var task _bt_qtask
	task.InfoId = string(s[1])
	task.Size = string(s[2])
	task.Name = string(s[3])
	task.IsFull = string(s[4])
	a := bytes.Split(s[5], []byte(","))
	task.Files = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Files[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[6], []byte(","))
	task.Sizesf = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Sizesf[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[7], []byte(","))
	task.Sizes = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Sizes[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[8], []byte(","))
	task.Picked = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Picked[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[9], []byte(","))
	task.Ext = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Ext[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[10], []byte(","))
	task.Index = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Index[i] = string(bytes.Trim(a[i], "' "))
	}
	task.Random = string(s[11])
	task.Ret = string(s[12])
	return &task
}

func extractTasks(ts []*Task) (urls []string, ids []string) {
	ids = make([]string, 0, len(ts))
	urls = make([]string, 0, len(ts))
	for i, _ := range ts {
		ids = append(ids, ts[i].Id)
		urls = append(urls, ts[i].URL)
	}
	return
}

func getEd2kHash(filename string) (string, error) {
	f, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer f.Close()
	rd := bufio.NewReader(f)
	eh := ed2k.New()
	_, err = rd.WriteTo(eh)
	return fmt.Sprintf("%x", eh.Sum(nil)), err
}

func getEd2kHashFromURL(uri string) string {
	h := strings.Split(uri, "|")
	if len(h) > 4 {
		return strings.ToLower(h[4])
	}
	return ""
}

func unescape_name(s string) (string, int) {
	v := html.UnescapeString(s)
	return v, len(v)
}

func unescapeName(s string) string {
	ll := len(s)
	l := 0
	for ll != l {
		ll = len(s)
		s, l = unescape_name(s)
	}
	return s
}
<commit_msg>Fixes evalParse()<commit_after>package api

import (
	"bufio"
	"bytes"
	"compress/flate"
	"compress/gzip"
	"crypto/md5"
	"fmt"
	"html"
	"io"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/zyxar/ed2k"
)

func readBody(resp *http.Response) ([]byte, error) {
	buffer := bytes.NewBuffer(make([]byte, 0, 1024))
	var rd io.ReadCloser
	var err error
	switch resp.Header.Get("Content-Encoding") {
	case "gzip":
		rd, _ = gzip.NewReader(resp.Body)
		defer rd.Close()
	case "deflate":
		rd = flate.NewReader(resp.Body)
		defer rd.Close()
	default:
		rd = resp.Body
	}
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
			err = panicErr
		} else {
			panic(e)
		}
	}()
	_, err = buffer.ReadFrom(rd)
	return buffer.Bytes(), err
}

func current_timestamp() int {
	return int(time.Now().UnixNano() / 1000000)
}

func current_random() string {
	return fmt.Sprintf("%d%v", current_timestamp(), rand.Float64()*1000000)
}

func hashPass(pass, vcode string) string {
	h := md5.New()
	v := EncryptPass(pass)
	io.WriteString(h, v)
	io.WriteString(h, vcode)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func EncryptPass(pass string) string {
	if len(pass) == 32 {
		if ok, _ := regexp.MatchString(`[a-f0-9]{32,32}`, pass); ok {
			return pass
		}
	}
	h := md5.New()
	v := pass
	io.WriteString(h, v)
	v = fmt.Sprintf("%x", h.Sum(nil))
	h.Reset()
	io.WriteString(h, v)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func md5sum(raw interface{}) []byte {
	h := md5.New()
	switch raw.(type) {
	case []byte:
		h.Write(raw.([]byte))
	case string:
		io.WriteString(h, raw.(string))
	default:
		io.WriteString(h, fmt.Sprintf("%s", raw))
	}
	return h.Sum(nil)
}

func getTaskPre(resp []byte) (*_task_pre, error) {
	exp := regexp.MustCompile(`queryCid\((.*)\)`)
	s := exp.FindSubmatch(resp)
	if s == nil {
		return nil, invalidResponseErr
	}
	ss := bytes.Split(s[1], []byte(","))
	j := 0
	if len(ss) >= 10 {
		j = 1
	}
	ret := _task_pre{}
	ret.Cid = string(bytes.Trim(ss[0], "' "))
	ret.GCid = string(bytes.Trim(ss[1], "' "))
	ret.SizeCost = string(bytes.Trim(ss[2], "' "))
	ret.FileName = string(bytes.Trim(ss[j+3], "' "))
	ret.Goldbean = string(bytes.Trim(ss[j+4], "' "))
	ret.Silverbean = string(bytes.Trim(ss[j+5], "' "))
	var err error
	if ret.Goldbean != "0" || ret.Silverbean != "0" {
		err = fmt.Errorf("Task need bean: %s:%s", ret.Goldbean, ret.Silverbean)
	}
	return &ret, err
}

func evalParse(queryUrl []byte) *_bt_qtask {
	exp := regexp.MustCompile(`'([0-9A-Za-z]{40,40})','(\d*)','(.*)','(\d)',new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),new Array\((.*)\),'([\d\.]+)','(\d)'`)
	s := exp.FindSubmatch(queryUrl)
	if s == nil {
		return nil
	}
	var task _bt_qtask
	task.InfoId = string(s[1])
	task.Size = string(s[2])
	task.Name = string(s[3])
	task.IsFull = string(s[4])
	a := bytes.Split(s[5], []byte(","))
	task.Files = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Files[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[6], []byte(","))
	task.Sizesf = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Sizesf[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[7], []byte(","))
	task.Sizes = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Sizes[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[8], []byte(","))
	task.Picked = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Picked[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[9], []byte(","))
	task.Ext = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Ext[i] = string(bytes.Trim(a[i], "' "))
	}
	a = bytes.Split(s[10], []byte(","))
	task.Index = make([]string, len(a))
	for i := 0; i < len(a); i++ {
		task.Index[i] = string(bytes.Trim(a[i], "' "))
	}
	task.Random = string(s[11])
	task.Ret = string(s[12])
	return &task
}

func extractTasks(ts []*Task) (urls []string, ids []string) {
	ids = make([]string, 0, len(ts))
	urls = make([]string, 0, len(ts))
	for i, _ := range ts {
		ids = append(ids, ts[i].Id)
		urls = append(urls, ts[i].URL)
	}
	return
}

func getEd2kHash(filename string) (string, error) {
	f, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer f.Close()
	rd := bufio.NewReader(f)
	eh := ed2k.New()
	_, err = rd.WriteTo(eh)
	return fmt.Sprintf("%x", eh.Sum(nil)), err
}

func getEd2kHashFromURL(uri string) string {
	h := strings.Split(uri, "|")
	if len(h) > 4 {
		return strings.ToLower(h[4])
	}
	return ""
}

func unescape_name(s string) (string, int) {
	v := html.UnescapeString(s)
	return v, len(v)
}

func unescapeName(s string) string {
	ll := len(s)
	l := 0
	for ll != l {
		ll = len(s)
		s, l = unescape_name(s)
	}
	return s
}
<|endoftext|>


<commit_before>package qingcloud

import (
	"fmt"

	"github.com/hashicorp/terraform/helper/schema"
	qc "github.com/yunify/qingcloud-sdk-go/service"
)

const (
	resourceLoadBalancerType            = "type"
	resourceLoadBalancerPrivateIPs      = "private_ips"
	resourceLoadBalancerEipIDs          = "eip_ids"
	resourceLoadBalancerNodeCount       = "node_count"
	resourceLoadBalancerSecurityGroupID = "security_group_id"
	resourceLoadBalancerVxnetID         = "vxnet_id"
	resourceLoadBalancerHttpHeaderSize  = "http_header_size"
)

func resourceQingcloudLoadBalancer() *schema.Resource {

	return &schema.Resource{
		Create: resourceQingcloudLoadBalancerCreate,
		Read:   resourceQingcloudLoadBalancerRead,
		Update: resourceQingcloudLoadBalancerUpdate,
		Delete: resourceQingcloudLoadBalancerDelete,
		Schema: map[string]*schema.Schema{
			resourceName: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			resourceDescription: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			resourceLoadBalancerType: &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      0,
				ValidateFunc: withinArrayInt(0, 1, 2, 3, 4, 5),
			},
			resourceLoadBalancerPrivateIPs: &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				Computed: true,
			},
			resourceLoadBalancerEipIDs: &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
			},
			resourceLoadBalancerNodeCount: &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  2,
			},
			resourceLoadBalancerSecurityGroupID: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			resourceLoadBalancerVxnetID: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Default:  "vxnet-0",
				ForceNew: true,
			},
			resourceLoadBalancerHttpHeaderSize: &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      15,
				ValidateFunc: withinArrayIntRange(1, 127),
			},
			resourceTagIds:   tagIdsSchema(),
			resourceTagNames: tagNamesSchema(),
		},
	}
}
func resourceQingcloudLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error {
	if err := waitLoadBalancerLease(d, meta); err != nil {
		return err
	}
	d.Partial(true)
	if err := modifyLoadBalancerAttributes(d, meta); err != nil {
		return err
	}
	d.SetPartial(resourceLoadBalancerPrivateIPs)
	d.SetPartial(resourceLoadBalancerHttpHeaderSize)
	d.SetPartial(resourceLoadBalancerSecurityGroupID)
	d.SetPartial(resourceLoadBalancerNodeCount)
	d.SetPartial(resourceName)
	d.SetPartial(resourceDescription)
	if d.HasChange(resourceLoadBalancerEipIDs) && !d.IsNewResource() {
		if err := updateLoadbalancerEips(d, meta); err != nil {
			return err
		}
	}
	d.SetPartial(resourceLoadBalancerEipIDs)
	if d.HasChange(resourceLoadBalancerType) && !d.IsNewResource() {
		if err := resizeLoadBalancer(qc.String(d.Id()), qc.Int(d.Get(resourceLoadBalancerType).(int)), meta); err != nil {
			return err
		}
	}
	d.SetPartial(resourceLoadBalancerType)
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeLoadBalancer); err != nil {
		return err
	}
	d.Partial(false)
	return resourceQingcloudLoadBalancerRead(d, meta)
}

func resourceQingcloudLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	input := new(qc.CreateLoadBalancerInput)
	input.LoadBalancerName, _ = getNamePointer(d)
	input.VxNet = getSetStringPointer(d, resourceLoadBalancerVxnetID)
	input.SecurityGroup = getSetStringPointer(d, resourceLoadBalancerSecurityGroupID)
	input.HTTPHeaderSize = qc.Int(d.Get(resourceLoadBalancerHttpHeaderSize).(int))
	input.NodeCount = qc.Int(d.Get(resourceLoadBalancerNodeCount).(int))
	input.LoadBalancerType = qc.Int(d.Get(resourceLoadBalancerType).(int))
	if _, ok := d.GetOk(resourceLoadBalancerPrivateIPs); ok {
		privateIPs := d.Get(resourceLoadBalancerPrivateIPs).(*schema.Set).List()
		if len(privateIPs) != 1 || d.Get(resourceLoadBalancerVxnetID).(string) == "vxnet-0" {
			return fmt.Errorf("error private_ips info")
		}
		input.PrivateIP = qc.String(privateIPs[0].(string))
	}
	var eips []*string
	for _, value := range d.Get(resourceLoadBalancerEipIDs).(*schema.Set).List() {
		eips = append(eips, qc.String(value.(string)))
	}
	var output *qc.CreateLoadBalancerOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.CreateLoadBalancer(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	d.SetId(qc.StringValue(output.LoadBalancerID))
	if _, err = LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	return resourceQingcloudVpcUpdate(d, meta)
}
func resourceQingcloudLoadBalancerRead(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	input := new(qc.DescribeLoadBalancersInput)
	input.LoadBalancers = []*string{qc.String(d.Id())}
	input.Verbose = qc.Int(1)
	var output *qc.DescribeLoadBalancersOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.DescribeLoadBalancers(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	if isLoadBalancerDeleted(output.LoadBalancerSet) {
		d.SetId("")
		return nil
	}
	lb := output.LoadBalancerSet[0]
	d.Set(resourceName, qc.StringValue(lb.LoadBalancerName))
	d.Set(resourceDescription, qc.StringValue(lb.Description))
	d.Set(resourceLoadBalancerType, qc.IntValue(lb.LoadBalancerType))
	d.Set(resourceLoadBalancerVxnetID, qc.StringValue(lb.VxNetID))
	d.Set(resourceLoadBalancerPrivateIPs, qc.StringValueSlice(lb.PrivateIPs))
	d.Set(resourceLoadBalancerSecurityGroupID, qc.StringValue(lb.SecurityGroupID))
	d.Set(resourceLoadBalancerNodeCount, qc.IntValue(lb.NodeCount))
	var eipIDs []string
	for _, eip := range lb.Cluster {
		eipIDs = append(eipIDs, qc.StringValue(eip.EIPID))
	}
	d.Set(resourceLoadBalancerEipIDs, eipIDs)
	resourceSetTag(d, lb.Tags)
	return nil
}

func resourceQingcloudLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	if err := waitLoadBalancerLease(d, meta); err != nil {
		return err
	}
	input := new(qc.DeleteLoadBalancersInput)
	input.LoadBalancers = []*string{qc.String(d.Id())}
	var output *qc.DeleteLoadBalancersOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.DeleteLoadBalancers(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	d.SetId("")
	return nil
}
<commit_msg>remove lb node cont default value , only external lb use this filed<commit_after>package qingcloud

import (
	"fmt"

	"github.com/hashicorp/terraform/helper/schema"
	qc "github.com/yunify/qingcloud-sdk-go/service"
)

const (
	resourceLoadBalancerType            = "type"
	resourceLoadBalancerPrivateIPs      = "private_ips"
	resourceLoadBalancerEipIDs          = "eip_ids"
	resourceLoadBalancerNodeCount       = "node_count"
	resourceLoadBalancerSecurityGroupID = "security_group_id"
	resourceLoadBalancerVxnetID         = "vxnet_id"
	resourceLoadBalancerHttpHeaderSize  = "http_header_size"
)

func resourceQingcloudLoadBalancer() *schema.Resource {

	return &schema.Resource{
		Create: resourceQingcloudLoadBalancerCreate,
		Read:   resourceQingcloudLoadBalancerRead,
		Update: resourceQingcloudLoadBalancerUpdate,
		Delete: resourceQingcloudLoadBalancerDelete,
		Schema: map[string]*schema.Schema{
			resourceName: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			resourceDescription: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			resourceLoadBalancerType: &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      0,
				ValidateFunc: withinArrayInt(0, 1, 2, 3, 4, 5),
			},
			resourceLoadBalancerPrivateIPs: &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
				Computed: true,
			},
			resourceLoadBalancerEipIDs: &schema.Schema{
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Optional: true,
			},
			resourceLoadBalancerNodeCount: &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
			},
			resourceLoadBalancerSecurityGroupID: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			resourceLoadBalancerVxnetID: &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Default:  "vxnet-0",
				ForceNew: true,
			},
			resourceLoadBalancerHttpHeaderSize: &schema.Schema{
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      15,
				ValidateFunc: withinArrayIntRange(1, 127),
			},
			resourceTagIds:   tagIdsSchema(),
			resourceTagNames: tagNamesSchema(),
		},
	}
}
func resourceQingcloudLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error {
	if err := waitLoadBalancerLease(d, meta); err != nil {
		return err
	}
	d.Partial(true)
	if err := modifyLoadBalancerAttributes(d, meta); err != nil {
		return err
	}
	d.SetPartial(resourceLoadBalancerPrivateIPs)
	d.SetPartial(resourceLoadBalancerHttpHeaderSize)
	d.SetPartial(resourceLoadBalancerSecurityGroupID)
	d.SetPartial(resourceLoadBalancerNodeCount)
	d.SetPartial(resourceName)
	d.SetPartial(resourceDescription)
	if d.HasChange(resourceLoadBalancerEipIDs) && !d.IsNewResource() {
		if err := updateLoadbalancerEips(d, meta); err != nil {
			return err
		}
	}
	d.SetPartial(resourceLoadBalancerEipIDs)
	if d.HasChange(resourceLoadBalancerType) && !d.IsNewResource() {
		if err := resizeLoadBalancer(qc.String(d.Id()), qc.Int(d.Get(resourceLoadBalancerType).(int)), meta); err != nil {
			return err
		}
	}
	d.SetPartial(resourceLoadBalancerType)
	if err := resourceUpdateTag(d, meta, qingcloudResourceTypeLoadBalancer); err != nil {
		return err
	}
	d.Partial(false)
	return resourceQingcloudLoadBalancerRead(d, meta)
}

func resourceQingcloudLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	input := new(qc.CreateLoadBalancerInput)
	input.LoadBalancerName, _ = getNamePointer(d)
	input.VxNet = getSetStringPointer(d, resourceLoadBalancerVxnetID)
	input.SecurityGroup = getSetStringPointer(d, resourceLoadBalancerSecurityGroupID)
	input.HTTPHeaderSize = qc.Int(d.Get(resourceLoadBalancerHttpHeaderSize).(int))
	if d.Get(resourceLoadBalancerNodeCount).(int) != 0 {
		input.NodeCount = qc.Int(d.Get(resourceLoadBalancerNodeCount).(int))
	}
	input.LoadBalancerType = qc.Int(d.Get(resourceLoadBalancerType).(int))
	if _, ok := d.GetOk(resourceLoadBalancerPrivateIPs); ok {
		privateIPs := d.Get(resourceLoadBalancerPrivateIPs).(*schema.Set).List()
		if len(privateIPs) != 1 || d.Get(resourceLoadBalancerVxnetID).(string) == "vxnet-0" {
			return fmt.Errorf("error private_ips info")
		}
		input.PrivateIP = qc.String(privateIPs[0].(string))
	}
	var eips []*string
	for _, value := range d.Get(resourceLoadBalancerEipIDs).(*schema.Set).List() {
		eips = append(eips, qc.String(value.(string)))
	}
	var output *qc.CreateLoadBalancerOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.CreateLoadBalancer(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	d.SetId(qc.StringValue(output.LoadBalancerID))
	if _, err = LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	return resourceQingcloudLoadBalancerUpdate(d, meta)
}
func resourceQingcloudLoadBalancerRead(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	input := new(qc.DescribeLoadBalancersInput)
	input.LoadBalancers = []*string{qc.String(d.Id())}
	input.Verbose = qc.Int(1)
	var output *qc.DescribeLoadBalancersOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.DescribeLoadBalancers(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	if isLoadBalancerDeleted(output.LoadBalancerSet) {
		d.SetId("")
		return nil
	}
	lb := output.LoadBalancerSet[0]
	d.Set(resourceName, qc.StringValue(lb.LoadBalancerName))
	d.Set(resourceDescription, qc.StringValue(lb.Description))
	d.Set(resourceLoadBalancerType, qc.IntValue(lb.LoadBalancerType))
	d.Set(resourceLoadBalancerVxnetID, qc.StringValue(lb.VxNetID))
	d.Set(resourceLoadBalancerPrivateIPs, qc.StringValueSlice(lb.PrivateIPs))
	d.Set(resourceLoadBalancerSecurityGroupID, qc.StringValue(lb.SecurityGroupID))
	d.Set(resourceLoadBalancerNodeCount, qc.IntValue(lb.NodeCount))
	var eipIDs []string
	for _, eip := range lb.Cluster {
		eipIDs = append(eipIDs, qc.StringValue(eip.EIPID))
	}
	d.Set(resourceLoadBalancerEipIDs, eipIDs)
	resourceSetTag(d, lb.Tags)
	return nil
}

func resourceQingcloudLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error {
	clt := meta.(*QingCloudClient).loadbalancer
	if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	if err := waitLoadBalancerLease(d, meta); err != nil {
		return err
	}
	input := new(qc.DeleteLoadBalancersInput)
	input.LoadBalancers = []*string{qc.String(d.Id())}
	var output *qc.DeleteLoadBalancersOutput
	var err error
	simpleRetry(func() error {
		output, err = clt.DeleteLoadBalancers(input)
		return isServerBusy(err)
	})
	if err != nil {
		return err
	}
	if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
		return err
	}
	d.SetId("")
	return nil
}
<|endoftext|>


<commit_before>/*--------------------------------------------------------*\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: https://hprose.com                     |
|                                                          |
| encoding/big_decoder.go                                  |
|                                                          |
| LastModified: Jun 27, 2020                               |
| Author: Ma Bingyao <andot@hprose.com>                    |
|                                                          |
\*________________________________________________________*/

package encoding

import (
	"math"
	"math/big"
	"reflect"

	"github.com/modern-go/reflect2"
)

var (
	bigIntZero   = big.NewInt(0)
	bigIntOne    = big.NewInt(1)
	bigFloatZero = big.NewFloat(0)
	bigFloatOne  = big.NewFloat(1)
	bigRatZero   = big.NewRat(0, 1)
	bigRatOne    = big.NewRat(1, 1)
)

func (dec *Decoder) strToBigInt(s string, t reflect.Type) *big.Int {
	if bi, ok := new(big.Int).SetString(s, 10); ok {
		return bi
	}
	typeName := "*big.Int"
	if t != nil {
		typeName = t.String()
	}
	dec.decodeStringError(s, typeName)
	return nil
}

func (dec *Decoder) strToBigFloat(s string, t reflect.Type) *big.Float {
	if bf, ok := new(big.Float).SetString(s); ok {
		return bf
	}
	typeName := "*big.Float"
	if t != nil {
		typeName = t.String()
	}
	dec.decodeStringError(s, typeName)
	return nil
}

func (dec *Decoder) strToBigRat(s string, t reflect.Type) *big.Rat {
	if bf, ok := new(big.Rat).SetString(s); ok {
		return bf
	}
	dec.decodeStringError(s, t.String())
	return nil
}

func (dec *Decoder) readBigInt(t reflect.Type) *big.Int {
	return dec.strToBigInt(unsafeString(dec.UnsafeUntil(TagSemicolon)), t)
}

func (dec *Decoder) readBigFloat(t reflect.Type) *big.Float {
	return dec.strToBigFloat(unsafeString(dec.UnsafeUntil(TagSemicolon)), t)
}

// ReadBigInt reads *big.Int
func (dec *Decoder) ReadBigInt() *big.Int {
	return dec.readBigInt(nil)
}

// ReadBigFloat reads *big.Float
func (dec *Decoder) ReadBigFloat() *big.Float {
	return dec.readBigFloat(nil)
}

func (dec *Decoder) decodeBigInt(t reflect.Type, tag byte) *big.Int {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewInt(int64(i))
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigIntZero
	case TagTrue:
		return bigIntOne
	case TagInteger:
		return big.NewInt(dec.ReadInt64())
	case TagLong:
		return dec.readBigInt(t)
	case TagDouble:
		if bf := dec.readBigFloat(t); bf != nil {
			bi, _ := bf.Int(nil)
			return bi
		}
	case TagUTF8Char:
		return dec.strToBigInt(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.strToBigInt(dec.ReadUnsafeString(), t)
		}
		return dec.strToBigInt(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigIntValue(t reflect.Type, tag byte) big.Int {
	if i := dec.decodeBigInt(t, tag); i != nil {
		return *i
	}
	return *bigIntZero
}

func (dec *Decoder) decodeBigFloat(t reflect.Type, tag byte) *big.Float {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewFloat(float64(i))
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigFloatZero
	case TagTrue:
		return bigFloatOne
	case TagInteger:
		return big.NewFloat(float64(dec.ReadInt64()))
	case TagLong, TagDouble:
		return dec.readBigFloat(t)
	case TagInfinity:
		if dec.NextByte() == TagNeg {
			return big.NewFloat(math.Inf(-1))
		}
		return big.NewFloat(math.Inf(1))
	case TagUTF8Char:
		return dec.strToBigFloat(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.strToBigFloat(dec.ReadUnsafeString(), t)
		}
		return dec.strToBigFloat(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigFloatValue(t reflect.Type, tag byte) big.Float {
	if f := dec.decodeBigFloat(t, tag); f != nil {
		return *f
	}
	return *bigFloatZero
}

func (dec *Decoder) decodeBigRat(t reflect.Type, tag byte) *big.Rat {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewRat(int64(i), 1)
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigRatZero
	case TagTrue:
		return bigRatOne
	case TagInteger:
		return big.NewRat(dec.ReadInt64(), 1)
	case TagLong:
		return new(big.Rat).SetInt(dec.readBigInt(t))
	case TagDouble:
		return new(big.Rat).SetFloat64(dec.ReadFloat64())
	case TagUTF8Char:
		return dec.strToBigRat(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.strToBigRat(dec.ReadUnsafeString(), t)
		}
		return dec.strToBigRat(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigRatValue(t reflect.Type, tag byte) big.Rat {
	if r := dec.decodeBigRat(t, tag); r != nil {
		return *r
	}
	return *bigRatZero
}

// bigIntValueDecoder is the implementation of ValueDecoder for big.Int.
type bigIntValueDecoder struct{}

func (bigIntValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Int)(reflect2.PtrOf(p)) = dec.decodeBigIntValue(bigIntValueType, tag)
}

func (bigIntValueDecoder) Type() reflect.Type {
	return bigIntValueType
}

// bigIntDecoder is the implementation of ValueDecoder for *big.Int.
type bigIntDecoder struct{}

func (bigIntDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Int)(reflect2.PtrOf(p)) = dec.decodeBigInt(bigIntType, tag)
}

func (bigIntDecoder) Type() reflect.Type {
	return bigIntType
}

// bigFloatValueDecoder is the implementation of ValueDecoder for big.Float.
type bigFloatValueDecoder struct{}

func (bigFloatValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Float)(reflect2.PtrOf(p)) = dec.decodeBigFloatValue(bigFloatValueType, tag)
}

func (bigFloatValueDecoder) Type() reflect.Type {
	return bigFloatValueType
}

// bigFloatDecoder is the implementation of ValueDecoder for *big.Float.
type bigFloatDecoder struct{}

func (bigFloatDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Float)(reflect2.PtrOf(p)) = dec.decodeBigFloat(bigFloatType, tag)
}

func (bigFloatDecoder) Type() reflect.Type {
	return bigFloatType
}

// bigRatValueDecoder is the implementation of ValueDecoder for big.Rat.
type bigRatValueDecoder struct{}

func (bigRatValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Rat)(reflect2.PtrOf(p)) = dec.decodeBigRatValue(bigRatValueType, tag)
}

func (bigRatValueDecoder) Type() reflect.Type {
	return bigRatValueType
}

// bigRatDecoder is the implementation of ValueDecoder for big.Rat/*big.Rat.
type bigRatDecoder struct{}

func (bigRatDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Rat)(reflect2.PtrOf(p)) = dec.decodeBigRat(bigRatType, tag)
}

func (bigRatDecoder) Type() reflect.Type {
	return bigRatType
}

func init() {
	RegisterValueDecoder(bigIntDecoder{})
	RegisterValueDecoder(bigFloatDecoder{})
	RegisterValueDecoder(bigRatDecoder{})
	RegisterValueDecoder(bigIntValueDecoder{})
	RegisterValueDecoder(bigFloatValueDecoder{})
	RegisterValueDecoder(bigRatValueDecoder{})
}
<commit_msg>Update big_decoder.go<commit_after>/*--------------------------------------------------------*\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: https://hprose.com                     |
|                                                          |
| encoding/big_decoder.go                                  |
|                                                          |
| LastModified: Jun 27, 2020                               |
| Author: Ma Bingyao <andot@hprose.com>                    |
|                                                          |
\*________________________________________________________*/

package encoding

import (
	"math"
	"math/big"
	"reflect"

	"github.com/modern-go/reflect2"
)

var (
	bigIntZero   = big.NewInt(0)
	bigIntOne    = big.NewInt(1)
	bigFloatZero = big.NewFloat(0)
	bigFloatOne  = big.NewFloat(1)
	bigRatZero   = big.NewRat(0, 1)
	bigRatOne    = big.NewRat(1, 1)
)

func (dec *Decoder) stringToBigInt(s string, t reflect.Type) *big.Int {
	if bi, ok := new(big.Int).SetString(s, 10); ok {
		return bi
	}
	typeName := "*big.Int"
	if t != nil {
		typeName = t.String()
	}
	dec.decodeStringError(s, typeName)
	return nil
}

func (dec *Decoder) stringToBigFloat(s string, t reflect.Type) *big.Float {
	if bf, ok := new(big.Float).SetString(s); ok {
		return bf
	}
	typeName := "*big.Float"
	if t != nil {
		typeName = t.String()
	}
	dec.decodeStringError(s, typeName)
	return nil
}

func (dec *Decoder) stringToBigRat(s string, t reflect.Type) *big.Rat {
	if bf, ok := new(big.Rat).SetString(s); ok {
		return bf
	}
	dec.decodeStringError(s, t.String())
	return nil
}

func (dec *Decoder) readBigInt(t reflect.Type) *big.Int {
	return dec.stringToBigInt(unsafeString(dec.UnsafeUntil(TagSemicolon)), t)
}

func (dec *Decoder) readBigFloat(t reflect.Type) *big.Float {
	return dec.stringToBigFloat(unsafeString(dec.UnsafeUntil(TagSemicolon)), t)
}

// ReadBigInt reads *big.Int
func (dec *Decoder) ReadBigInt() *big.Int {
	return dec.readBigInt(nil)
}

// ReadBigFloat reads *big.Float
func (dec *Decoder) ReadBigFloat() *big.Float {
	return dec.readBigFloat(nil)
}

func (dec *Decoder) decodeBigInt(t reflect.Type, tag byte) *big.Int {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewInt(int64(i))
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigIntZero
	case TagTrue:
		return bigIntOne
	case TagInteger:
		return big.NewInt(dec.ReadInt64())
	case TagLong:
		return dec.readBigInt(t)
	case TagDouble:
		if bf := dec.readBigFloat(t); bf != nil {
			bi, _ := bf.Int(nil)
			return bi
		}
	case TagUTF8Char:
		return dec.stringToBigInt(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.stringToBigInt(dec.ReadUnsafeString(), t)
		}
		return dec.stringToBigInt(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigIntValue(t reflect.Type, tag byte) big.Int {
	if i := dec.decodeBigInt(t, tag); i != nil {
		return *i
	}
	return *bigIntZero
}

func (dec *Decoder) decodeBigFloat(t reflect.Type, tag byte) *big.Float {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewFloat(float64(i))
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigFloatZero
	case TagTrue:
		return bigFloatOne
	case TagInteger:
		return big.NewFloat(float64(dec.ReadInt64()))
	case TagLong, TagDouble:
		return dec.readBigFloat(t)
	case TagInfinity:
		if dec.NextByte() == TagNeg {
			return big.NewFloat(math.Inf(-1))
		}
		return big.NewFloat(math.Inf(1))
	case TagUTF8Char:
		return dec.stringToBigFloat(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.stringToBigFloat(dec.ReadUnsafeString(), t)
		}
		return dec.stringToBigFloat(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigFloatValue(t reflect.Type, tag byte) big.Float {
	if f := dec.decodeBigFloat(t, tag); f != nil {
		return *f
	}
	return *bigFloatZero
}

func (dec *Decoder) decodeBigRat(t reflect.Type, tag byte) *big.Rat {
	if i := intDigits[tag]; i != invalidDigit {
		return big.NewRat(int64(i), 1)
	}
	switch tag {
	case TagNull:
		return nil
	case TagEmpty, TagFalse:
		return bigRatZero
	case TagTrue:
		return bigRatOne
	case TagInteger:
		return big.NewRat(dec.ReadInt64(), 1)
	case TagLong:
		return new(big.Rat).SetInt(dec.readBigInt(t))
	case TagDouble:
		return new(big.Rat).SetFloat64(dec.ReadFloat64())
	case TagUTF8Char:
		return dec.stringToBigRat(dec.readUnsafeString(1), t)
	case TagString:
		if dec.IsSimple() {
			return dec.stringToBigRat(dec.ReadUnsafeString(), t)
		}
		return dec.stringToBigRat(dec.ReadString(), t)
	default:
		dec.decodeError(t, tag)
	}
	return nil
}

func (dec *Decoder) decodeBigRatValue(t reflect.Type, tag byte) big.Rat {
	if r := dec.decodeBigRat(t, tag); r != nil {
		return *r
	}
	return *bigRatZero
}

// bigIntValueDecoder is the implementation of ValueDecoder for big.Int.
type bigIntValueDecoder struct{}

func (bigIntValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Int)(reflect2.PtrOf(p)) = dec.decodeBigIntValue(bigIntValueType, tag)
}

func (bigIntValueDecoder) Type() reflect.Type {
	return bigIntValueType
}

// bigIntDecoder is the implementation of ValueDecoder for *big.Int.
type bigIntDecoder struct{}

func (bigIntDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Int)(reflect2.PtrOf(p)) = dec.decodeBigInt(bigIntType, tag)
}

func (bigIntDecoder) Type() reflect.Type {
	return bigIntType
}

// bigFloatValueDecoder is the implementation of ValueDecoder for big.Float.
type bigFloatValueDecoder struct{}

func (bigFloatValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Float)(reflect2.PtrOf(p)) = dec.decodeBigFloatValue(bigFloatValueType, tag)
}

func (bigFloatValueDecoder) Type() reflect.Type {
	return bigFloatValueType
}

// bigFloatDecoder is the implementation of ValueDecoder for *big.Float.
type bigFloatDecoder struct{}

func (bigFloatDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Float)(reflect2.PtrOf(p)) = dec.decodeBigFloat(bigFloatType, tag)
}

func (bigFloatDecoder) Type() reflect.Type {
	return bigFloatType
}

// bigRatValueDecoder is the implementation of ValueDecoder for big.Rat.
type bigRatValueDecoder struct{}

func (bigRatValueDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(*big.Rat)(reflect2.PtrOf(p)) = dec.decodeBigRatValue(bigRatValueType, tag)
}

func (bigRatValueDecoder) Type() reflect.Type {
	return bigRatValueType
}

// bigRatDecoder is the implementation of ValueDecoder for big.Rat/*big.Rat.
type bigRatDecoder struct{}

func (bigRatDecoder) Decode(dec *Decoder, p interface{}, tag byte) {
	*(**big.Rat)(reflect2.PtrOf(p)) = dec.decodeBigRat(bigRatType, tag)
}

func (bigRatDecoder) Type() reflect.Type {
	return bigRatType
}

func init() {
	RegisterValueDecoder(bigIntDecoder{})
	RegisterValueDecoder(bigFloatDecoder{})
	RegisterValueDecoder(bigRatDecoder{})
	RegisterValueDecoder(bigIntValueDecoder{})
	RegisterValueDecoder(bigFloatValueDecoder{})
	RegisterValueDecoder(bigRatValueDecoder{})
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package auth

import (
	"context"
	"fmt"
	netutil "k8s.io/utils/net"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/pkg/cluster/ports"
	"k8s.io/kubernetes/test/e2e/framework"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	e2enode "k8s.io/kubernetes/test/e2e/framework/node"
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
)

var _ = SIGDescribe("[Feature:NodeAuthenticator]", func() {

	f := framework.NewDefaultFramework("node-authn")
	var ns string
	var nodeIPs []string
	ginkgo.BeforeEach(func() {
		ns = f.Namespace.Name

		nodeList, err := f.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
		framework.ExpectNoError(err, "failed to list nodes in namespace: %s", ns)
		framework.ExpectNotEqual(len(nodeList.Items), 0)

		pickedNode := nodeList.Items[0]
		nodeIPs = e2enode.GetAddresses(&pickedNode, v1.NodeExternalIP)
		// The pods running in the cluster can see the internal addresses.
		nodeIPs = append(nodeIPs, e2enode.GetAddresses(&pickedNode, v1.NodeInternalIP)...)

		// make sure ServiceAccount admission controller is enabled, so secret generation on SA creation works
		saName := "default"
		sa, err := f.ClientSet.CoreV1().ServiceAccounts(ns).Get(context.TODO(), saName, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to retrieve service account (%s:%s)", ns, saName)
		framework.ExpectNotEqual(len(sa.Secrets), 0)

	})

	ginkgo.It("The kubelet's main port 10250 should reject requests with no credentials", func() {
		pod := createNodeAuthTestPod(f)
		for _, nodeIP := range nodeIPs {
			// Anonymous authentication is disabled by default
			nodeIP = getFormattedNodeIP(nodeIP)
			result := framework.RunHostCmdOrDie(ns, pod.Name, fmt.Sprintf("curl -sIk -o /dev/null -w '%s' https://%s:%v/metrics", "%{http_code}", nodeIP, ports.KubeletPort))
			gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet's main port 10250 should reject requests with no credentials")
		}
	})

	ginkgo.It("The kubelet can delegate ServiceAccount tokens to the API server", func() {
		ginkgo.By("create a new ServiceAccount for authentication")
		trueValue := true
		newSA := &v1.ServiceAccount{
			ObjectMeta: metav1.ObjectMeta{
				Namespace: ns,
				Name:      "node-auth-newsa",
			},
			AutomountServiceAccountToken: &trueValue,
		}
		_, err := f.ClientSet.CoreV1().ServiceAccounts(ns).Create(context.TODO(), newSA, metav1.CreateOptions{})
		framework.ExpectNoError(err, "failed to create service account (%s:%s)", ns, newSA.Name)

		pod := createNodeAuthTestPod(f)

		for _, nodeIP := range nodeIPs {
			nodeIP = getFormattedNodeIP(nodeIP)
			result := framework.RunHostCmdOrDie(ns,
				pod.Name,
				fmt.Sprintf("curl -sIk -o /dev/null -w '%s' --header \"Authorization: Bearer `%s`\" https://%s:%v/metrics",
					"%{http_code}",
					"cat /var/run/secrets/kubernetes.io/serviceaccount/token",
					nodeIP, ports.KubeletPort))
			gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet can delegate ServiceAccount tokens to the API server")
		}
	})
})

func getFormattedNodeIP(nodeIP string) string {
	if netutil.IsIPv6String(nodeIP) {
		return fmt.Sprintf("[%s]", nodeIP)
	}
	return nodeIP
}

func createNodeAuthTestPod(f *framework.Framework) *v1.Pod {
	pod := e2epod.NewAgnhostPod(f.Namespace.Name, "agnhost-pod", nil, nil, nil)
	pod.ObjectMeta.GenerateName = "test-node-authn-"
	return f.PodClient().CreateSync(pod)
}
<commit_msg>Use builtin JoinHostPort function<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package auth

import (
	"context"
	"fmt"
	"net"
	"strconv"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/pkg/cluster/ports"
	"k8s.io/kubernetes/test/e2e/framework"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	e2enode "k8s.io/kubernetes/test/e2e/framework/node"
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
)

var _ = SIGDescribe("[Feature:NodeAuthenticator]", func() {

	f := framework.NewDefaultFramework("node-authn")
	var ns string
	var nodeIPs []string
	ginkgo.BeforeEach(func() {
		ns = f.Namespace.Name

		nodeList, err := f.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
		framework.ExpectNoError(err, "failed to list nodes in namespace: %s", ns)
		framework.ExpectNotEqual(len(nodeList.Items), 0)

		pickedNode := nodeList.Items[0]
		nodeIPs = e2enode.GetAddresses(&pickedNode, v1.NodeExternalIP)
		// The pods running in the cluster can see the internal addresses.
		nodeIPs = append(nodeIPs, e2enode.GetAddresses(&pickedNode, v1.NodeInternalIP)...)

		// make sure ServiceAccount admission controller is enabled, so secret generation on SA creation works
		saName := "default"
		sa, err := f.ClientSet.CoreV1().ServiceAccounts(ns).Get(context.TODO(), saName, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to retrieve service account (%s:%s)", ns, saName)
		framework.ExpectNotEqual(len(sa.Secrets), 0)

	})

	ginkgo.It("The kubelet's main port 10250 should reject requests with no credentials", func() {
		pod := createNodeAuthTestPod(f)
		for _, nodeIP := range nodeIPs {
			// Anonymous authentication is disabled by default
			host := net.JoinHostPort(nodeIP, strconv.Itoa(ports.KubeletPort))
			result := framework.RunHostCmdOrDie(ns, pod.Name, fmt.Sprintf("curl -sIk -o /dev/null -w '%s' https://%s/metrics", "%{http_code}", host))
			gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet's main port 10250 should reject requests with no credentials")
		}
	})

	ginkgo.It("The kubelet can delegate ServiceAccount tokens to the API server", func() {
		ginkgo.By("create a new ServiceAccount for authentication")
		trueValue := true
		newSA := &v1.ServiceAccount{
			ObjectMeta: metav1.ObjectMeta{
				Namespace: ns,
				Name:      "node-auth-newsa",
			},
			AutomountServiceAccountToken: &trueValue,
		}
		_, err := f.ClientSet.CoreV1().ServiceAccounts(ns).Create(context.TODO(), newSA, metav1.CreateOptions{})
		framework.ExpectNoError(err, "failed to create service account (%s:%s)", ns, newSA.Name)

		pod := createNodeAuthTestPod(f)

		for _, nodeIP := range nodeIPs {
			host := net.JoinHostPort(nodeIP, strconv.Itoa(ports.KubeletPort))
			result := framework.RunHostCmdOrDie(ns,
				pod.Name,
				fmt.Sprintf("curl -sIk -o /dev/null -w '%s' --header \"Authorization: Bearer `%s`\" https://%s/metrics",
					"%{http_code}",
					"cat /var/run/secrets/kubernetes.io/serviceaccount/token",
					host))
			gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet can delegate ServiceAccount tokens to the API server")
		}
	})
})

func createNodeAuthTestPod(f *framework.Framework) *v1.Pod {
	pod := e2epod.NewAgnhostPod(f.Namespace.Name, "agnhost-pod", nil, nil, nil)
	pod.ObjectMeta.GenerateName = "test-node-authn-"
	return f.PodClient().CreateSync(pod)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsMainRouteTableAssociation() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsMainRouteTableAssociationCreate,
		Read:   resourceAwsMainRouteTableAssociationRead,
		Update: resourceAwsMainRouteTableAssociationUpdate,
		Delete: resourceAwsMainRouteTableAssociationDelete,

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

			"route_table_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			// We use this field to record the main route table that is automatically
			// created when the VPC is created. We need this to be able to "destroy"
			// our main route table association, which we do by returning this route
			// table to its original place as the Main Route Table for the VPC.
			"original_route_table_id": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsMainRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	routeTableId := d.Get("route_table_id").(string)

	log.Printf("[INFO] Creating main route table association: %s => %s", vpcId, routeTableId)

	mainAssociation, err := findMainRouteTableAssociation(conn, vpcId)
	if err != nil {
		return err
	}

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: mainAssociation.RouteTableAssociationID,
		RouteTableID:  aws.String(routeTableId),
	})
	if err != nil {
		return err
	}

	d.Set("original_route_table_id", mainAssociation.RouteTableID)
	d.SetId(*resp.NewAssociationID)
	log.Printf("[INFO] New main route table association ID: %s", d.Id())

	return nil
}

func resourceAwsMainRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	mainAssociation, err := findMainRouteTableAssociation(
		conn,
		d.Get("vpc_id").(string))
	if err != nil {
		return err
	}

	if *mainAssociation.RouteTableAssociationID != d.Id() {
		// It seems it doesn't exist anymore, so clear the ID
		d.SetId("")
	}

	return nil
}

// Update is almost exactly like Create, except we want to retain the
// original_route_table_id - this needs to stay recorded as the AWS-created
// table from VPC creation.
func resourceAwsMainRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	routeTableId := d.Get("route_table_id").(string)

	log.Printf("[INFO] Updating main route table association: %s => %s", vpcId, routeTableId)

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: aws.String(d.Id()),
		RouteTableID:  aws.String(routeTableId),
	})
	if err != nil {
		return err
	}

	d.SetId(*resp.NewAssociationID)
	log.Printf("[INFO] New main route table association ID: %s", d.Id())

	return nil
}

func resourceAwsMainRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	originalRouteTableId := d.Get("original_route_table_id").(string)

	log.Printf("[INFO] Deleting main route table association by resetting Main Route Table for VPC: %s to its original Route Table: %s",
		vpcId,
		originalRouteTableId)

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: aws.String(d.Id()),
		RouteTableID:  aws.String(originalRouteTableId),
	})
	if err != nil {
		return err
	}

	log.Printf("[INFO] Resulting Association ID: %s", *resp.NewAssociationID)

	return nil
}

func findMainRouteTableAssociation(conn *ec2.EC2, vpcId string) (*ec2.RouteTableAssociation, error) {
	mainRouteTable, err := findMainRouteTable(conn, vpcId)
	if err != nil {
		return nil, err
	}

	for _, a := range mainRouteTable.Associations {
		if *a.Main {
			return a, nil
		}
	}
	return nil, fmt.Errorf("Could not find main routing table association for VPC: %s", vpcId)
}

func findMainRouteTable(conn *ec2.EC2, vpcId string) (*ec2.RouteTable, error) {
	mainFilter := &ec2.Filter{
		Name:   aws.String("association.main"),
		Values: []*string{aws.String("true")},
	}
	vpcFilter := &ec2.Filter{
		Name:   aws.String("vpc-id"),
		Values: []*string{aws.String(vpcId)},
	}
	routeResp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
		Filters: []*ec2.Filter{mainFilter, vpcFilter},
	})
	if err != nil {
		return nil, err
	} else if len(routeResp.RouteTables) != 1 {
		return nil, fmt.Errorf(
			"Expected to find a single main routing table for VPC: %s, but found %d",
			vpcId,
			len(routeResp.RouteTables))
	}

	return routeResp.RouteTables[0], nil
}
<commit_msg>provider/aws: main route table refresh handles VPC being gone [GH-1806]<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsMainRouteTableAssociation() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsMainRouteTableAssociationCreate,
		Read:   resourceAwsMainRouteTableAssociationRead,
		Update: resourceAwsMainRouteTableAssociationUpdate,
		Delete: resourceAwsMainRouteTableAssociationDelete,

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

			"route_table_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			// We use this field to record the main route table that is automatically
			// created when the VPC is created. We need this to be able to "destroy"
			// our main route table association, which we do by returning this route
			// table to its original place as the Main Route Table for the VPC.
			"original_route_table_id": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsMainRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	routeTableId := d.Get("route_table_id").(string)

	log.Printf("[INFO] Creating main route table association: %s => %s", vpcId, routeTableId)

	mainAssociation, err := findMainRouteTableAssociation(conn, vpcId)
	if err != nil {
		return err
	}

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: mainAssociation.RouteTableAssociationID,
		RouteTableID:  aws.String(routeTableId),
	})
	if err != nil {
		return err
	}

	d.Set("original_route_table_id", mainAssociation.RouteTableID)
	d.SetId(*resp.NewAssociationID)
	log.Printf("[INFO] New main route table association ID: %s", d.Id())

	return nil
}

func resourceAwsMainRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	mainAssociation, err := findMainRouteTableAssociation(
		conn,
		d.Get("vpc_id").(string))
	if err != nil {
		return err
	}

	if mainAssociation == nil || *mainAssociation.RouteTableAssociationID != d.Id() {
		// It seems it doesn't exist anymore, so clear the ID
		d.SetId("")
	}

	return nil
}

// Update is almost exactly like Create, except we want to retain the
// original_route_table_id - this needs to stay recorded as the AWS-created
// table from VPC creation.
func resourceAwsMainRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	routeTableId := d.Get("route_table_id").(string)

	log.Printf("[INFO] Updating main route table association: %s => %s", vpcId, routeTableId)

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: aws.String(d.Id()),
		RouteTableID:  aws.String(routeTableId),
	})
	if err != nil {
		return err
	}

	d.SetId(*resp.NewAssociationID)
	log.Printf("[INFO] New main route table association ID: %s", d.Id())

	return nil
}

func resourceAwsMainRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	vpcId := d.Get("vpc_id").(string)
	originalRouteTableId := d.Get("original_route_table_id").(string)

	log.Printf("[INFO] Deleting main route table association by resetting Main Route Table for VPC: %s to its original Route Table: %s",
		vpcId,
		originalRouteTableId)

	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
		AssociationID: aws.String(d.Id()),
		RouteTableID:  aws.String(originalRouteTableId),
	})
	if err != nil {
		return err
	}

	log.Printf("[INFO] Resulting Association ID: %s", *resp.NewAssociationID)

	return nil
}

func findMainRouteTableAssociation(conn *ec2.EC2, vpcId string) (*ec2.RouteTableAssociation, error) {
	mainRouteTable, err := findMainRouteTable(conn, vpcId)
	if err != nil {
		return nil, err
	}
	if mainRouteTable == nil {
		return nil, nil
	}

	for _, a := range mainRouteTable.Associations {
		if *a.Main {
			return a, nil
		}
	}
	return nil, fmt.Errorf("Could not find main routing table association for VPC: %s", vpcId)
}

func findMainRouteTable(conn *ec2.EC2, vpcId string) (*ec2.RouteTable, error) {
	mainFilter := &ec2.Filter{
		Name:   aws.String("association.main"),
		Values: []*string{aws.String("true")},
	}
	vpcFilter := &ec2.Filter{
		Name:   aws.String("vpc-id"),
		Values: []*string{aws.String(vpcId)},
	}
	routeResp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
		Filters: []*ec2.Filter{mainFilter, vpcFilter},
	})
	if err != nil {
		return nil, err
	} else if len(routeResp.RouteTables) != 1 {
		return nil, nil
	}

	return routeResp.RouteTables[0], nil
}
<|endoftext|>