<commit_before>package aws

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/docdb"
)

func TestAccAWSDocDBSubnetGroup_basic(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "Managed by Terraform"),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.foo",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_disappears(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					testAccCheckAWSDocDBSubnetGroupDisappears(&v),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_namePrefix(t *testing.T) {
	var v docdb.DBSubnetGroup

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig_namePrefix,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.test", &v),
					resource.TestMatchResourceAttr(
						"aws_docdb_subnet_group.test", "name", regexp.MustCompile("^tf_test-")),
				),
			},
			{
				ResourceName:            "aws_docdb_subnet_group.test",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"name_prefix"},
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_generatedName(t *testing.T) {
	var v docdb.DBSubnetGroup

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig_generatedName,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.test", &v),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.test",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_updateDescription(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "Managed by Terraform"),
				),
			},

			{
				Config: testAccDocDBSubnetGroupConfig_updatedDescription(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "foo description updated"),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.foo",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckDocDBSubnetGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).docdbconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_docdb_subnet_group" {
			continue
		}

		// Try to find the resource
		resp, err := conn.DescribeDBSubnetGroups(
			&docdb.DescribeDBSubnetGroupsInput{DBSubnetGroupName: aws.String(rs.Primary.ID)})

		if err == nil {
			if len(resp.DBSubnetGroups) != 0 &&
				aws.StringValue(resp.DBSubnetGroups[0].DBSubnetGroupName) == rs.Primary.ID {
				return fmt.Errorf("DocDB Subnet Group %s still exists", rs.Primary.ID)
			}
		}

		if err != nil {
			if isAWSErr(err, docdb.ErrCodeDBSubnetGroupNotFoundFault, "") {
				return nil
			}
			return err
		}
	}

	return nil
}

func testAccCheckAWSDocDBSubnetGroupDisappears(group *docdb.DBSubnetGroup) resource.TestCheckFunc {

	return func(s *terraform.State) error {
		conn := testAccProvider.Meta().(*AWSClient).docdbconn

		params := &docdb.DeleteDBSubnetGroupInput{
			DBSubnetGroupName: group.DBSubnetGroupName,
		}

		_, err := conn.DeleteDBSubnetGroup(params)
		if err != nil {
			return err
		}

		return waitForDocDBSubnetGroupDeletion(conn, *group.DBSubnetGroupName)
	}
}

func testAccCheckDocDBSubnetGroupExists(n string, v *docdb.DBSubnetGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).docdbconn
		resp, err := conn.DescribeDBSubnetGroups(
			&docdb.DescribeDBSubnetGroupsInput{DBSubnetGroupName: aws.String(rs.Primary.ID)})
		if err != nil {
			return err
		}
		if len(resp.DBSubnetGroups) == 0 {
			return fmt.Errorf("DbSubnetGroup not found")
		}

		*v = *resp.DBSubnetGroups[0]

		return nil
	}
}

func testAccDocDBSubnetGroupConfig(rName string) string {
	return fmt.Sprintf(`
resource "aws_vpc" "foo" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group"
  }
}

resource "aws_subnet" "foo" {
  cidr_block        = "10.1.1.0/24"
  availability_zone = "us-west-2a"
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-1"
  }
}

resource "aws_subnet" "bar" {
  cidr_block        = "10.1.2.0/24"
  availability_zone = "us-west-2b"
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-2"
  }
}

resource "aws_docdb_subnet_group" "foo" {
  name       = "%s"
  subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id]

  tags = {
    Name = "tf-docdb-subnet-group-test"
  }
}
`, rName)
}

func testAccDocDBSubnetGroupConfig_updatedDescription(rName string) string {
	return fmt.Sprintf(`
resource "aws_vpc" "foo" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group"
  }
}

resource "aws_subnet" "foo" {
  cidr_block        = "10.1.1.0/24"
  availability_zone = "us-west-2a"
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-1"
  }
}

resource "aws_subnet" "bar" {
  cidr_block        = "10.1.2.0/24"
  availability_zone = "us-west-2b"
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-2"
  }
}

resource "aws_docdb_subnet_group" "foo" {
  name        = "%s"
  description = "foo description updated"
  subnet_ids  = [aws_subnet.foo.id, aws_subnet.bar.id]

  tags = {
    Name = "tf-docdb-subnet-group-test"
  }
}
`, rName)
}

const testAccDocDBSubnetGroupConfig_namePrefix = `
resource "aws_vpc" "test" {
  cidr_block = "10.1.0.0/16"
  tags = {
    Name = "terraform-testacc-docdb-subnet-group-name-prefix"
  }
}

resource "aws_subnet" "a" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.1.0/24"
  availability_zone = "us-west-2a"
  tags = {
    Name = "tf-acc-docdb-subnet-group-name-prefix-a"
  }
}

resource "aws_subnet" "b" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.2.0/24"
  availability_zone = "us-west-2b"
  tags = {
    Name = "tf-acc-docdb-subnet-group-name-prefix-b"
  }
}

resource "aws_docdb_subnet_group" "test" {
  name_prefix = "tf_test-"
  subnet_ids  = [aws_subnet.a.id, aws_subnet.b.id]
}`

const testAccDocDBSubnetGroupConfig_generatedName = `
resource "aws_vpc" "test" {
  cidr_block = "10.1.0.0/16"
  tags = {
    Name = "terraform-testacc-docdb-subnet-group-generated-name"
  }
}

resource "aws_subnet" "a" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.1.0/24"
  availability_zone = "us-west-2a"
  tags = {
    Name = "tf-acc-docdb-subnet-group-generated-name-a"
  }
}

resource "aws_subnet" "b" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.2.0/24"
  availability_zone = "us-west-2b"
  tags = {
    Name = "tf-acc-docdb-subnet-group-generated-name-a"
  }
}

resource "aws_docdb_subnet_group" "test" {
  subnet_ids = [aws_subnet.a.id, aws_subnet.b.id]
}`
<commit_msg>tests/provider: Fix hardcoded AZs (docdb subnet)<commit_after>package aws

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/docdb"
)

func TestAccAWSDocDBSubnetGroup_basic(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "name", rName),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "Managed by Terraform"),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.foo",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_disappears(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					testAccCheckAWSDocDBSubnetGroupDisappears(&v),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_namePrefix(t *testing.T) {
	var v docdb.DBSubnetGroup

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig_namePrefix(),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.test", &v),
					resource.TestMatchResourceAttr(
						"aws_docdb_subnet_group.test", "name", regexp.MustCompile("^tf_test-")),
				),
			},
			{
				ResourceName:            "aws_docdb_subnet_group.test",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"name_prefix"},
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_generatedName(t *testing.T) {
	var v docdb.DBSubnetGroup

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig_generatedName(),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.test", &v),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.test",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSDocDBSubnetGroup_updateDescription(t *testing.T) {
	var v docdb.DBSubnetGroup

	rName := fmt.Sprintf("tf-test-%d", acctest.RandInt())

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckDocDBSubnetGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccDocDBSubnetGroupConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "Managed by Terraform"),
				),
			},

			{
				Config: testAccDocDBSubnetGroupConfig_updatedDescription(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckDocDBSubnetGroupExists(
						"aws_docdb_subnet_group.foo", &v),
					resource.TestCheckResourceAttr(
						"aws_docdb_subnet_group.foo", "description", "foo description updated"),
				),
			},
			{
				ResourceName:      "aws_docdb_subnet_group.foo",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckDocDBSubnetGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).docdbconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_docdb_subnet_group" {
			continue
		}

		// Try to find the resource
		resp, err := conn.DescribeDBSubnetGroups(
			&docdb.DescribeDBSubnetGroupsInput{DBSubnetGroupName: aws.String(rs.Primary.ID)})

		if err == nil {
			if len(resp.DBSubnetGroups) != 0 &&
				aws.StringValue(resp.DBSubnetGroups[0].DBSubnetGroupName) == rs.Primary.ID {
				return fmt.Errorf("DocDB Subnet Group %s still exists", rs.Primary.ID)
			}
		}

		if err != nil {
			if isAWSErr(err, docdb.ErrCodeDBSubnetGroupNotFoundFault, "") {
				return nil
			}
			return err
		}
	}

	return nil
}

func testAccCheckAWSDocDBSubnetGroupDisappears(group *docdb.DBSubnetGroup) resource.TestCheckFunc {

	return func(s *terraform.State) error {
		conn := testAccProvider.Meta().(*AWSClient).docdbconn

		params := &docdb.DeleteDBSubnetGroupInput{
			DBSubnetGroupName: group.DBSubnetGroupName,
		}

		_, err := conn.DeleteDBSubnetGroup(params)
		if err != nil {
			return err
		}

		return waitForDocDBSubnetGroupDeletion(conn, *group.DBSubnetGroupName)
	}
}

func testAccCheckDocDBSubnetGroupExists(n string, v *docdb.DBSubnetGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).docdbconn
		resp, err := conn.DescribeDBSubnetGroups(
			&docdb.DescribeDBSubnetGroupsInput{DBSubnetGroupName: aws.String(rs.Primary.ID)})
		if err != nil {
			return err
		}
		if len(resp.DBSubnetGroups) == 0 {
			return fmt.Errorf("DbSubnetGroup not found")
		}

		*v = *resp.DBSubnetGroups[0]

		return nil
	}
}

func testAccDocDBSubnetGroupConfig(rName string) string {
	return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(`
resource "aws_vpc" "foo" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group"
  }
}

resource "aws_subnet" "foo" {
  cidr_block        = "10.1.1.0/24"
  availability_zone = data.aws_availability_zones.available.names[0]
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-1"
  }
}

resource "aws_subnet" "bar" {
  cidr_block        = "10.1.2.0/24"
  availability_zone = data.aws_availability_zones.available.names[1]
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-2"
  }
}

resource "aws_docdb_subnet_group" "foo" {
  name       = "%s"
  subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id]

  tags = {
    Name = "tf-docdb-subnet-group-test"
  }
}
`, rName))
}

func testAccDocDBSubnetGroupConfig_updatedDescription(rName string) string {
	return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(`
resource "aws_vpc" "foo" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group"
  }
}

resource "aws_subnet" "foo" {
  cidr_block        = "10.1.1.0/24"
  availability_zone = data.aws_availability_zones.available.names[0]
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-1"
  }
}

resource "aws_subnet" "bar" {
  cidr_block        = "10.1.2.0/24"
  availability_zone = data.aws_availability_zones.available.names[1]
  vpc_id            = aws_vpc.foo.id

  tags = {
    Name = "tf-acc-docdb-subnet-group-2"
  }
}

resource "aws_docdb_subnet_group" "foo" {
  name        = "%s"
  description = "foo description updated"
  subnet_ids  = [aws_subnet.foo.id, aws_subnet.bar.id]

  tags = {
    Name = "tf-docdb-subnet-group-test"
  }
}
`, rName))
}

func testAccDocDBSubnetGroupConfig_namePrefix() string {
	return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(`
resource "aws_vpc" "test" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group-name-prefix"
  }
}

resource "aws_subnet" "a" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.1.0/24"
  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    Name = "tf-acc-docdb-subnet-group-name-prefix-a"
  }
}

resource "aws_subnet" "b" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.2.0/24"
  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    Name = "tf-acc-docdb-subnet-group-name-prefix-b"
  }
}

resource "aws_docdb_subnet_group" "test" {
  name_prefix = "tf_test-"
  subnet_ids  = [aws_subnet.a.id, aws_subnet.b.id]
}`))
}

func testAccDocDBSubnetGroupConfig_generatedName() string {
	return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf(`
resource "aws_vpc" "test" {
  cidr_block = "10.1.0.0/16"

  tags = {
    Name = "terraform-testacc-docdb-subnet-group-generated-name"
  }
}

resource "aws_subnet" "a" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.1.0/24"
  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    Name = "tf-acc-docdb-subnet-group-generated-name-a"
  }
}

resource "aws_subnet" "b" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.1.2.0/24"
  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    Name = "tf-acc-docdb-subnet-group-generated-name-a"
  }
}

resource "aws_docdb_subnet_group" "test" {
  subnet_ids = [aws_subnet.a.id, aws_subnet.b.id]
}`))
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSSSMPatchBaseline_basic(t *testing.T) {
	var before, after ssm.PatchBaselineIdentity
	name := acctest.RandString(10)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSSMPatchBaselineBasicConfig(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &before),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("patch-baseline-%s", name)),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches_compliance_level", ssm.PatchComplianceLevelCritical),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "description", "Baseline containing all updates approved for production systems"),
				),
			},
			{
				Config: testAccAWSSSMPatchBaselineBasicConfigUpdated(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &after),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2291496788", "KB456789"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("updated-patch-baseline-%s", name)),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches_compliance_level", ssm.PatchComplianceLevelHigh),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "description", "Baseline containing all updates approved for production systems - August 2017"),
					func(*terraform.State) error {
						if *before.BaselineId != *after.BaselineId {
							t.Fatal("Baseline IDs changed unexpectedly")
						}
						return nil
					},
				),
			},
		},
	})
}

func TestAccAWSSSMPatchBaselineWithOperatingSystem(t *testing.T) {
	var before, after ssm.PatchBaselineIdentity
	name := acctest.RandString(10)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSSMPatchBaselineConfigWithOperatingSystem(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &before),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.approve_after_days", "7"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.patch_filter.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.compliance_level", ssm.PatchComplianceLevelCritical),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.enable_non_security", "true"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "operating_system", "AMAZON_LINUX"),
				),
			},
			{
				Config: testAccAWSSSMPatchBaselineConfigWithOperatingSystemUpdated(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &after),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.approve_after_days", "7"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.patch_filter.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.compliance_level", ssm.PatchComplianceLevelInformational),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "operating_system", ssm.OperatingSystemWindows),
					testAccCheckAwsSsmPatchBaselineRecreated(t, &before, &after),
				),
			},
		},
	})
}

func testAccCheckAwsSsmPatchBaselineRecreated(t *testing.T,
	before, after *ssm.PatchBaselineIdentity) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if *before.BaselineId == *after.BaselineId {
			t.Fatalf("Expected change of SSM Patch Baseline IDs, but both were %v", *before.BaselineId)
		}
		return nil
	}
}

func testAccCheckAWSSSMPatchBaselineExists(n string, patch *ssm.PatchBaselineIdentity) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No SSM Patch Baseline ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ssmconn

		resp, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
			Filters: []*ssm.PatchOrchestratorFilter{
				{
					Key:    aws.String("NAME_PREFIX"),
					Values: []*string{aws.String(rs.Primary.Attributes["name"])},
				},
			},
		})

		for _, i := range resp.BaselineIdentities {
			if *i.BaselineId == rs.Primary.ID {
				*patch = *i
				return nil
			}
		}
		if err != nil {
			return err
		}

		return fmt.Errorf("No AWS SSM Patch Baseline found")
	}
}

func testAccCheckAWSSSMPatchBaselineDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ssmconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ssm_patch_baseline" {
			continue
		}

		out, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
			Filters: []*ssm.PatchOrchestratorFilter{
				{
					Key:    aws.String("NAME_PREFIX"),
					Values: []*string{aws.String(rs.Primary.Attributes["name"])},
				},
			},
		})

		if err != nil {
			return err
		}

		if len(out.BaselineIdentities) > 0 {
			return fmt.Errorf("Expected AWS SSM Patch Baseline to be gone, but was still found")
		}

		return nil
	}

	return nil
}

func testAccAWSSSMPatchBaselineBasicConfig(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  description = "Baseline containing all updates approved for production systems"
  approved_patches = ["KB123456"]
  approved_patches_compliance_level = "CRITICAL"
}

`, rName)
}

func testAccAWSSSMPatchBaselineBasicConfigUpdated(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "updated-patch-baseline-%s"
  description = "Baseline containing all updates approved for production systems - August 2017"
  approved_patches = ["KB123456","KB456789"]
  approved_patches_compliance_level = "HIGH"
}

`, rName)
}

func testAccAWSSSMPatchBaselineConfigWithOperatingSystem(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  operating_system = "AMAZON_LINUX"
  description = "Baseline containing all updates approved for production systems"
  approval_rule {
  	approve_after_days = 7
	enable_non_security = true
  	compliance_level = "CRITICAL"

  	patch_filter {
		key = "PRODUCT"
		values = ["AmazonLinux2016.03","AmazonLinux2016.09","AmazonLinux2017.03","AmazonLinux2017.09"]
  	}

  	patch_filter {
		key = "SEVERITY"
		values = ["Critical","Important"]
  	}
  }
}

`, rName)
}

func testAccAWSSSMPatchBaselineConfigWithOperatingSystemUpdated(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  operating_system = "WINDOWS"
  description = "Baseline containing all updates approved for production systems"
  approval_rule {
  	approve_after_days = 7
  	compliance_level = "INFORMATIONAL"

  	patch_filter {
		key = "PRODUCT"
		values = ["WindowsServer2012R2"]
  	}

  	patch_filter {
		key = "MSRC_SEVERITY"
		values = ["Critical","Important"]
  	}
  }
}

`, rName)
}
<commit_msg>add acceptance test<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSSSMPatchBaseline_basic(t *testing.T) {
	var before, after ssm.PatchBaselineIdentity
	name := acctest.RandString(10)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSSMPatchBaselineBasicConfig(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &before),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("patch-baseline-%s", name)),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches_compliance_level", ssm.PatchComplianceLevelCritical),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "description", "Baseline containing all updates approved for production systems"),
				),
			},
			{
				Config: testAccAWSSSMPatchBaselineBasicConfigUpdated(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &after),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2062620480", "KB123456"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches.2291496788", "KB456789"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "name", fmt.Sprintf("updated-patch-baseline-%s", name)),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approved_patches_compliance_level", ssm.PatchComplianceLevelHigh),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "description", "Baseline containing all updates approved for production systems - August 2017"),
					func(*terraform.State) error {
						if *before.BaselineId != *after.BaselineId {
							t.Fatal("Baseline IDs changed unexpectedly")
						}
						return nil
					},
				),
			},
		},
	})
}

func TestAccAWSSSMPatchBaseline_disappears(t *testing.T) {
	var identity ssm.PatchBaselineIdentity
	name := acctest.RandString(10)
	resourceName := "aws_ssm_patch_baseline.foo"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSSMPatchBaselineBasicConfig(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists(resourceName, &identity),
					testAccCheckAWSSSMPatchBaselineDisappears(&identity),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

func TestAccAWSSSMPatchBaselineWithOperatingSystem(t *testing.T) {
	var before, after ssm.PatchBaselineIdentity
	name := acctest.RandString(10)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSSMPatchBaselineDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSSSMPatchBaselineConfigWithOperatingSystem(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &before),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.approve_after_days", "7"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.patch_filter.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.compliance_level", ssm.PatchComplianceLevelCritical),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.enable_non_security", "true"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "operating_system", "AMAZON_LINUX"),
				),
			},
			{
				Config: testAccAWSSSMPatchBaselineConfigWithOperatingSystemUpdated(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSSSMPatchBaselineExists("aws_ssm_patch_baseline.foo", &after),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.#", "1"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.approve_after_days", "7"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.patch_filter.#", "2"),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "approval_rule.0.compliance_level", ssm.PatchComplianceLevelInformational),
					resource.TestCheckResourceAttr(
						"aws_ssm_patch_baseline.foo", "operating_system", ssm.OperatingSystemWindows),
					testAccCheckAwsSsmPatchBaselineRecreated(t, &before, &after),
				),
			},
		},
	})
}

func testAccCheckAwsSsmPatchBaselineRecreated(t *testing.T,
	before, after *ssm.PatchBaselineIdentity) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if *before.BaselineId == *after.BaselineId {
			t.Fatalf("Expected change of SSM Patch Baseline IDs, but both were %v", *before.BaselineId)
		}
		return nil
	}
}

func testAccCheckAWSSSMPatchBaselineExists(n string, patch *ssm.PatchBaselineIdentity) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No SSM Patch Baseline ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ssmconn

		resp, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
			Filters: []*ssm.PatchOrchestratorFilter{
				{
					Key:    aws.String("NAME_PREFIX"),
					Values: []*string{aws.String(rs.Primary.Attributes["name"])},
				},
			},
		})

		for _, i := range resp.BaselineIdentities {
			if *i.BaselineId == rs.Primary.ID {
				*patch = *i
				return nil
			}
		}
		if err != nil {
			return err
		}

		return fmt.Errorf("No AWS SSM Patch Baseline found")
	}
}

func testAccCheckAWSSSMPatchBaselineDisappears(patch *ssm.PatchBaselineIdentity) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		conn := testAccProvider.Meta().(*AWSClient).ssmconn

		id := aws.StringValue(patch.BaselineId)
		params := &ssm.DeletePatchBaselineInput{
			BaselineId: aws.String(id),
		}

		_, err := conn.DeletePatchBaseline(params)
		if err != nil {
			return fmt.Errorf("error deleting Patch Baseline %s: %s", id, err)
		}

		return nil
	}
}

func testAccCheckAWSSSMPatchBaselineDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ssmconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ssm_patch_baseline" {
			continue
		}

		out, err := conn.DescribePatchBaselines(&ssm.DescribePatchBaselinesInput{
			Filters: []*ssm.PatchOrchestratorFilter{
				{
					Key:    aws.String("NAME_PREFIX"),
					Values: []*string{aws.String(rs.Primary.Attributes["name"])},
				},
			},
		})

		if err != nil {
			return err
		}

		if len(out.BaselineIdentities) > 0 {
			return fmt.Errorf("Expected AWS SSM Patch Baseline to be gone, but was still found")
		}

		return nil
	}

	return nil
}

func testAccAWSSSMPatchBaselineBasicConfig(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  description = "Baseline containing all updates approved for production systems"
  approved_patches = ["KB123456"]
  approved_patches_compliance_level = "CRITICAL"
}

`, rName)
}

func testAccAWSSSMPatchBaselineBasicConfigUpdated(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "updated-patch-baseline-%s"
  description = "Baseline containing all updates approved for production systems - August 2017"
  approved_patches = ["KB123456","KB456789"]
  approved_patches_compliance_level = "HIGH"
}

`, rName)
}

func testAccAWSSSMPatchBaselineConfigWithOperatingSystem(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  operating_system = "AMAZON_LINUX"
  description = "Baseline containing all updates approved for production systems"
  approval_rule {
  	approve_after_days = 7
	enable_non_security = true
  	compliance_level = "CRITICAL"

  	patch_filter {
		key = "PRODUCT"
		values = ["AmazonLinux2016.03","AmazonLinux2016.09","AmazonLinux2017.03","AmazonLinux2017.09"]
  	}

  	patch_filter {
		key = "SEVERITY"
		values = ["Critical","Important"]
  	}
  }
}

`, rName)
}

func testAccAWSSSMPatchBaselineConfigWithOperatingSystemUpdated(rName string) string {
	return fmt.Sprintf(`

resource "aws_ssm_patch_baseline" "foo" {
  name  = "patch-baseline-%s"
  operating_system = "WINDOWS"
  description = "Baseline containing all updates approved for production systems"
  approval_rule {
  	approve_after_days = 7
  	compliance_level = "INFORMATIONAL"

  	patch_filter {
		key = "PRODUCT"
		values = ["WindowsServer2012R2"]
  	}

  	patch_filter {
		key = "MSRC_SEVERITY"
		values = ["Critical","Important"]
  	}
  }
}

`, rName)
}
<|endoftext|>


<commit_before>package main

// #cgo pkg-config: libzfs_core
// #cgo CFLAGS: -fms-extensions -Wno-microsoft
// int do_ioctl(int, char *, int, void *, int, void *, int);
import "C"
import (
	"errors"
	"os"
	"unsafe"
)

func ioctl(f *os.File, name string, input, output []byte) error {
	if len(input) == 0 {
		return errors.New("input nvl required")
	}
	in := unsafe.Pointer(&input[0])

	var out unsafe.Pointer
	if len(output) != 0 {
		out = unsafe.Pointer(&output[0])
	}

	_, err := C.do_ioctl(C.int(f.Fd()),
		C.CString(name), C.int(len(name)),
		unsafe.Pointer(in), C.int(len(input)),
		unsafe.Pointer(out), C.int(len(output)))
	return err
}
<commit_msg>remove libzfs_core dependency<commit_after>package main

// #cgo CFLAGS: -fms-extensions -Wno-microsoft
// int do_ioctl(int, char *, int, void *, int, void *, int);
import "C"
import (
	"errors"
	"os"
	"unsafe"
)

func ioctl(f *os.File, name string, input, output []byte) error {
	if len(input) == 0 {
		return errors.New("input nvl required")
	}
	in := unsafe.Pointer(&input[0])

	var out unsafe.Pointer
	if len(output) != 0 {
		out = unsafe.Pointer(&output[0])
	}

	_, err := C.do_ioctl(C.int(f.Fd()),
		C.CString(name), C.int(len(name)),
		unsafe.Pointer(in), C.int(len(input)),
		unsafe.Pointer(out), C.int(len(output)))
	return err
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// 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 commands

import (
	"fmt"
	"os"
	"strings"

	"github.com/docopt/docopt-go"
	"github.com/projectcalico/calicoctl/calicoctl/commands/clientmgr"
	"github.com/projectcalico/calicoctl/calicoctl/commands/constants"
)

var VERSION, BUILD_DATE, GIT_REVISION string
var VERSION_SUMMARY string

func init() {
	VERSION_SUMMARY = "calicoctl version " + VERSION + ", build " + GIT_REVISION
}

func Version(args []string) {
	doc := `Usage:
  calicoctl version [--config=<CONFIG>]

Options:
  -h --help             Show this screen.
  -c --config=<CONFIG>  Path to the file containing connection configuration in
                        YAML or JSON format.
                        [default: ` + constants.DefaultConfigPath + `]

Description:
  Display the version of calicoctl.
`
	parsedArgs, err := docopt.Parse(doc, args, true, "", false, false)
	if err != nil {
		fmt.Printf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.\n", strings.Join(args, " "))
		os.Exit(1)
	}
	if len(parsedArgs) == 0 {
		return
	}

	fmt.Println("Client Version:   ", VERSION)
	fmt.Println("Build date:       ", BUILD_DATE)
	fmt.Println("Git commit:       ", GIT_REVISION)

	// Load the client config and connect.
	cf := parsedArgs["--config"].(string)
	client, err := clientmgr.NewClient(cf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	cfg := client.Config()

	val, assigned, err := cfg.GetFelixConfig("CalicoVersion", "")
	if err != nil {
		val = fmt.Sprintf("unknown (%s)", err)
	} else if !assigned {
		val = "unknown"
	}
	fmt.Println("Server Version:   ", val)
	val, assigned, err = cfg.GetFelixConfig("ClusterType", "")
	if err != nil {
		val = fmt.Sprintf("unknown (%s)", err)
	} else if !assigned {
		val = "unknown"
	}
	fmt.Println("Cluster Type:     ", val)
}
<commit_msg>Fix version output<commit_after>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// 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 commands

import (
	"fmt"
	"os"
	"strings"

	"github.com/docopt/docopt-go"
	"github.com/projectcalico/calicoctl/calicoctl/commands/clientmgr"
	"github.com/projectcalico/calicoctl/calicoctl/commands/constants"
)

var VERSION, BUILD_DATE, GIT_REVISION string
var VERSION_SUMMARY string

func init() {
	VERSION_SUMMARY = "calicoctl version " + VERSION + ", build " + GIT_REVISION
}

func Version(args []string) {
	doc := `Usage:
  calicoctl version [--config=<CONFIG>]

Options:
  -h --help             Show this screen.
  -c --config=<CONFIG>  Path to the file containing connection configuration in
                        YAML or JSON format.
                        [default: ` + constants.DefaultConfigPath + `]

Description:
  Display the version of calicoctl.
`
	parsedArgs, err := docopt.Parse(doc, args, true, "", false, false)
	if err != nil {
		fmt.Printf("Invalid option: 'calicoctl %s'. Use flag '--help' to read about a specific subcommand.\n", strings.Join(args, " "))
		os.Exit(1)
	}
	if len(parsedArgs) == 0 {
		return
	}

	fmt.Println("Client Version:   ", VERSION)
	fmt.Println("Build date:       ", BUILD_DATE)
	fmt.Println("Git commit:       ", GIT_REVISION)

	// Load the client config and connect.
	cf := parsedArgs["--config"].(string)
	client, err := clientmgr.NewClient(cf)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	cfg := client.Config()

	val, assigned, err := cfg.GetFelixConfig("CalicoVersion", "")
	if err != nil {
		val = fmt.Sprintf("unknown (%s)", err)
	} else if !assigned {
		val = "unknown"
	}
	fmt.Println("Cluster Version:  ", val)
	val, assigned, err = cfg.GetFelixConfig("ClusterType", "")
	if err != nil {
		val = fmt.Sprintf("unknown (%s)", err)
	} else if !assigned {
		val = "unknown"
	}
	fmt.Println("Cluster Type:     ", val)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"dns-master"
	"errors"
	"flag"
	"io/ioutil"
	"log"
	"math/rand"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

// flag whether we want to emit debug output
var DEBUG bool = false

// called for debug output
func _D(fmt string, v ...interface{}) {
	if DEBUG {
		log.Printf(fmt, v...)
	}
}
func (this ClientProxy) getServerIP() error {
	var dns_servers []string
	dnsClient := new(dns.Client)
	if dnsClient == nil {
		return errors.New("Can not new dns Client")
	}
	dnsClient.WriteTimeout = this.timeout
	dnsClient.ReadTimeout = this.timeout
	for _, serverstring := range this.SERVERS {
		ipaddress := net.ParseIP(serverstring)
		if ipaddress != nil {
			if len(ipaddress) == 4 {
				dns_servers = append(dns_servers, serverstring)
			} else {
				serverstring = "[" + serverstring + "]"
				dns_servers = append(dns_servers, serverstring)
			}
		} else {
			dnsRequest := new(dns.Msg)
			dnsRequest.SetQuestion("domain", dns.TypeA)
			dnsResponse, _, err := dnsClient.Exchange(dnsRequest, this.DNS_SERVERS[rand.Intn(len(this.DNS_SERVERS))])
			if err == nil {
				for i := 0; i < len(dnsResponse.Answer); i++ {
					dns_servers = append(dns_servers, dnsResponse.Answer[i].String())
				}
			} else {
				return err
			}
			dnsRequest.SetQuestion("domain", dns.TypeAAAA)
			dnsResponse, _, err = dnsClient.Exchange(dnsRequest, this.DNS_SERVERS[0])
			if err == nil {
				for i := 0; i < len(dnsResponse.Answer); i++ {
					dns_servers = append(dns_servers, "["+dnsResponse.Answer[i].String()+"]")
				}
			} else {
				return err
			}
		}
	}
	this.SERVERS = dns_servers
	return nil
}

func (this ClientProxy) ServeDNS(w dns.ResponseWriter, request *dns.Msg) {
	request_bytes, err := request.Pack() //I am not sure it is better to pack directly or using a pointer
	if err != nil {
		SRVFAIL(w, request)
		_D("error in packing request, error message: %s", err)
		return
	}
	ServerInput := "http://" + this.SERVERS[rand.Intn(len(this.SERVERS))]
	postBytesReader := bytes.NewReader(request_bytes)
	req, err := http.NewRequest("POST", ServerInput, postBytesReader) //need add random here in future
	if err != nil {
		SRVFAIL(w, request)
		_D("error in creating HTTP request, error message: %s", err)
		return
	}
	if this.TransPro == UDPcode {
		req.Header.Add("X-Proxy-DNS-Transport", "udp")
	} else if this.TransPro == TCPcode {
		req.Header.Add("X-Proxy-DNS-Transport", "tcp")
	}
	req.Header.Add("Content-Type", "application/X-DNSoverHTTP")

	resp, err := http.DefaultClient.Do(req)
	//	defer resp.Body.Close()
	if err != nil {
		SRVFAIL(w, request)
		_D("error in HTTP post request, error message: %s", err)
		return
	}
	var requestBody []byte
	requestBody, err = ioutil.ReadAll(resp.Body)
	//	nRead, err := resp.Body.Read(requestBody)
	if err != nil {
		// these need to be separate checks, otherwise you will get a nil-reference
		// when you print the error message below!
		SRVFAIL(w, request)
		_D("error in reading HTTP response, error message: %s", err)
		return
	}
	//I not sure whether I should return server fail directly
	//I just found there is a bug here. Body.Read can not read all the contents out, I don't know how to solve it.
	if len(requestBody) < (int)(resp.ContentLength) {
		SRVFAIL(w, request)
		_D("fail to read all HTTP content")
		return
	}
	var DNSreponse dns.Msg
	err = DNSreponse.Unpack(requestBody)
	if err != nil {
		SRVFAIL(w, request)
		_D("error in packing HTTP response to DNS, error message: %s", err)
		return
	}
	err = w.WriteMsg(&DNSreponse)
	if err != nil {
		_D("error in sending DNS response back, error message: %s", err)
		return
	}
}

func SRVFAIL(w dns.ResponseWriter, req *dns.Msg) {
	m := new(dns.Msg)
	m.SetRcode(req, dns.RcodeServerFailure)
	w.WriteMsg(m)
}

type ClientProxy struct {
	ACCESS      []*net.IPNet
	SERVERS     []string
	s_len       int
	entries     int64
	max_entries int64
	NOW         int64
	giant       *sync.RWMutex
	timeout     time.Duration
	TransPro    int //specify for transmit protocol
	DNS_SERVERS []string
}

const UDPcode = 1
const TCPcode = 2

func main() {
	var (
		S_SERVERS       string
		S_LISTEN        string
		S_ACCESS        string
		timeout         int
		max_entries     int64
		expire_interval int64
		S_DNS_SERVERS   string
	)
	flag.StringVar(&S_SERVERS, "proxy", "", "we proxy requests to those servers,input like http://biilab.cn") //Not sure use IP or URL, default server undefined
	flag.StringVar(&S_LISTEN, "listen", "[::]:53", "listen on (both tcp and udp)")
	flag.StringVar(&S_ACCESS, "access", "127.0.0.0/8,10.0.0.0/8", "allow those networks, use 0.0.0.0/0 to allow everything")
	flag.IntVar(&timeout, "timeout", 5, "timeout")
	flag.Int64Var(&expire_interval, "expire_interval", 300, "delete expired entries every N seconds")
	flag.BoolVar(&DEBUG, "debug", false, "enable/disable debug")
	flag.Int64Var(&max_entries, "max_cache_entries", 2000000, "max cache entries")
	flag.StringVar(&S_DNS_SERVERS, "dns_server", "114.114.114.114:53", "DNS server for initial server lookup")
	flag.Parse()
	servers := strings.Split(S_SERVERS, ",")
	dns_servers := strings.Split(S_DNS_SERVERS, ",")
	UDPproxyer := ClientProxy{
		giant:       new(sync.RWMutex),
		ACCESS:      make([]*net.IPNet, 0),
		SERVERS:     servers,
		s_len:       len(servers),
		NOW:         time.Now().UTC().Unix(),
		entries:     0,
		timeout:     time.Duration(timeout) * time.Second,
		max_entries: max_entries,
		TransPro:    UDPcode,
		DNS_SERVERS: dns_servers}
	TCPproxyer := ClientProxy{
		giant:       new(sync.RWMutex),
		ACCESS:      make([]*net.IPNet, 0),
		SERVERS:     servers,
		s_len:       len(servers),
		NOW:         time.Now().UTC().Unix(),
		entries:     0,
		timeout:     time.Duration(timeout) * time.Second,
		max_entries: max_entries,
		TransPro:    TCPcode,
		DNS_SERVERS: dns_servers}
	for _, mask := range strings.Split(S_ACCESS, ",") {
		_, cidr, err := net.ParseCIDR(mask)
		if err != nil {
			panic(err)
		}
		_D("added access for %s\n", mask)
		UDPproxyer.ACCESS = append(UDPproxyer.ACCESS, cidr)
		TCPproxyer.ACCESS = append(TCPproxyer.ACCESS, cidr)
	}
	err := UDPproxyer.getServerIP()
	if err != nil {
		_D("can not get server address")
		return
	}
	err = TCPproxyer.getServerIP()
	if err != nil {
		_D("can not get server address")
		return
	}
	for _, addr := range strings.Split(S_LISTEN, ",") {
		_D("listening @ %s\n", addr)
		go func() {
			if err := dns.ListenAndServe(addr, "udp", UDPproxyer); err != nil {
				log.Fatal(err)
			}
		}()

		go func() {
			if err := dns.ListenAndServe(addr, "tcp", TCPproxyer); err != nil {
				log.Fatal(err)
			}
		}()
	}
	for {
		UDPproxyer.NOW = time.Now().UTC().Unix()
		time.Sleep(time.Duration(1) * time.Second)
	}
}
<commit_msg>c support added<commit_after>package main

import (
	"bytes"
	"dns-master"
	"errors"
	"flag"
	"io/ioutil"
	"log"
	"math/rand"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

// flag whether we want to emit debug output
var DEBUG bool = false

// called for debug output
func _D(fmt string, v ...interface{}) {
	if DEBUG {
		log.Printf(fmt, v...)
	}
}
func (this ClientProxy) getServerIP() error {
	var dns_servers []string
	dnsClient := new(dns.Client)
	if dnsClient == nil {
		return errors.New("Can not new dns Client")
	}
	dnsClient.WriteTimeout = this.timeout
	dnsClient.ReadTimeout = this.timeout
	for _, serverstring := range this.SERVERS {
		ipaddress := net.ParseIP(serverstring)
		if ipaddress != nil {
			if len(ipaddress) == 4 {
				dns_servers = append(dns_servers, serverstring)
			} else {
				serverstring = "[" + serverstring + "]"
				dns_servers = append(dns_servers, serverstring)
			}
		} else {
			dnsRequest := new(dns.Msg)
			dnsRequest.SetQuestion("domain", dns.TypeA)
			dnsResponse, _, err := dnsClient.Exchange(dnsRequest, this.DNS_SERVERS[rand.Intn(len(this.DNS_SERVERS))])
			if err == nil {
				for i := 0; i < len(dnsResponse.Answer); i++ {
					dns_servers = append(dns_servers, dnsResponse.Answer[i].String())
				}
			} else {
				return err
			}
			dnsRequest.SetQuestion("domain", dns.TypeAAAA)
			dnsResponse, _, err = dnsClient.Exchange(dnsRequest, this.DNS_SERVERS[0])
			if err == nil {
				for i := 0; i < len(dnsResponse.Answer); i++ {
					dns_servers = append(dns_servers, "["+dnsResponse.Answer[i].String()+"]")
				}
			} else {
				return err
			}
		}
	}
	this.SERVERS = dns_servers
	return nil
}

func (this ClientProxy) ServeDNS(w dns.ResponseWriter, request *dns.Msg) {
	request_bytes, err := request.Pack() //I am not sure it is better to pack directly or using a pointer
	if err != nil {
		SRVFAIL(w, request)
		_D("error in packing request, error message: %s", err)
		return
	}
	ServerInput := "http://" + this.SERVERS[rand.Intn(len(this.SERVERS))]
	postBytesReader := bytes.NewReader(request_bytes)
	req, err := http.NewRequest("POST", ServerInput, postBytesReader) //need add random here in future
	if err != nil {
		SRVFAIL(w, request)
		_D("error in creating HTTP request, error message: %s", err)
		return
	}
	if this.C_version {
		req.Header.Add("Content-Type: ", "application/octet-stream")
		if this.TransPro == UDPcode {
			req.Header.Add("HTTP_PROXY_DNS_TRANSPORT", "UDP")
		} else if this.TransPro == TCPcode {
			req.Header.Add("HTTP_PROXY_DNS_TRANSPORT", "TCP")
		}
	} else {
		if this.TransPro == UDPcode {
			req.Header.Add("X-Proxy-DNS-Transport", "udp")
		} else if this.TransPro == TCPcode {
			req.Header.Add("X-Proxy-DNS-Transport", "tcp")
		}
		req.Header.Add("Content-Type", "application/X-DNSoverHTTP")
	}
	resp, err := http.DefaultClient.Do(req)
	//	defer resp.Body.Close()
	if err != nil {
		SRVFAIL(w, request)
		_D("error in HTTP post request, error message: %s", err)
		return
	}
	var requestBody []byte
	requestBody, err = ioutil.ReadAll(resp.Body)
	//	nRead, err := resp.Body.Read(requestBody)
	if err != nil {
		// these need to be separate checks, otherwise you will get a nil-reference
		// when you print the error message below!
		SRVFAIL(w, request)
		_D("error in reading HTTP response, error message: %s", err)
		return
	}
	//I not sure whether I should return server fail directly
	//I just found there is a bug here. Body.Read can not read all the contents out, I don't know how to solve it.
	if len(requestBody) < (int)(resp.ContentLength) {
		SRVFAIL(w, request)
		_D("fail to read all HTTP content")
		return
	}
	var DNSreponse dns.Msg
	err = DNSreponse.Unpack(requestBody)
	if err != nil {
		SRVFAIL(w, request)
		_D("error in packing HTTP response to DNS, error message: %s", err)
		return
	}
	err = w.WriteMsg(&DNSreponse)
	if err != nil {
		_D("error in sending DNS response back, error message: %s", err)
		return
	}
}

func SRVFAIL(w dns.ResponseWriter, req *dns.Msg) {
	m := new(dns.Msg)
	m.SetRcode(req, dns.RcodeServerFailure)
	w.WriteMsg(m)
}

type ClientProxy struct {
	ACCESS      []*net.IPNet
	SERVERS     []string
	s_len       int
	entries     int64
	max_entries int64
	NOW         int64
	giant       *sync.RWMutex
	timeout     time.Duration
	TransPro    int //specify for transmit protocol
	DNS_SERVERS []string
	C_version   bool
}

const UDPcode = 1
const TCPcode = 2

func main() {
	var (
		S_SERVERS       string
		S_LISTEN        string
		S_ACCESS        string
		timeout         int
		max_entries     int64
		expire_interval int64
		S_DNS_SERVERS   string
		Support_C       bool
	)
	flag.StringVar(&S_SERVERS, "proxy", "", "we proxy requests to those servers,input like http://biilab.cn") //Not sure use IP or URL, default server undefined
	flag.StringVar(&S_LISTEN, "listen", "[::]:53", "listen on (both tcp and udp)")
	flag.StringVar(&S_ACCESS, "access", "127.0.0.0/8,10.0.0.0/8", "allow those networks, use 0.0.0.0/0 to allow everything")
	flag.IntVar(&timeout, "timeout", 5, "timeout")
	flag.Int64Var(&expire_interval, "expire_interval", 300, "delete expired entries every N seconds")
	flag.BoolVar(&DEBUG, "debug", false, "enable/disable debug")
	flag.Int64Var(&max_entries, "max_cache_entries", 2000000, "max cache entries")
	flag.StringVar(&S_DNS_SERVERS, "dns_server", "114.114.114.114:53", "DNS server for initial server lookup")
	flag.BoolVar(&Support_C, "support_version", false, "Whether support Paul Vixie's C version")
	flag.Parse()
	servers := strings.Split(S_SERVERS, ",")
	dns_servers := strings.Split(S_DNS_SERVERS, ",")
	UDPproxyer := ClientProxy{
		giant:       new(sync.RWMutex),
		ACCESS:      make([]*net.IPNet, 0),
		SERVERS:     servers,
		s_len:       len(servers),
		NOW:         time.Now().UTC().Unix(),
		entries:     0,
		timeout:     time.Duration(timeout) * time.Second,
		max_entries: max_entries,
		TransPro:    UDPcode,
		DNS_SERVERS: dns_servers,
		C_version:   Support_C}
	TCPproxyer := ClientProxy{
		giant:       new(sync.RWMutex),
		ACCESS:      make([]*net.IPNet, 0),
		SERVERS:     servers,
		s_len:       len(servers),
		NOW:         time.Now().UTC().Unix(),
		entries:     0,
		timeout:     time.Duration(timeout) * time.Second,
		max_entries: max_entries,
		TransPro:    TCPcode,
		DNS_SERVERS: dns_servers,
		C_version:   Support_C}
	for _, mask := range strings.Split(S_ACCESS, ",") {
		_, cidr, err := net.ParseCIDR(mask)
		if err != nil {
			panic(err)
		}
		_D("added access for %s\n", mask)
		UDPproxyer.ACCESS = append(UDPproxyer.ACCESS, cidr)
		TCPproxyer.ACCESS = append(TCPproxyer.ACCESS, cidr)
	}
	err := UDPproxyer.getServerIP()
	if err != nil {
		_D("can not get server address")
		return
	}
	err = TCPproxyer.getServerIP()
	if err != nil {
		_D("can not get server address")
		return
	}
	for _, addr := range strings.Split(S_LISTEN, ",") {
		_D("listening @ %s\n", addr)
		go func() {
			if err := dns.ListenAndServe(addr, "udp", UDPproxyer); err != nil {
				log.Fatal(err)
			}
		}()

		go func() {
			if err := dns.ListenAndServe(addr, "tcp", TCPproxyer); err != nil {
				log.Fatal(err)
			}
		}()
	}
	for {
		UDPproxyer.NOW = time.Now().UTC().Unix()
		time.Sleep(time.Duration(1) * time.Second)
	}
}
<|endoftext|>


<commit_before>package handlers

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	tspb "github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/grpc/codes"

	"pixur.org/pixur/api"
	"pixur.org/pixur/be/schema"
	"pixur.org/pixur/be/status"
	"pixur.org/pixur/be/tasks"
)

func TestGetRefreshTokenSucceedsOnIdentSecret(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.NewTokenID = 3
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		return nil
	}

	s := serv{
		runner: tasks.TestTaskRunner(successRunner),
		now:    time.Now,
	}
	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:  "a",
		Secret: "b",
	})

	if sts != nil {
		t.Fatal(sts)
	}
	if resp.RefreshToken == "" || resp.AuthToken == "" || resp.PixToken == "" {
		t.Error("tokens should be present", resp)
	}
	if resp.RefreshPayload.Subject != "2" || resp.RefreshPayload.TokenId != 3 {
		t.Error("wrong token ids", resp)
	}
	if taskCap == nil {
		t.Fatal("task didn't run")
	}
	if taskCap.CompareHashAndPassword == nil {
		t.Error("no compare hash function")
	}
	if taskCap.Ident != "a" || taskCap.Secret != "b" {
		t.Error("wrong task input", taskCap.Ident, taskCap.Secret)
	}
}

func TestGetRefreshTokenSucceedsOnRefreshToken(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.NewTokenID = 3
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		return nil
	}
	s := serv{
		runner: tasks.TestTaskRunner(successRunner),
		now:    time.Now,
	}

	token, payload := testRefreshToken()
	res, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: token,
	})
	if sts != nil {
		t.Fatal(sts)
	}

	if res.RefreshToken == "" || res.AuthToken == "" || res.PixToken == "" {
		t.Error("tokens should be present", res)
	}
	if res.RefreshPayload.Subject != "2" || res.RefreshPayload.TokenId != 3 {
		t.Error("wrong token ids", res)
	}
	if taskCap == nil {
		t.Fatal("task didn't run")
	}
	if taskCap.TokenID != payload.TokenId || taskCap.UserID != 9 /* payload.Subject */ {
		t.Error("wrong task input", taskCap.Ident, taskCap.Secret)
	}
}

func TestGetRefreshTokenFailsOnInvalidToken(t *testing.T) {
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: "invalid",
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := sts.Message(), "can't decode token"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnNonRefreshToken(t *testing.T) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "9",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_AUTH,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: string(refreshToken),
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "can't decode non refresh token"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnBadSubject(t *testing.T) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "invalid",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: string(refreshToken),
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "can't decode subject"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnTaskError(t *testing.T) {
	failureRunner := func(_ context.Context, task tasks.Task) status.S {
		return status.Internal(nil, "bad")
	}

	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(failureRunner),
	}

	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{})

	if have, want := sts.Code(), codes.Internal; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "bad"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshToken(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		taskCap.NewTokenID = 4
		return nil
	}
	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(successRunner),
	}
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "2",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   3,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}

	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:        "ident",
		Secret:       "secret",
		RefreshToken: string(refreshToken),
	})
	if sts != nil {
		t.Fatal(err)
	}

	if have, want := taskCap.Ident, "ident"; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.Secret, "secret"; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.UserID, int64(2); have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.TokenID, int64(3); have != want {
		t.Error("have", have, "want", want)
	}

	if len(resp.RefreshToken) == 0 || len(resp.AuthToken) == 0 || len(resp.PixToken) == 0 {
		t.Error("expected non-empty token", resp.RefreshToken, resp.AuthToken, resp.PixToken)
	}

	if !withinProto(resp.RefreshPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.RefreshPayload.NotBefore)
	}
	if !withinProto(resp.RefreshPayload.NotAfter, time.Now().Add(refreshPwtDuration), time.Minute) {
		t.Error("wrong after", resp.RefreshPayload.NotAfter)
	}
	resp.RefreshPayload.NotBefore = nil
	resp.RefreshPayload.NotAfter = nil
	expectedRefresh := &api.PwtPayload{
		Subject: "2",
		TokenId: 4,
		Type:    api.PwtPayload_REFRESH,
	}
	if !proto.Equal(resp.RefreshPayload, expectedRefresh) {
		t.Error("have", resp.RefreshPayload, "want", expectedRefresh)
	}

	if !withinProto(resp.AuthPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.AuthPayload.NotBefore)
	}
	if !withinProto(resp.AuthPayload.NotAfter, time.Now().Add(authPwtDuration), time.Minute) {
		t.Error("wrong after", resp.AuthPayload.NotAfter)
	}
	resp.AuthPayload.NotBefore = nil
	resp.AuthPayload.NotAfter = nil
	expectedAuth := &api.PwtPayload{
		Subject:       "2",
		TokenParentId: 4,
		Type:          api.PwtPayload_AUTH,
	}
	if !proto.Equal(resp.AuthPayload, expectedAuth) {
		t.Error("have", resp.AuthPayload, "want", expectedAuth)
	}

	if !withinProto(resp.PixPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.PixPayload.NotBefore)
	}
	if !withinProto(resp.PixPayload.NotAfter, time.Now().Add(refreshPwtDuration), time.Minute) {
		t.Error("wrong after", resp.PixPayload.NotAfter)
	}
	if !withinProto(resp.PixPayload.SoftNotAfter, time.Now().Add(authPwtDuration), time.Minute) {
		t.Error("wrong soft after", resp.PixPayload.SoftNotAfter)
	}
	resp.PixPayload.NotBefore = nil
	resp.PixPayload.NotAfter = nil
	resp.PixPayload.SoftNotAfter = nil
	expectedPix := &api.PwtPayload{
		Subject:       "2",
		TokenParentId: 4,
		Type:          api.PwtPayload_PIX,
	}
	if !proto.Equal(resp.PixPayload, expectedPix) {
		t.Error("have", resp.PixPayload, "want", expectedPix)
	}
}

func TestGetRefreshTokenNoPix(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.User = &schema.User{
			UserId: 2,
		}
		taskCap.NewTokenID = 4
		return nil
	}
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "2",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   3,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}

	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(successRunner),
	}

	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:        "ident",
		Secret:       "secret",
		RefreshToken: string(refreshToken),
	})
	if sts != nil {
		t.Fatal(err)
	}

	if len(resp.PixToken) != 0 {
		t.Error("expected empty token", resp.PixToken)
	}
	if resp.PixPayload != nil {
		t.Error("have", resp.PixPayload, "want", nil)
	}
}

func within(t1, t2 time.Time, diff time.Duration) bool {
	d := t1.Sub(t2)
	if d < 0 {
		d = -d
	}
	return d <= diff
}

func withinProto(t1pb *tspb.Timestamp, t2 time.Time, diff time.Duration) bool {
	t1, err := ptypes.Timestamp(t1pb)
	if err != nil {
		panic(err)
	}
	d := t1.Sub(t2)
	if d < 0 {
		d = -d
	}
	return d <= diff
}

func testRefreshToken() (string, *api.PwtPayload) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "9",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   10,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	return string(refreshToken), payload
}
<commit_msg>be/handlers: fix softNotAfter tests<commit_after>package handlers

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	tspb "github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/grpc/codes"

	"pixur.org/pixur/api"
	"pixur.org/pixur/be/schema"
	"pixur.org/pixur/be/status"
	"pixur.org/pixur/be/tasks"
)

func TestGetRefreshTokenSucceedsOnIdentSecret(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.NewTokenID = 3
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		return nil
	}

	s := serv{
		runner: tasks.TestTaskRunner(successRunner),
		now:    time.Now,
	}
	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:  "a",
		Secret: "b",
	})

	if sts != nil {
		t.Fatal(sts)
	}
	if resp.RefreshToken == "" || resp.AuthToken == "" || resp.PixToken == "" {
		t.Error("tokens should be present", resp)
	}
	if resp.RefreshPayload.Subject != "2" || resp.RefreshPayload.TokenId != 3 {
		t.Error("wrong token ids", resp)
	}
	if taskCap == nil {
		t.Fatal("task didn't run")
	}
	if taskCap.CompareHashAndPassword == nil {
		t.Error("no compare hash function")
	}
	if taskCap.Ident != "a" || taskCap.Secret != "b" {
		t.Error("wrong task input", taskCap.Ident, taskCap.Secret)
	}
}

func TestGetRefreshTokenSucceedsOnRefreshToken(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.NewTokenID = 3
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		return nil
	}
	s := serv{
		runner: tasks.TestTaskRunner(successRunner),
		now:    time.Now,
	}

	token, payload := testRefreshToken()
	res, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: token,
	})
	if sts != nil {
		t.Fatal(sts)
	}

	if res.RefreshToken == "" || res.AuthToken == "" || res.PixToken == "" {
		t.Error("tokens should be present", res)
	}
	if res.RefreshPayload.Subject != "2" || res.RefreshPayload.TokenId != 3 {
		t.Error("wrong token ids", res)
	}
	if taskCap == nil {
		t.Fatal("task didn't run")
	}
	if taskCap.TokenID != payload.TokenId || taskCap.UserID != 9 /* payload.Subject */ {
		t.Error("wrong task input", taskCap.Ident, taskCap.Secret)
	}
}

func TestGetRefreshTokenFailsOnInvalidToken(t *testing.T) {
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: "invalid",
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := sts.Message(), "can't decode token"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnNonRefreshToken(t *testing.T) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "9",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_AUTH,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: string(refreshToken),
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "can't decode non refresh token"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnBadSubject(t *testing.T) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "invalid",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	s := serv{
		now: time.Now,
	}
	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		RefreshToken: string(refreshToken),
	})

	if have, want := sts.Code(), codes.Unauthenticated; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "can't decode subject"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshTokenFailsOnTaskError(t *testing.T) {
	failureRunner := func(_ context.Context, task tasks.Task) status.S {
		return status.Internal(nil, "bad")
	}

	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(failureRunner),
	}

	_, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{})

	if have, want := sts.Code(), codes.Internal; have != want {
		t.Error("have", have, "want", want)
	}

	if have, want := sts.Message(), "bad"; !strings.Contains(have, want) {
		t.Error("have", have, "want", want)
	}
}

func TestGetRefreshToken(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.User = &schema.User{
			UserId:     2,
			Capability: []schema.User_Capability{schema.User_PIC_READ},
		}
		taskCap.NewTokenID = 4
		return nil
	}
	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(successRunner),
	}
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "2",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   3,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}

	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:        "ident",
		Secret:       "secret",
		RefreshToken: string(refreshToken),
	})
	if sts != nil {
		t.Fatal(err)
	}

	if have, want := taskCap.Ident, "ident"; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.Secret, "secret"; have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.UserID, int64(2); have != want {
		t.Error("have", have, "want", want)
	}
	if have, want := taskCap.TokenID, int64(3); have != want {
		t.Error("have", have, "want", want)
	}

	if len(resp.RefreshToken) == 0 || len(resp.AuthToken) == 0 || len(resp.PixToken) == 0 {
		t.Error("expected non-empty token", resp.RefreshToken, resp.AuthToken, resp.PixToken)
	}

	if !withinProto(resp.RefreshPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.RefreshPayload.NotBefore)
	}
	if !withinProto(resp.RefreshPayload.NotAfter, time.Now().Add(refreshPwtDuration), time.Minute) {
		t.Error("wrong after", resp.RefreshPayload.NotAfter)
	}
	resp.RefreshPayload.NotBefore = nil
	resp.RefreshPayload.NotAfter = nil
	expectedRefresh := &api.PwtPayload{
		Subject: "2",
		TokenId: 4,
		Type:    api.PwtPayload_REFRESH,
	}
	if !proto.Equal(resp.RefreshPayload, expectedRefresh) {
		t.Error("have", resp.RefreshPayload, "want", expectedRefresh)
	}

	if !withinProto(resp.AuthPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.AuthPayload.NotBefore)
	}
	if !withinProto(resp.AuthPayload.NotAfter, time.Now().Add(authPwtDuration), time.Minute) {
		t.Error("wrong after", resp.AuthPayload.NotAfter)
	}
	if !withinProto(resp.AuthPayload.SoftNotAfter, time.Now().Add(authPwtSoftDuration), time.Minute) {
		t.Error("wrong soft after", resp.AuthPayload.SoftNotAfter)
	}
	resp.AuthPayload.NotBefore = nil
	resp.AuthPayload.NotAfter = nil
	resp.AuthPayload.SoftNotAfter = nil
	expectedAuth := &api.PwtPayload{
		Subject:       "2",
		TokenParentId: 4,
		Type:          api.PwtPayload_AUTH,
	}
	if !proto.Equal(resp.AuthPayload, expectedAuth) {
		t.Error("have", resp.AuthPayload, "want", expectedAuth)
	}

	if !withinProto(resp.PixPayload.NotBefore, time.Now(), time.Minute*2) {
		t.Error("wrong before", resp.PixPayload.NotBefore)
	}
	if !withinProto(resp.PixPayload.NotAfter, time.Now().Add(refreshPwtDuration), time.Minute) {
		t.Error("wrong after", resp.PixPayload.NotAfter)
	}
	if !withinProto(resp.PixPayload.SoftNotAfter, time.Now().Add(authPwtDuration), time.Minute) {
		t.Error("wrong soft after", resp.PixPayload.SoftNotAfter)
	}
	resp.PixPayload.NotBefore = nil
	resp.PixPayload.NotAfter = nil
	resp.PixPayload.SoftNotAfter = nil
	expectedPix := &api.PwtPayload{
		Subject:       "2",
		TokenParentId: 4,
		Type:          api.PwtPayload_PIX,
	}
	if !proto.Equal(resp.PixPayload, expectedPix) {
		t.Error("have", resp.PixPayload, "want", expectedPix)
	}
}

func TestGetRefreshTokenNoPix(t *testing.T) {
	var taskCap *tasks.AuthUserTask
	successRunner := func(_ context.Context, task tasks.Task) status.S {
		taskCap = task.(*tasks.AuthUserTask)
		taskCap.User = &schema.User{
			UserId: 2,
		}
		taskCap.NewTokenID = 4
		return nil
	}
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "2",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   3,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}

	s := serv{
		now:    time.Now,
		runner: tasks.TestTaskRunner(successRunner),
	}

	resp, sts := s.handleGetRefreshToken(context.Background(), &api.GetRefreshTokenRequest{
		Ident:        "ident",
		Secret:       "secret",
		RefreshToken: string(refreshToken),
	})
	if sts != nil {
		t.Fatal(err)
	}

	if len(resp.PixToken) != 0 {
		t.Error("expected empty token", resp.PixToken)
	}
	if resp.PixPayload != nil {
		t.Error("have", resp.PixPayload, "want", nil)
	}
}

func within(t1, t2 time.Time, diff time.Duration) bool {
	d := t1.Sub(t2)
	if d < 0 {
		d = -d
	}
	return d <= diff
}

func withinProto(t1pb *tspb.Timestamp, t2 time.Time, diff time.Duration) bool {
	t1, err := ptypes.Timestamp(t1pb)
	if err != nil {
		panic(err)
	}
	d := t1.Sub(t2)
	if d < 0 {
		d = -d
	}
	return d <= diff
}

func testRefreshToken() (string, *api.PwtPayload) {
	notafter, _ := ptypes.TimestampProto(time.Now().Add(refreshPwtDuration))
	notbefore, _ := ptypes.TimestampProto(time.Now().Add(-1 * time.Minute))
	payload := &api.PwtPayload{
		Subject:   "9",
		NotAfter:  notafter,
		NotBefore: notbefore,
		Type:      api.PwtPayload_REFRESH,
		TokenId:   10,
	}
	refreshToken, err := defaultPwtCoder.encode(payload)
	if err != nil {
		panic(err)
	}
	return string(refreshToken), payload
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"

	"github.com/koding/kite"
	"github.com/koding/kite/protocol"
	"github.com/koding/kloud"
)

// Kloud represents a remote kloud instance
type Kloud struct {
	client *kite.Client
}

// Kloud returns a new connected kloud instance. The kloud is ready to use.
// It's connected and will redial if there is any disconnections.
func NewKloud(k *kite.Kite) (*Kloud, error) {
	kontrolQuery := protocol.KontrolQuery{
		Username:    "koding",
		Environment: "vagrant",
		Name:        "kloud",
	}

	timeout := time.After(time.Minute)

	k.Log.Info("Querying for Kloud: %+v", kontrolQuery)
	for {
		select {
		case <-time.Tick(time.Second * 2):
			kites, err := k.GetKites(kontrolQuery)
			if err != nil {
				// still not up, try again until the kite is ready
				continue
			}

			remoteKite := kites[0]

			connected, err := remoteKite.DialForever()
			if err != nil {
				return nil, err
			}

			select {
			case <-connected:
			case <-time.After(time.Minute):
				return nil, kloud.NewError(kloud.ErrNoKiteConnection)
			}

			// Kloud connection is ready now
			return &Kloud{
				client: remoteKite,
			}, nil
		case <-timeout:
			return nil, fmt.Errorf("timeout while connection for kite")
		}
	}
}

// Report reports machine and usage metrics to kloud instance.
func (k *Kloud) Report() error {
	// update information before we send it
	usg.Update()

	fmt.Printf("repoting usage %+v\n", usg)
	resp, err := k.client.Tell("report", usg)
	if err != nil {
		return err
	}

	fmt.Printf("kloud response: %+v\n", resp.MustString())
	return nil
}
<commit_msg>kloud: move report to koding provider<commit_after>package main

import (
	"fmt"
	"time"

	"github.com/koding/kite"
	"github.com/koding/kite/protocol"
	"github.com/koding/kloud"
)

// Kloud represents a remote kloud instance
type Kloud struct {
	client *kite.Client
}

// Kloud returns a new connected kloud instance. The kloud is ready to use.
// It's connected and will redial if there is any disconnections.
func NewKloud(k *kite.Kite) (*Kloud, error) {
	kontrolQuery := protocol.KontrolQuery{
		Username:    "koding",
		Environment: "vagrant",
		Name:        "kloud",
	}

	timeout := time.After(time.Minute)

	k.Log.Info("Querying for Kloud: %+v", kontrolQuery)
	for {
		select {
		case <-time.Tick(time.Second * 2):
			kites, err := k.GetKites(kontrolQuery)
			if err != nil {
				// still not up, try again until the kite is ready
				continue
			}

			remoteKite := kites[0]

			connected, err := remoteKite.DialForever()
			if err != nil {
				return nil, err
			}

			select {
			case <-connected:
			case <-time.After(time.Minute):
				return nil, kloud.NewError(kloud.ErrNoKiteConnection)
			}

			// Kloud connection is ready now
			return &Kloud{
				client: remoteKite,
			}, nil
		case <-timeout:
			return nil, fmt.Errorf("timeout while connection for kite")
		}
	}
}

// Report reports machine and usage metrics to kloud instance.
func (k *Kloud) Report() error {
	// update information before we send it
	usg.Update()

	fmt.Printf("repoting usage %+v\n", usg)
	_, err := k.client.Tell("report", usg)
	return err
}
<|endoftext|>


<commit_before>package vdf

import (
	"bufio"
	"bytes"
	"io"
)

// Scanner represents a lexical scanner.
type Scanner struct {
	r *bufio.Reader
}

// NewScanner returns a new instance of Scanner.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{r: bufio.NewReader(r)}
}

// read reads the next rune from the buffered reader.
// Returns the rune(0) if an error occurs (or io.EOF is returned).
func (s *Scanner) read() rune {
	ch, _, err := s.r.ReadRune()
	if err != nil {
		return eof
	}
	return ch
}

// unread places the previously read rune back on the reader.
func (s *Scanner) unread() {
	_ = s.r.UnreadRune()
}

// Scan returns the next token and literal value.
func (s *Scanner) Scan(respectWhitespace bool) (tok Token, lit string) {
	// Read the next rune.
	ch := s.read()

	// If we see whitespace then consume all contiguous whitespace.
	if respectWhitespace == false && (isWhitespace(ch) || isLineEnding(ch)) {
		s.unread()
		return s.scanWhitespace()

		// If we see a whitespace, return it
	} else if respectWhitespace == true && isWhitespace(ch) {
		return WS, string(ch)

		// If we see a line ending, return it
	} else if respectWhitespace == true && isLineEnding(ch) {
		return EOL, string(ch)

		// If we see a letter then consume as an ident or reserved word.
	} else if isLetter(ch) || isDigit(ch) {
		s.unread()
		return s.scanIdent()

		// If we see a "//" this line is a comment
	} else if isComment(ch, s) {
		return CommentDoubleSlash, string(ch) + string(ch)
	}

	// Otherwise read the individual character.
	switch ch {
	case eof:
		return EOF, ""
	case '\\':
		return EscapeSequence, string(ch)
	case '{':
		return CurlyBraceOpen, string(ch)
	case '}':
		return CurlyBraceClose, string(ch)
	case '"':
		return QuotationMark, string(ch)
	}

	return Illegal, string(ch)
}

// scanWhitespace consumes the current rune and all contiguous whitespace.
func (s *Scanner) scanWhitespace() (Token, string) {
	// Create a buffer and read the current character into it.
	var buf bytes.Buffer
	buf.WriteRune(s.read())

	// Read every subsequent whitespace character into the buffer.
	// Non-whitespace characters and EOF will cause the loop to exit.
	for {
		if ch := s.read(); ch == eof {
			break
		} else if !isWhitespace(ch) {
			s.unread()
			break
		} else {
			buf.WriteRune(ch)
		}
	}

	return WS, buf.String()
}

// scanIdent consumes the current rune and all contiguous ident runes.
func (s *Scanner) scanIdent() (tok Token, lit string) {
	// Create a buffer and read the current character into it.
	var buf bytes.Buffer
	buf.WriteRune(s.read())

	// Read every subsequent ident character into the buffer.
	// Non-ident characters and EOF will cause the loop to exit.
	for {
		if ch := s.read(); ch == eof {
			break
		} else if !isLetter(ch) && !isDigit(ch) && ch != '_' {
			s.unread()
			break
		} else {
			_, _ = buf.WriteRune(ch)
		}
	}

	// Otherwise return as a regular identifier.
	return Ident, buf.String()
}

func isWhitespace(ch rune) bool {
	return ch == ' ' || ch == '\t'
}

func isLineEnding(ch rune) bool {
	return ch == '\n' || ch == '\r'
}

func isLetter(ch rune) bool {
	return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
}

// isDigit returns true if the rune is a digit.
func isDigit(ch rune) bool {
	return (ch >= '0' && ch <= '9')
}

// isComment returns true if this line starts with a comment ("//")
func isComment(ch rune, s *Scanner) bool {
	if ch != '/' {
		return false
	}

	nextRune := s.read()
	if nextRune != '/' {
		s.unread()
		return false
	}

	return true
}<commit_msg>go fmt<commit_after>package vdf

import (
	"bufio"
	"bytes"
	"io"
)

// Scanner represents a lexical scanner.
type Scanner struct {
	r *bufio.Reader
}

// NewScanner returns a new instance of Scanner.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{r: bufio.NewReader(r)}
}

// read reads the next rune from the buffered reader.
// Returns the rune(0) if an error occurs (or io.EOF is returned).
func (s *Scanner) read() rune {
	ch, _, err := s.r.ReadRune()
	if err != nil {
		return eof
	}
	return ch
}

// unread places the previously read rune back on the reader.
func (s *Scanner) unread() {
	_ = s.r.UnreadRune()
}

// Scan returns the next token and literal value.
func (s *Scanner) Scan(respectWhitespace bool) (tok Token, lit string) {
	// Read the next rune.
	ch := s.read()

	// If we see whitespace then consume all contiguous whitespace.
	if respectWhitespace == false && (isWhitespace(ch) || isLineEnding(ch)) {
		s.unread()
		return s.scanWhitespace()

		// If we see a whitespace, return it
	} else if respectWhitespace == true && isWhitespace(ch) {
		return WS, string(ch)

		// If we see a line ending, return it
	} else if respectWhitespace == true && isLineEnding(ch) {
		return EOL, string(ch)

		// If we see a letter then consume as an ident or reserved word.
	} else if isLetter(ch) || isDigit(ch) {
		s.unread()
		return s.scanIdent()

		// If we see a "//" this line is a comment
	} else if isComment(ch, s) {
		return CommentDoubleSlash, string(ch) + string(ch)
	}

	// Otherwise read the individual character.
	switch ch {
	case eof:
		return EOF, ""
	case '\\':
		return EscapeSequence, string(ch)
	case '{':
		return CurlyBraceOpen, string(ch)
	case '}':
		return CurlyBraceClose, string(ch)
	case '"':
		return QuotationMark, string(ch)
	}

	return Illegal, string(ch)
}

// scanWhitespace consumes the current rune and all contiguous whitespace.
func (s *Scanner) scanWhitespace() (Token, string) {
	// Create a buffer and read the current character into it.
	var buf bytes.Buffer
	buf.WriteRune(s.read())

	// Read every subsequent whitespace character into the buffer.
	// Non-whitespace characters and EOF will cause the loop to exit.
	for {
		if ch := s.read(); ch == eof {
			break
		} else if !isWhitespace(ch) {
			s.unread()
			break
		} else {
			buf.WriteRune(ch)
		}
	}

	return WS, buf.String()
}

// scanIdent consumes the current rune and all contiguous ident runes.
func (s *Scanner) scanIdent() (tok Token, lit string) {
	// Create a buffer and read the current character into it.
	var buf bytes.Buffer
	buf.WriteRune(s.read())

	// Read every subsequent ident character into the buffer.
	// Non-ident characters and EOF will cause the loop to exit.
	for {
		if ch := s.read(); ch == eof {
			break
		} else if !isLetter(ch) && !isDigit(ch) && ch != '_' {
			s.unread()
			break
		} else {
			_, _ = buf.WriteRune(ch)
		}
	}

	// Otherwise return as a regular identifier.
	return Ident, buf.String()
}

func isWhitespace(ch rune) bool {
	return ch == ' ' || ch == '\t'
}

func isLineEnding(ch rune) bool {
	return ch == '\n' || ch == '\r'
}

func isLetter(ch rune) bool {
	return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
}

// isDigit returns true if the rune is a digit.
func isDigit(ch rune) bool {
	return (ch >= '0' && ch <= '9')
}

// isComment returns true if this line starts with a comment ("//")
func isComment(ch rune, s *Scanner) bool {
	if ch != '/' {
		return false
	}

	nextRune := s.read()
	if nextRune != '/' {
		s.unread()
		return false
	}

	return true
}
<|endoftext|>