<commit_before>package aws

import (
	"fmt"
	"regexp"
	"testing"

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

func TestAccAwsWafv2IPSet_basic(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfigUpdate(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", "Updated"),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "3"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_minimal(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfigMinimal(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ""),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "0"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_changeNameForceNew(t *testing.T) {
	var before, after wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	ipSetNewName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &before),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetNewName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &after),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetNewName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetNewName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
				),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_tags(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag1", "Value1"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
			{
				Config: testAccAwsWafv2IPSetConfigTwoTags(ipSetName, "Tag1", "Value1Updated", "Tag2", "Value2"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1Updated"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag2", "Value2"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
		},
	})
}

func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_wafv2_ip_set" {
			continue
		}

		conn := testAccProvider.Meta().(*AWSClient).wafv2conn
		resp, err := conn.GetIPSet(
			&wafv2.GetIPSetInput{
				Id:    aws.String(rs.Primary.ID),
				Name:  aws.String(rs.Primary.Attributes["name"]),
				Scope: aws.String(rs.Primary.Attributes["scope"]),
			})

		if err == nil {
			if *resp.IPSet.Id == rs.Primary.ID {
				return fmt.Errorf("WAFV2 IPSet %s still exists", rs.Primary.ID)
			}
		}

		// Return nil if the IPSet is already destroyed
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == wafv2.ErrCodeWAFNonexistentItemException {
				return nil
			}
		}

		return err
	}

	return nil
}

func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) 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 WAFV2 IPSet ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).wafv2conn
		resp, err := conn.GetIPSet(&wafv2.GetIPSetInput{
			Id:    aws.String(rs.Primary.ID),
			Name:  aws.String(rs.Primary.Attributes["name"]),
			Scope: aws.String(rs.Primary.Attributes["scope"]),
		})

		if err != nil {
			return err
		}

		if *resp.IPSet.Id == rs.Primary.ID {
			*v = *resp.IPSet
			return nil
		}

		return fmt.Errorf("WAFV2 IPSet (%s) not found", rs.Primary.ID)
	}
}

func testAccAwsWafv2IPSetConfig(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name = "%s"
  description = "%s"
  scope = "REGIONAL"
  ip_address_version = "IPV4"
  addresses = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }
}
`, name, name)
}

func testAccAwsWafv2IPSetConfigUpdate(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name = "%s"
  description = "Updated"
  scope = "REGIONAL"
  ip_address_version = "IPV4"
  addresses = ["1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/32"]
}
`, name)
}

func testAccAwsWafv2IPSetConfigMinimal(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name = "%s"
  scope = "REGIONAL"
  ip_address_version = "IPV4"
}
`, name)
}

func testAccAwsWafv2IPSetConfigOneTag(name, tagKey, tagValue string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name = "%s"
  description = "%s"
  scope = "REGIONAL"
  ip_address_version = "IPV4"
  addresses = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    %q = %q
  }
}
`, name, name, tagKey, tagValue)
}

func testAccAwsWafv2IPSetConfigTwoTags(name, tag1Key, tag1Value, tag2Key, tag2Value string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name = "%s"
  description = "%s"
  scope = "REGIONAL"
  ip_address_version = "IPV4"
  addresses = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    %q = %q
    %q = %q
  }
}
`, name, name, tag1Key, tag1Value, tag2Key, tag2Value)
}

func testAccAWSWafv2IPSetImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
	return func(s *terraform.State) (string, error) {
		rs, ok := s.RootModule().Resources[resourceName]
		if !ok {
			return "", fmt.Errorf("Not found: %s", resourceName)
		}

		return fmt.Sprintf("%s/%s/%s", rs.Primary.ID, rs.Primary.Attributes["name"], rs.Primary.Attributes["scope"]), nil
	}
}
<commit_msg>Format test config<commit_after>package aws

import (
	"fmt"
	"regexp"
	"testing"

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

func TestAccAwsWafv2IPSet_basic(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfigUpdate(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", "Updated"),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "3"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_minimal(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfigMinimal(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ""),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "0"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_changeNameForceNew(t *testing.T) {
	var before, after wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	ipSetNewName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &before),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfig(ipSetNewName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &after),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "name", ipSetNewName),
					resource.TestCheckResourceAttr(resourceName, "description", ipSetNewName),
					resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
					resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4),
					resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"),
				),
			},
		},
	})
}

func TestAccAwsWafv2IPSet_tags(t *testing.T) {
	var v wafv2.IPSet
	ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
	resourceName := "aws_wafv2_ip_set.ip_set"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSWafv2IPSetDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag1", "Value1"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
				ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName),
			},
			{
				Config: testAccAwsWafv2IPSetConfigTwoTags(ipSetName, "Tag1", "Value1Updated", "Tag2", "Value2"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1Updated"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
			{
				Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag2", "Value2"),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v),
					testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
					resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"),
				),
			},
		},
	})
}

func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_wafv2_ip_set" {
			continue
		}

		conn := testAccProvider.Meta().(*AWSClient).wafv2conn
		resp, err := conn.GetIPSet(
			&wafv2.GetIPSetInput{
				Id:    aws.String(rs.Primary.ID),
				Name:  aws.String(rs.Primary.Attributes["name"]),
				Scope: aws.String(rs.Primary.Attributes["scope"]),
			})

		if err == nil {
			if *resp.IPSet.Id == rs.Primary.ID {
				return fmt.Errorf("WAFV2 IPSet %s still exists", rs.Primary.ID)
			}
		}

		// Return nil if the IPSet is already destroyed
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == wafv2.ErrCodeWAFNonexistentItemException {
				return nil
			}
		}

		return err
	}

	return nil
}

func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) 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 WAFV2 IPSet ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).wafv2conn
		resp, err := conn.GetIPSet(&wafv2.GetIPSetInput{
			Id:    aws.String(rs.Primary.ID),
			Name:  aws.String(rs.Primary.Attributes["name"]),
			Scope: aws.String(rs.Primary.Attributes["scope"]),
		})

		if err != nil {
			return err
		}

		if *resp.IPSet.Id == rs.Primary.ID {
			*v = *resp.IPSet
			return nil
		}

		return fmt.Errorf("WAFV2 IPSet (%s) not found", rs.Primary.ID)
	}
}

func testAccAwsWafv2IPSetConfig(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name               = "%s"
  description        = "%s"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }
}
`, name, name)
}

func testAccAwsWafv2IPSetConfigUpdate(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name               = "%s"
  description        = "Updated"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = ["1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/32"]
}
`, name)
}

func testAccAwsWafv2IPSetConfigMinimal(name string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name               = "%s"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
}
`, name)
}

func testAccAwsWafv2IPSetConfigOneTag(name, tagKey, tagValue string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name               = "%s"
  description        = "%s"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    "%s" = "%s"
  }
}
`, name, name, tagKey, tagValue)
}

func testAccAwsWafv2IPSetConfigTwoTags(name, tag1Key, tag1Value, tag2Key, tag2Value string) string {
	return fmt.Sprintf(`
resource "aws_wafv2_ip_set" "ip_set" {
  name               = "%s"
  description        = "%s"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    "%s" = "%s"
    "%s" = "%s"
  }
}
`, name, name, tag1Key, tag1Value, tag2Key, tag2Value)
}

func testAccAWSWafv2IPSetImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
	return func(s *terraform.State) (string, error) {
		rs, ok := s.RootModule().Resources[resourceName]
		if !ok {
			return "", fmt.Errorf("Not found: %s", resourceName)
		}

		return fmt.Sprintf("%s/%s/%s", rs.Primary.ID, rs.Primary.Attributes["name"], rs.Primary.Attributes["scope"]), nil
	}
}
<|endoftext|>


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

package main

import (
	"image"
	"math"

	"github.com/thinkofdeath/steven/type/direction"
)

type processedModel struct {
	faces            []processedFace
	ambientOcclusion bool
}

type processedFace struct {
	cullFace  direction.Type
	facing    direction.Type
	vertices  []chunkVertex
	shade     bool
	tintIndex int
}

func precomputeModel(bm *blockModel) *processedModel {
	p := &processedModel{}
	p.ambientOcclusion = bm.ambientOcclusion
	for ei := range bm.elements {
		// Render the last element first so that
		// grass's overlay works correctly.
		el := bm.elements[len(bm.elements)-1-ei]
		for i, face := range el.faces {
			faceID := i
			if face == nil {
				continue
			}
			pFace := processedFace{}
			cullFace := face.cullFace
			if bm.y > 0 {
				if cullFace >= 2 && cullFace != direction.Invalid {
					var pos int
					for di, d := range faceRotation {
						if d == cullFace {
							pos = di
							break
						}
					}
					cullFace = faceRotation[(pos+(int(bm.y)/90))%len(faceRotation)]
				}
				if faceID >= 2 {
					var pos int
					for di, d := range faceRotation {
						if d == direction.Type(faceID) {
							pos = di
							break
						}
					}
					faceID = int(faceRotation[(pos+(int(bm.y)/90))%len(faceRotation)])
				}
			}
			pFace.cullFace = cullFace
			pFace.facing = direction.Type(faceID)
			pFace.tintIndex = face.tintIndex
			pFace.shade = el.shade

			vert := faceVertices[i]
			tex := bm.lookupTexture(face.texture)

			ux1 := int16(face.uv[0] * tex.Width)
			ux2 := int16(face.uv[2] * tex.Width)
			uy1 := int16(face.uv[1] * tex.Height)
			uy2 := int16(face.uv[3] * tex.Height)

			var minX, minY, minZ int16 = math.MaxInt16, math.MaxInt16, math.MaxInt16
			var maxX, maxY, maxZ int16 = math.MinInt16, math.MinInt16, math.MinInt16

			for v := range vert {
				vert[v].TX = uint16(tex.X)
				vert[v].TY = uint16(tex.Y + tex.Atlas*1024.0)
				vert[v].TW = uint16(tex.Width)
				vert[v].TH = uint16(tex.Height)

				if vert[v].X == 0 {
					vert[v].X = int16(el.from[0] * 16)
				} else {
					vert[v].X = int16(el.to[0] * 16)
				}
				if vert[v].Y == 0 {
					vert[v].Y = int16(el.from[1] * 16)
				} else {
					vert[v].Y = int16(el.to[1] * 16)
				}
				if vert[v].Z == 0 {
					vert[v].Z = int16(el.from[2] * 16)
				} else {
					vert[v].Z = int16(el.to[2] * 16)
				}

				if el.rotation != nil {
					r := el.rotation
					switch r.axis {
					case "y":
						rotY := r.angle * (math.Pi / 180)
						c := math.Cos(rotY)
						s := math.Sin(rotY)
						x := float64(vert[v].X) - r.origin[0]*16
						z := float64(vert[v].Z) - r.origin[2]*16
						vert[v].X = int16(r.origin[0] + (x*c - z*s))
						vert[v].Z = int16(r.origin[2] + (z*c + x*s))
					case "x":
						rotX := r.angle * (math.Pi / 180)
						c := math.Cos(-rotX)
						s := math.Sin(-rotX)
						z := float64(vert[v].Z) - r.origin[1]*16
						y := float64(vert[v].Y) - r.origin[1]*16
						vert[v].Z = int16(r.origin[2] + (z*c - y*s))
						vert[v].Y = int16(r.origin[1] + (y*c + z*s))
					case "z":
						rotZ := r.angle * (math.Pi / 180)
						c := math.Cos(-rotZ)
						s := math.Sin(-rotZ)
						x := float64(vert[v].X) - r.origin[0]*16
						y := float64(vert[v].Y) - r.origin[1]*16
						vert[v].X = int16(r.origin[0] + (x*c - y*s))
						vert[v].Y = int16(r.origin[1] + (y*c + x*s))
					}
				}

				if bm.y > 0 {
					rotY := bm.y * (math.Pi / 180)
					c := int16(math.Cos(rotY))
					s := int16(math.Sin(rotY))
					x := vert[v].X - 8*16
					z := vert[v].Z - 8*16
					vert[v].X = 8*16 + int16(x*c-z*s)
					vert[v].Z = 8*16 + int16(z*c+x*s)
				}

				if vert[v].TOffsetX == 0 {
					vert[v].TOffsetX = int16(ux1)
				} else {
					vert[v].TOffsetX = int16(ux2)
				}
				if vert[v].TOffsetY == 0 {
					vert[v].TOffsetY = int16(uy1)
				} else {
					vert[v].TOffsetY = int16(uy2)
				}

				if face.rotation > 0 {
					rotY := float64(face.rotation) * (math.Pi / 180)
					c := int16(math.Cos(rotY))
					s := int16(math.Sin(rotY))
					x := vert[v].TOffsetX - 8*16
					y := vert[v].TOffsetY - 8*16
					vert[v].TOffsetX = 8*16 + int16(x*c-y*s)
					vert[v].TOffsetY = 8*16 + int16(y*c+x*s)
				}

				if el.rotation != nil && el.rotation.rescale {
					if vert[v].X < minX {
						minX = vert[v].X
					} else if vert[v].X > maxX {
						maxX = vert[v].X
					}
					if vert[v].Y < minY {
						minY = vert[v].Y
					} else if vert[v].Y > maxY {
						maxY = vert[v].Y
					}
					if vert[v].Z < minZ {
						minZ = vert[v].Z
					} else if vert[v].Z > maxZ {
						maxZ = vert[v].Z
					}
				}
			}

			if el.rotation != nil && el.rotation.rescale {
				diffX := float64(maxX - minX)
				diffY := float64(maxY - minY)
				diffZ := float64(maxZ - minZ)
				for v := range vert {
					vert[v].X = int16((float64(vert[v].X-minX) / diffX) * 256)
					vert[v].Y = int16((float64(vert[v].Y-minY) / diffY) * 256)
					vert[v].Z = int16((float64(vert[v].Z-minZ) / diffZ) * 256)
				}
			}

			pFace.vertices = vert[:]

			p.faces = append(p.faces, pFace)
		}
	}
	return p
}

func (p processedModel) Render(x, y, z int, bs *blocksSnapshot) []chunkVertex {
	var out []chunkVertex
	this := bs.block(x, y, z)
	for _, f := range p.faces {
		if f.cullFace != direction.Invalid {
			ox, oy, oz := f.cullFace.Offset()
			if b := bs.block(x+ox, y+oy, z+oz); b.ShouldCullAgainst() || b == this {
				continue
			}
		}

		off := len(out)
		out = append(out, f.vertices...)
		verts := out[off:]

		var cr, cg, cb byte
		cr = 255
		cg = 255
		cb = 255
		if this.TintImage() != nil {
			switch f.tintIndex {
			case 0:
				cr, cg, cb = calculateBiome(bs, x, z, this.TintImage())
			}
		}
		if f.facing == direction.West || f.facing == direction.East {
			cr = byte(float64(cr) * 0.8)
			cg = byte(float64(cg) * 0.8)
			cb = byte(float64(cb) * 0.8)
		}

		for i := range verts {
			verts[i].R = cr
			verts[i].G = cg
			verts[i].B = cb

			verts[i].X += int16(x * 256)
			verts[i].Y += int16(y * 256)
			verts[i].Z += int16(z * 256)

			verts[i].BlockLight, verts[i].SkyLight = calculateLight(
				bs,
				x, y, z,
				float64(verts[i].X)/256.0,
				float64(verts[i].Y)/256.0,
				float64(verts[i].Z)/256.0,
				int(f.facing), p.ambientOcclusion, this.ForceShade(),
			)
		}
	}
	return out
}

// Takes an average of the biome colors of the surrounding area
func calculateBiome(bs *blocksSnapshot, x, z int, img *image.NRGBA) (byte, byte, byte) {
	count := 0
	var r, g, b int
	for xx := -2; xx <= 2; xx++ {
		for zz := -2; zz <= 2; zz++ {
			biome := bs.biome(x+xx, z+zz)
			ix := biome.ColorIndex & 0xFF
			iy := biome.ColorIndex >> 8
			col := img.NRGBAAt(ix, iy)
			r += int(col.R)
			g += int(col.G)
			b += int(col.B)
			count++
		}
	}
	return byte(r / count), byte(g / count), byte(b / count)
}

func calculateLight(bs *blocksSnapshot, origX, origY, origZ int,
	x, y, z float64, face int, smooth, force bool) (byte, byte) {
	blockLight := bs.blockLight(origX, origY, origZ)
	skyLight := bs.skyLight(origX, origY, origZ)
	if !smooth {
		return blockLight, skyLight
	}
	count := 1

	// TODO(Think) Document/cleanup this
	// it was taken from and older renderer of mine
	// (thinkmap).

	var pox, poy, poz, nox, noy, noz int

	switch face {
	case 0: // Up
		poz, pox = 0, 0
		noz, nox = -1, -1
		poy = 1
		noy = 0
	case 1: // Down
		poz, pox = 0, 0
		noz, nox = -1, -1
		poy = -1
		noy = -2
	case 2: // North
		poy, pox = 0, 0
		noy, nox = -1, -1
		poz = -1
		noz = -2
	case 3: // South
		poy, pox = 0, 0
		noy, nox = -1, -1
		poz = 1
		noz = 0
	case 4: // West
		poz, poy = 0, 0
		noz, noy = -1, -1
		pox = -1
		nox = -2
	case 5: // East
		poz, poy = 0, 0
		noz, noy = -1, -1
		pox = 1
		nox = 0
	}
	for ox := nox; ox <= pox; ox++ {
		for oy := noy; oy <= poy; oy++ {
			for oz := noz; oz <= poz; oz++ {
				bx := round(x + float64(ox))
				by := round(y + float64(oy))
				bz := round(z + float64(oz))
				count++
				blockLight += bs.blockLight(bx, by, bz)
				if !force {
					skyLight += bs.skyLight(bx, by, bz)
				} else if bl := bs.block(bx, by, bz); bl.Is(BlockAir) {
					skyLight += 15
				}
			}
		}

	}

	return blockLight / byte(count), skyLight / byte(count)
}

func round(f float64) int {
	return int(f + math.Copysign(0.5, f))
}
<commit_msg>/: disable texture rotation<commit_after>// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"image"
	"math"

	"github.com/thinkofdeath/steven/type/direction"
)

type processedModel struct {
	faces            []processedFace
	ambientOcclusion bool
}

type processedFace struct {
	cullFace  direction.Type
	facing    direction.Type
	vertices  []chunkVertex
	shade     bool
	tintIndex int
}

func precomputeModel(bm *blockModel) *processedModel {
	p := &processedModel{}
	p.ambientOcclusion = bm.ambientOcclusion
	for ei := range bm.elements {
		// Render the last element first so that
		// grass's overlay works correctly.
		el := bm.elements[len(bm.elements)-1-ei]
		for i, face := range el.faces {
			faceID := i
			if face == nil {
				continue
			}
			pFace := processedFace{}
			cullFace := face.cullFace
			if bm.y > 0 {
				if cullFace >= 2 && cullFace != direction.Invalid {
					var pos int
					for di, d := range faceRotation {
						if d == cullFace {
							pos = di
							break
						}
					}
					cullFace = faceRotation[(pos+(int(bm.y)/90))%len(faceRotation)]
				}
				if faceID >= 2 {
					var pos int
					for di, d := range faceRotation {
						if d == direction.Type(faceID) {
							pos = di
							break
						}
					}
					faceID = int(faceRotation[(pos+(int(bm.y)/90))%len(faceRotation)])
				}
			}
			pFace.cullFace = cullFace
			pFace.facing = direction.Type(faceID)
			pFace.tintIndex = face.tintIndex
			pFace.shade = el.shade

			vert := faceVertices[i]
			tex := bm.lookupTexture(face.texture)

			ux1 := int16(face.uv[0] * tex.Width)
			ux2 := int16(face.uv[2] * tex.Width)
			uy1 := int16(face.uv[1] * tex.Height)
			uy2 := int16(face.uv[3] * tex.Height)

			var minX, minY, minZ int16 = math.MaxInt16, math.MaxInt16, math.MaxInt16
			var maxX, maxY, maxZ int16 = math.MinInt16, math.MinInt16, math.MinInt16

			for v := range vert {
				vert[v].TX = uint16(tex.X)
				vert[v].TY = uint16(tex.Y + tex.Atlas*1024.0)
				vert[v].TW = uint16(tex.Width)
				vert[v].TH = uint16(tex.Height)

				if vert[v].X == 0 {
					vert[v].X = int16(el.from[0] * 16)
				} else {
					vert[v].X = int16(el.to[0] * 16)
				}
				if vert[v].Y == 0 {
					vert[v].Y = int16(el.from[1] * 16)
				} else {
					vert[v].Y = int16(el.to[1] * 16)
				}
				if vert[v].Z == 0 {
					vert[v].Z = int16(el.from[2] * 16)
				} else {
					vert[v].Z = int16(el.to[2] * 16)
				}

				if el.rotation != nil {
					r := el.rotation
					switch r.axis {
					case "y":
						rotY := r.angle * (math.Pi / 180)
						c := math.Cos(rotY)
						s := math.Sin(rotY)
						x := float64(vert[v].X) - r.origin[0]*16
						z := float64(vert[v].Z) - r.origin[2]*16
						vert[v].X = int16(r.origin[0] + (x*c - z*s))
						vert[v].Z = int16(r.origin[2] + (z*c + x*s))
					case "x":
						rotX := r.angle * (math.Pi / 180)
						c := math.Cos(-rotX)
						s := math.Sin(-rotX)
						z := float64(vert[v].Z) - r.origin[1]*16
						y := float64(vert[v].Y) - r.origin[1]*16
						vert[v].Z = int16(r.origin[2] + (z*c - y*s))
						vert[v].Y = int16(r.origin[1] + (y*c + z*s))
					case "z":
						rotZ := r.angle * (math.Pi / 180)
						c := math.Cos(-rotZ)
						s := math.Sin(-rotZ)
						x := float64(vert[v].X) - r.origin[0]*16
						y := float64(vert[v].Y) - r.origin[1]*16
						vert[v].X = int16(r.origin[0] + (x*c - y*s))
						vert[v].Y = int16(r.origin[1] + (y*c + x*s))
					}
				}

				if bm.y > 0 {
					rotY := bm.y * (math.Pi / 180)
					c := int16(math.Cos(rotY))
					s := int16(math.Sin(rotY))
					x := vert[v].X - 8*16
					z := vert[v].Z - 8*16
					vert[v].X = 8*16 + int16(x*c-z*s)
					vert[v].Z = 8*16 + int16(z*c+x*s)
				}

				if vert[v].TOffsetX == 0 {
					vert[v].TOffsetX = int16(ux1)
				} else {
					vert[v].TOffsetX = int16(ux2)
				}
				if vert[v].TOffsetY == 0 {
					vert[v].TOffsetY = int16(uy1)
				} else {
					vert[v].TOffsetY = int16(uy2)
				}

				// We don't seem to need to do this
				// keep it here in case
				/*
					if face.rotation > 0 {
						rotY := float64(face.rotation) * (math.Pi / 180)
						c := int16(math.Cos(rotY))
						s := int16(math.Sin(rotY))
						x := vert[v].TOffsetX - 8*16
						y := vert[v].TOffsetY - 8*16
						vert[v].TOffsetX = 8*16 + int16(x*c-y*s)
						vert[v].TOffsetY = 8*16 + int16(y*c+x*s)
					}
				*/

				if el.rotation != nil && el.rotation.rescale {
					if vert[v].X < minX {
						minX = vert[v].X
					} else if vert[v].X > maxX {
						maxX = vert[v].X
					}
					if vert[v].Y < minY {
						minY = vert[v].Y
					} else if vert[v].Y > maxY {
						maxY = vert[v].Y
					}
					if vert[v].Z < minZ {
						minZ = vert[v].Z
					} else if vert[v].Z > maxZ {
						maxZ = vert[v].Z
					}
				}
			}

			if el.rotation != nil && el.rotation.rescale {
				diffX := float64(maxX - minX)
				diffY := float64(maxY - minY)
				diffZ := float64(maxZ - minZ)
				for v := range vert {
					vert[v].X = int16((float64(vert[v].X-minX) / diffX) * 256)
					vert[v].Y = int16((float64(vert[v].Y-minY) / diffY) * 256)
					vert[v].Z = int16((float64(vert[v].Z-minZ) / diffZ) * 256)
				}
			}

			pFace.vertices = vert[:]

			p.faces = append(p.faces, pFace)
		}
	}
	return p
}

func (p processedModel) Render(x, y, z int, bs *blocksSnapshot) []chunkVertex {
	var out []chunkVertex
	this := bs.block(x, y, z)
	for _, f := range p.faces {
		if f.cullFace != direction.Invalid {
			ox, oy, oz := f.cullFace.Offset()
			if b := bs.block(x+ox, y+oy, z+oz); b.ShouldCullAgainst() || b == this {
				continue
			}
		}

		off := len(out)
		out = append(out, f.vertices...)
		verts := out[off:]

		var cr, cg, cb byte
		cr = 255
		cg = 255
		cb = 255
		if this.TintImage() != nil {
			switch f.tintIndex {
			case 0:
				cr, cg, cb = calculateBiome(bs, x, z, this.TintImage())
			}
		}
		if f.facing == direction.West || f.facing == direction.East {
			cr = byte(float64(cr) * 0.8)
			cg = byte(float64(cg) * 0.8)
			cb = byte(float64(cb) * 0.8)
		}

		for i := range verts {
			verts[i].R = cr
			verts[i].G = cg
			verts[i].B = cb

			verts[i].X += int16(x * 256)
			verts[i].Y += int16(y * 256)
			verts[i].Z += int16(z * 256)

			verts[i].BlockLight, verts[i].SkyLight = calculateLight(
				bs,
				x, y, z,
				float64(verts[i].X)/256.0,
				float64(verts[i].Y)/256.0,
				float64(verts[i].Z)/256.0,
				int(f.facing), p.ambientOcclusion, this.ForceShade(),
			)
		}
	}
	return out
}

// Takes an average of the biome colors of the surrounding area
func calculateBiome(bs *blocksSnapshot, x, z int, img *image.NRGBA) (byte, byte, byte) {
	count := 0
	var r, g, b int
	for xx := -2; xx <= 2; xx++ {
		for zz := -2; zz <= 2; zz++ {
			biome := bs.biome(x+xx, z+zz)
			ix := biome.ColorIndex & 0xFF
			iy := biome.ColorIndex >> 8
			col := img.NRGBAAt(ix, iy)
			r += int(col.R)
			g += int(col.G)
			b += int(col.B)
			count++
		}
	}
	return byte(r / count), byte(g / count), byte(b / count)
}

func calculateLight(bs *blocksSnapshot, origX, origY, origZ int,
	x, y, z float64, face int, smooth, force bool) (byte, byte) {
	blockLight := bs.blockLight(origX, origY, origZ)
	skyLight := bs.skyLight(origX, origY, origZ)
	if !smooth {
		return blockLight, skyLight
	}
	count := 1

	// TODO(Think) Document/cleanup this
	// it was taken from and older renderer of mine
	// (thinkmap).

	var pox, poy, poz, nox, noy, noz int

	switch face {
	case 0: // Up
		poz, pox = 0, 0
		noz, nox = -1, -1
		poy = 1
		noy = 0
	case 1: // Down
		poz, pox = 0, 0
		noz, nox = -1, -1
		poy = -1
		noy = -2
	case 2: // North
		poy, pox = 0, 0
		noy, nox = -1, -1
		poz = -1
		noz = -2
	case 3: // South
		poy, pox = 0, 0
		noy, nox = -1, -1
		poz = 1
		noz = 0
	case 4: // West
		poz, poy = 0, 0
		noz, noy = -1, -1
		pox = -1
		nox = -2
	case 5: // East
		poz, poy = 0, 0
		noz, noy = -1, -1
		pox = 1
		nox = 0
	}
	for ox := nox; ox <= pox; ox++ {
		for oy := noy; oy <= poy; oy++ {
			for oz := noz; oz <= poz; oz++ {
				bx := round(x + float64(ox))
				by := round(y + float64(oy))
				bz := round(z + float64(oz))
				count++
				blockLight += bs.blockLight(bx, by, bz)
				if !force {
					skyLight += bs.skyLight(bx, by, bz)
				} else if bl := bs.block(bx, by, bz); bl.Is(BlockAir) {
					skyLight += 15
				}
			}
		}

	}

	return blockLight / byte(count), skyLight / byte(count)
}

func round(f float64) int {
	return int(f + math.Copysign(0.5, f))
}
<|endoftext|>


<commit_before>package manager

import (
	"fmt"
	"net"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/swarm-v2/api"
	"github.com/docker/swarm-v2/ca"
	"github.com/docker/swarm-v2/log"
	"github.com/docker/swarm-v2/manager/allocator"
	"github.com/docker/swarm-v2/manager/clusterapi"
	"github.com/docker/swarm-v2/manager/dispatcher"
	"github.com/docker/swarm-v2/manager/orchestrator"
	"github.com/docker/swarm-v2/manager/raftpicker"
	"github.com/docker/swarm-v2/manager/scheduler"
	"github.com/docker/swarm-v2/manager/state/raft"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

var _ api.ManagerServer = &Manager{}

// Config is used to tune the Manager.
type Config struct {
	SecurityConfig *ca.ManagerSecurityConfig

	ListenProto string
	ListenAddr  string
	// Listener will be used for grpc serving if it's not nil, ListenProto and
	// ListenAddr fields will be used otherwise.
	Listener net.Listener

	// JoinRaft is an optional address of a node in an existing raft
	// cluster to join.
	JoinRaft string

	// Top-level state directory
	StateDir string
}

// Manager is the cluster manager for Swarm.
// This is the high-level object holding and initializing all the manager
// subsystems.
type Manager struct {
	config *Config

	caserver     *ca.Server
	dispatcher   *dispatcher.Dispatcher
	orchestrator *orchestrator.Orchestrator
	scheduler    *scheduler.Scheduler
	allocator    *allocator.Allocator
	server       *grpc.Server
	raftNode     *raft.Node

	leadershipCh chan raft.LeadershipState
	leaderLock   sync.Mutex

	managerDone chan struct{}
}

// New creates a Manager which has not started to accept requests yet.
func New(config *Config) (*Manager, error) {
	dispatcherConfig := dispatcher.DefaultConfig()

	// TODO(stevvooe): Reported address of manager is plumbed to listen addr
	// for now, may want to make this separate. This can be tricky to get right
	// so we need to make it easy to override. This needs to be the address
	// through which agent nodes access the manager.
	dispatcherConfig.Addr = config.ListenAddr

	err := os.MkdirAll(config.StateDir, 0700)
	if err != nil {
		return nil, fmt.Errorf("failed to create state directory: %v", err)
	}

	raftStateDir := filepath.Join(config.StateDir, "raft")
	err = os.MkdirAll(raftStateDir, 0700)
	if err != nil {
		return nil, fmt.Errorf("failed to create raft state directory: %v", err)
	}

	raftCfg := raft.DefaultNodeConfig()

	leadershipCh := make(chan raft.LeadershipState)

	newNodeOpts := raft.NewNodeOptions{
		Addr:           config.ListenAddr,
		JoinAddr:       config.JoinRaft,
		Config:         raftCfg,
		StateDir:       raftStateDir,
		TLSCredentials: config.SecurityConfig.ClientTLSCreds,
	}
	raftNode, err := raft.NewNode(context.TODO(), newNodeOpts, leadershipCh)
	if err != nil {
		return nil, fmt.Errorf("can't create raft node: %v", err)
	}

	store := raftNode.MemoryStore()

	opts := []grpc.ServerOption{
		grpc.Creds(config.SecurityConfig.ServerTLSCreds)}

	m := &Manager{
		config:       config,
		caserver:     ca.NewServer(config.SecurityConfig),
		dispatcher:   dispatcher.New(store, dispatcherConfig),
		server:       grpc.NewServer(opts...),
		raftNode:     raftNode,
		leadershipCh: leadershipCh,
	}

	return m, nil
}

// Run starts all manager sub-systems and the gRPC server at the configured
// address.
// The call never returns unless an error occurs or `Stop()` is called.
func (m *Manager) Run(ctx context.Context) error {
	lis := m.config.Listener
	if lis == nil {
		l, err := net.Listen(m.config.ListenProto, m.config.ListenAddr)
		if err != nil {
			return err
		}
		lis = l
	}

	m.raftNode.Server = m.server

	m.managerDone = make(chan struct{})
	defer close(m.managerDone)

	go func() {
		for {
			select {
			case newState := <-m.leadershipCh:
				if newState == raft.IsLeader {
					store := m.raftNode.MemoryStore()

					m.leaderLock.Lock()
					m.orchestrator = orchestrator.New(store)
					m.scheduler = scheduler.New(store)

					// TODO(stevvooe): Allocate a context that can be used to
					// shutdown underlying manager processes when leadership is
					// lost.

					allocator, err := allocator.New(store)
					if err != nil {
						log.G(ctx).WithError(err).Error("failed to create allocator")
						// TODO(stevvooe): It doesn't seem correct here to fail
						// creating the allocator but then use it anyways.
					}
					m.allocator = allocator

					m.leaderLock.Unlock()

					// Start all sub-components in separate goroutines.
					// TODO(aluzzardi): This should have some kind of error handling so that
					// any component that goes down would bring the entire manager down.

					if m.allocator != nil {
						if err := m.allocator.Start(ctx); err != nil {
							log.G(ctx).WithError(err).Error("allocator exited with an error")
						}
					}

					go func() {
						if err := m.scheduler.Run(ctx); err != nil {
							log.G(ctx).WithError(err).Error("scheduler exited with an error")
						}
					}()
					go func() {
						if err := m.orchestrator.Run(ctx); err != nil {
							log.G(ctx).WithError(err).Error("orchestrator exited with an error")
						}
					}()
				} else if newState == raft.IsFollower {
					m.leaderLock.Lock()
					m.orchestrator.Stop()
					m.scheduler.Stop()

					if m.allocator != nil {
						m.allocator.Stop()
					}

					m.orchestrator = nil
					m.scheduler = nil
					m.allocator = nil
					m.leaderLock.Unlock()
				}
			case <-m.managerDone:
				return
			}
		}
	}()

	ctx = log.WithLogger(ctx, log.G(ctx).WithFields(
		logrus.Fields{
			"proto": lis.Addr().Network(),
			"addr":  lis.Addr().String()}))
	log.G(ctx).Info("listening")
	go m.raftNode.Run(ctx)

	backoffConfig := *grpc.DefaultBackoffConfig
	backoffConfig.MaxDelay = 2 * time.Second

	proxyOpts := []grpc.DialOption{
		grpc.WithBackoffConfig(&backoffConfig),
		grpc.WithTransportCredentials(m.config.SecurityConfig.ClientTLSCreds),
	}

	cs := raftpicker.NewConnSelector(m.raftNode, proxyOpts...)

	localAPI := clusterapi.NewServer(m.raftNode.MemoryStore(), m.raftNode)
	proxyAPI := api.NewRaftProxyClusterServer(localAPI, cs, m.raftNode)

	api.RegisterCAServer(m.server, m.caserver)
	api.RegisterRaftServer(m.server, m.raftNode)
	api.RegisterManagerServer(m.server, m)
	api.RegisterClusterServer(m.server, proxyAPI)
	api.RegisterDispatcherServer(m.server, m.dispatcher)

	errServe := make(chan error, 1)
	go func() {
		errServe <- m.server.Serve(lis)
	}()

	leaderCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
	if err := raft.WaitForLeader(leaderCtx, m.raftNode); err != nil {
		m.server.Stop()
		return err
	}
	cancel()
	return <-errServe
}

// Stop stops the manager. It immediately closes all open connections and
// active RPCs as well as stopping the scheduler.
func (m *Manager) Stop() {
	m.leaderLock.Lock()
	if m.orchestrator != nil {
		m.orchestrator.Stop()
	}
	if m.scheduler != nil {
		m.scheduler.Stop()
	}
	m.leaderLock.Unlock()

	m.raftNode.Shutdown()
	m.server.Stop()
}

// GRPC Methods

// NodeCount returns number of nodes connected to particular manager.
// Supposed to be called only by cluster leader.
func (m *Manager) NodeCount(ctx context.Context, r *api.NodeCountRequest) (*api.NodeCountResponse, error) {
	managerID, err := ca.AuthorizeRole(ctx, []string{ca.ManagerRole})
	if err != nil {
		return nil, err
	}

	log.G(ctx).WithField("request", r).Debugf("(*Manager).NodeCount from node %s", managerID)

	return &api.NodeCountResponse{
		Count: m.dispatcher.NodeCount(),
	}, nil
}
<commit_msg>manager: Create listener earlier<commit_after>package manager

import (
	"fmt"
	"net"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/swarm-v2/api"
	"github.com/docker/swarm-v2/ca"
	"github.com/docker/swarm-v2/log"
	"github.com/docker/swarm-v2/manager/allocator"
	"github.com/docker/swarm-v2/manager/clusterapi"
	"github.com/docker/swarm-v2/manager/dispatcher"
	"github.com/docker/swarm-v2/manager/orchestrator"
	"github.com/docker/swarm-v2/manager/raftpicker"
	"github.com/docker/swarm-v2/manager/scheduler"
	"github.com/docker/swarm-v2/manager/state/raft"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

var _ api.ManagerServer = &Manager{}

// Config is used to tune the Manager.
type Config struct {
	SecurityConfig *ca.ManagerSecurityConfig

	ListenProto string
	ListenAddr  string
	// Listener will be used for grpc serving if it's not nil, ListenProto and
	// ListenAddr fields will be used otherwise.
	Listener net.Listener

	// JoinRaft is an optional address of a node in an existing raft
	// cluster to join.
	JoinRaft string

	// Top-level state directory
	StateDir string
}

// Manager is the cluster manager for Swarm.
// This is the high-level object holding and initializing all the manager
// subsystems.
type Manager struct {
	config   *Config
	listener net.Listener

	caserver     *ca.Server
	dispatcher   *dispatcher.Dispatcher
	orchestrator *orchestrator.Orchestrator
	scheduler    *scheduler.Scheduler
	allocator    *allocator.Allocator
	server       *grpc.Server
	raftNode     *raft.Node

	leadershipCh chan raft.LeadershipState
	leaderLock   sync.Mutex

	managerDone chan struct{}
}

// New creates a Manager which has not started to accept requests yet.
func New(config *Config) (*Manager, error) {
	dispatcherConfig := dispatcher.DefaultConfig()

	// TODO(stevvooe): Reported address of manager is plumbed to listen addr
	// for now, may want to make this separate. This can be tricky to get right
	// so we need to make it easy to override. This needs to be the address
	// through which agent nodes access the manager.
	dispatcherConfig.Addr = config.ListenAddr

	err := os.MkdirAll(config.StateDir, 0700)
	if err != nil {
		return nil, fmt.Errorf("failed to create state directory: %v", err)
	}

	raftStateDir := filepath.Join(config.StateDir, "raft")
	err = os.MkdirAll(raftStateDir, 0700)
	if err != nil {
		return nil, fmt.Errorf("failed to create raft state directory: %v", err)
	}

	lis := config.Listener
	if lis == nil {
		l, err := net.Listen(config.ListenProto, config.ListenAddr)
		if err != nil {
			return nil, err
		}
		lis = l
	}

	raftCfg := raft.DefaultNodeConfig()

	leadershipCh := make(chan raft.LeadershipState)

	newNodeOpts := raft.NewNodeOptions{
		Addr:           config.ListenAddr,
		JoinAddr:       config.JoinRaft,
		Config:         raftCfg,
		StateDir:       raftStateDir,
		TLSCredentials: config.SecurityConfig.ClientTLSCreds,
	}
	raftNode, err := raft.NewNode(context.TODO(), newNodeOpts, leadershipCh)
	if err != nil {
		lis.Close()
		return nil, fmt.Errorf("can't create raft node: %v", err)
	}

	store := raftNode.MemoryStore()

	opts := []grpc.ServerOption{
		grpc.Creds(config.SecurityConfig.ServerTLSCreds)}

	m := &Manager{
		config:       config,
		listener:     lis,
		caserver:     ca.NewServer(config.SecurityConfig),
		dispatcher:   dispatcher.New(store, dispatcherConfig),
		server:       grpc.NewServer(opts...),
		raftNode:     raftNode,
		leadershipCh: leadershipCh,
	}

	return m, nil
}

// Run starts all manager sub-systems and the gRPC server at the configured
// address.
// The call never returns unless an error occurs or `Stop()` is called.
func (m *Manager) Run(ctx context.Context) error {
	m.managerDone = make(chan struct{})
	defer close(m.managerDone)

	go func() {
		for {
			select {
			case newState := <-m.leadershipCh:
				if newState == raft.IsLeader {
					store := m.raftNode.MemoryStore()

					m.leaderLock.Lock()
					m.orchestrator = orchestrator.New(store)
					m.scheduler = scheduler.New(store)

					// TODO(stevvooe): Allocate a context that can be used to
					// shutdown underlying manager processes when leadership is
					// lost.

					allocator, err := allocator.New(store)
					if err != nil {
						log.G(ctx).WithError(err).Error("failed to create allocator")
						// TODO(stevvooe): It doesn't seem correct here to fail
						// creating the allocator but then use it anyways.
					}
					m.allocator = allocator

					m.leaderLock.Unlock()

					// Start all sub-components in separate goroutines.
					// TODO(aluzzardi): This should have some kind of error handling so that
					// any component that goes down would bring the entire manager down.

					if m.allocator != nil {
						if err := m.allocator.Start(ctx); err != nil {
							log.G(ctx).WithError(err).Error("allocator exited with an error")
						}
					}

					go func() {
						if err := m.scheduler.Run(ctx); err != nil {
							log.G(ctx).WithError(err).Error("scheduler exited with an error")
						}
					}()
					go func() {
						if err := m.orchestrator.Run(ctx); err != nil {
							log.G(ctx).WithError(err).Error("orchestrator exited with an error")
						}
					}()
				} else if newState == raft.IsFollower {
					m.leaderLock.Lock()
					m.orchestrator.Stop()
					m.scheduler.Stop()

					if m.allocator != nil {
						m.allocator.Stop()
					}

					m.orchestrator = nil
					m.scheduler = nil
					m.allocator = nil
					m.leaderLock.Unlock()
				}
			case <-m.managerDone:
				return
			}
		}
	}()

	ctx = log.WithLogger(ctx, log.G(ctx).WithFields(
		logrus.Fields{
			"proto": m.listener.Addr().Network(),
			"addr":  m.listener.Addr().String()}))
	log.G(ctx).Info("listening")
	go m.raftNode.Run(ctx)

	backoffConfig := *grpc.DefaultBackoffConfig
	backoffConfig.MaxDelay = 2 * time.Second

	proxyOpts := []grpc.DialOption{
		grpc.WithBackoffConfig(&backoffConfig),
		grpc.WithTransportCredentials(m.config.SecurityConfig.ClientTLSCreds),
	}

	cs := raftpicker.NewConnSelector(m.raftNode, proxyOpts...)

	localAPI := clusterapi.NewServer(m.raftNode.MemoryStore(), m.raftNode)
	proxyAPI := api.NewRaftProxyClusterServer(localAPI, cs, m.raftNode)

	api.RegisterCAServer(m.server, m.caserver)
	api.RegisterRaftServer(m.server, m.raftNode)
	api.RegisterManagerServer(m.server, m)
	api.RegisterClusterServer(m.server, proxyAPI)
	api.RegisterDispatcherServer(m.server, m.dispatcher)

	errServe := make(chan error, 1)
	go func() {
		errServe <- m.server.Serve(m.listener)
	}()

	leaderCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
	if err := raft.WaitForLeader(leaderCtx, m.raftNode); err != nil {
		m.server.Stop()
		return err
	}
	cancel()
	return <-errServe
}

// Stop stops the manager. It immediately closes all open connections and
// active RPCs as well as stopping the scheduler.
func (m *Manager) Stop() {
	m.leaderLock.Lock()
	if m.orchestrator != nil {
		m.orchestrator.Stop()
	}
	if m.scheduler != nil {
		m.scheduler.Stop()
	}
	m.leaderLock.Unlock()

	m.raftNode.Shutdown()
	m.server.Stop()
}

// GRPC Methods

// NodeCount returns number of nodes connected to particular manager.
// Supposed to be called only by cluster leader.
func (m *Manager) NodeCount(ctx context.Context, r *api.NodeCountRequest) (*api.NodeCountResponse, error) {
	managerID, err := ca.AuthorizeRole(ctx, []string{ca.ManagerRole})
	if err != nil {
		return nil, err
	}

	log.G(ctx).WithField("request", r).Debugf("(*Manager).NodeCount from node %s", managerID)

	return &api.NodeCountResponse{
		Count: m.dispatcher.NodeCount(),
	}, nil
}
<|endoftext|>


<commit_before>package restfulspec

import (
	"testing"

	restful "github.com/emicklei/go-restful"
	"github.com/go-openapi/spec"
)

func TestRouteToPath(t *testing.T) {
	description := "get the a b test\nthis is the test description"
	notes := "notes\nblah blah"

	ws := new(restful.WebService)
	ws.Path("/tests/{v}")
	ws.Param(ws.PathParameter("v", "value of v").DefaultValue("default-v"))
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)
	ws.Route(ws.GET("/a/{b}").To(dummy).
		Doc(description).
		Notes(notes).
		Param(ws.PathParameter("b", "value of b").DefaultValue("default-b")).
		Param(ws.QueryParameter("q", "value of q").DefaultValue("default-q")).
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))
	ws.Route(ws.GET("/a/{b}/{c:[a-z]+}/{d:[1-9]+}/e").To(dummy).
		Param(ws.PathParameter("b", "value of b").DefaultValue("default-b")).
		Param(ws.PathParameter("c", "with regex").DefaultValue("abc")).
		Param(ws.PathParameter("d", "with regex").DefaultValue("abcef")).
		Param(ws.QueryParameter("q", "value of q").DefaultValue("default-q")).
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	if p.Paths["/tests/{v}/a/{b}"].Get.Parameters[0].Type != "string" {
		t.Error("Parameter type is not set.")
	}
	if _, exists := p.Paths["/tests/{v}/a/{b}/{c}/{d}/e"]; !exists {
		t.Error("Expected path to exist after it was sanitized.")
	}

	if p.Paths["/tests/{v}/a/{b}"].Get.Description != notes {
		t.Errorf("GET description incorrect")
	}
	if p.Paths["/tests/{v}/a/{b}"].Get.Summary != "get the a b test\nthis is the test description" {
		t.Errorf("GET summary incorrect")
	}
	response := p.Paths["/tests/{v}/a/{b}"].Get.Responses.StatusCodeResponses[200]
	if response.Schema.Type[0] != "array" {
		t.Errorf("response type incorrect")
	}
	if response.Schema.Items.Schema.Ref.String() != "#/definitions/restfulspec.Sample" {
		t.Errorf("response element type incorrect")
	}

	// Test for patterns
	path := p.Paths["/tests/{v}/a/{b}/{c}/{d}/e"]
	checkPattern(t, path, "c", "[a-z]+")
	checkPattern(t, path, "d", "[1-9]+")
	checkPattern(t, path, "v", "")
}

func getParameter(path spec.PathItem, name string) (*spec.Parameter, bool) {
	for _, param := range path.Get.Parameters {
		if param.Name == name {
			return &param, true
		}
	}
	return nil, false
}

func checkPattern(t *testing.T, path spec.PathItem, paramName string, pattern string) {
	param, exists := getParameter(path, paramName)
	if !exists {
		t.Error("Expected Parameter %s to exist", paramName)
	}
	if param.Pattern != pattern {
		t.Error("Expected pattern %s to equal %s", param.Pattern, pattern)
	}
}

func TestMultipleMethodsRouteToPath(t *testing.T) {
	ws := new(restful.WebService)
	ws.Path("/tests/a")
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)
	ws.Route(ws.GET("/a/b").To(dummy).
		Doc("get a b test").
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))
	ws.Route(ws.POST("/a/b").To(dummy).
		Doc("post a b test").
		Returns(200, "list of a b tests", []Sample{}).
		Returns(500, "internal server error", []Sample{}).
		Reads(Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	if p.Paths["/tests/a/a/b"].Get.Summary != "get a b test" {
		t.Errorf("GET summary incorrect")
	}
	if p.Paths["/tests/a/a/b"].Post.Summary != "post a b test" {
		t.Errorf("POST summary incorrect")
	}
	if _, exists := p.Paths["/tests/a/a/b"].Post.Responses.StatusCodeResponses[500]; !exists {
		t.Errorf("Response code 500 not added to spec.")
	}

	expectedRef := spec.MustCreateRef("#/definitions/restfulspec.Sample")
	postBodyparam := p.Paths["/tests/a/a/b"].Post.Parameters[0]
	postBodyRef := postBodyparam.Schema.Ref
	if postBodyRef.String() != expectedRef.String() {
		t.Errorf("Expected: %s, Got: %s", expectedRef.String(), postBodyRef.String())
	}

	if postBodyparam.Format != "" || postBodyparam.Type != "" || postBodyparam.Default != nil {
		t.Errorf("Invalid parameter property is set on body property")
	}
}

func TestReadArrayObjectInBody(t *testing.T) {
	ws := new(restful.WebService)
	ws.Path("/tests/a")
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)

	ws.Route(ws.POST("/a/b").To(dummy).
		Doc("post a b test with array in body").
		Returns(200, "list of a b tests", []Sample{}).
		Returns(500, "internal server error", []Sample{}).
		Reads([]Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	postInfo := p.Paths["/tests/a/a/b"].Post

	if postInfo.Summary != "post a b test with array in body" {
		t.Errorf("POST description incorrect")
	}
	if _, exists := postInfo.Responses.StatusCodeResponses[500]; !exists {
		t.Errorf("Response code 500 not added to spec.")
	}
	// indentify  element model type in body array
	expectedItemRef := spec.MustCreateRef("#/definitions/restfulspec.Sample")
	postBody := postInfo.Parameters[0]
	if postBody.Schema.Ref.String() != "" {
		t.Errorf("you shouldn't have body Ref setting when using array in body!")
	}
	// check body array dy item ref
	postBodyitems := postBody.Schema.Items.Schema.Ref
	if postBodyitems.String() != expectedItemRef.String() {
		t.Errorf("Expected: %s, Got: %s", expectedItemRef.String(), expectedItemRef.String())
	}

	if postBody.Format != "" || postBody.Type != "" || postBody.Default != nil {
		t.Errorf("Invalid parameter property is set on body property")
	}
}
<commit_msg>lint fixes<commit_after>package restfulspec

import (
	"testing"

	restful "github.com/emicklei/go-restful"
	"github.com/go-openapi/spec"
)

func TestRouteToPath(t *testing.T) {
	description := "get the a b test\nthis is the test description"
	notes := "notes\nblah blah"

	ws := new(restful.WebService)
	ws.Path("/tests/{v}")
	ws.Param(ws.PathParameter("v", "value of v").DefaultValue("default-v"))
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)
	ws.Route(ws.GET("/a/{b}").To(dummy).
		Doc(description).
		Notes(notes).
		Param(ws.PathParameter("b", "value of b").DefaultValue("default-b")).
		Param(ws.QueryParameter("q", "value of q").DefaultValue("default-q")).
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))
	ws.Route(ws.GET("/a/{b}/{c:[a-z]+}/{d:[1-9]+}/e").To(dummy).
		Param(ws.PathParameter("b", "value of b").DefaultValue("default-b")).
		Param(ws.PathParameter("c", "with regex").DefaultValue("abc")).
		Param(ws.PathParameter("d", "with regex").DefaultValue("abcef")).
		Param(ws.QueryParameter("q", "value of q").DefaultValue("default-q")).
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	if p.Paths["/tests/{v}/a/{b}"].Get.Parameters[0].Type != "string" {
		t.Error("Parameter type is not set.")
	}
	if _, exists := p.Paths["/tests/{v}/a/{b}/{c}/{d}/e"]; !exists {
		t.Error("Expected path to exist after it was sanitized.")
	}

	if p.Paths["/tests/{v}/a/{b}"].Get.Description != notes {
		t.Errorf("GET description incorrect")
	}
	if p.Paths["/tests/{v}/a/{b}"].Get.Summary != "get the a b test\nthis is the test description" {
		t.Errorf("GET summary incorrect")
	}
	response := p.Paths["/tests/{v}/a/{b}"].Get.Responses.StatusCodeResponses[200]
	if response.Schema.Type[0] != "array" {
		t.Errorf("response type incorrect")
	}
	if response.Schema.Items.Schema.Ref.String() != "#/definitions/restfulspec.Sample" {
		t.Errorf("response element type incorrect")
	}

	// Test for patterns
	path := p.Paths["/tests/{v}/a/{b}/{c}/{d}/e"]
	checkPattern(t, path, "c", "[a-z]+")
	checkPattern(t, path, "d", "[1-9]+")
	checkPattern(t, path, "v", "")
}

func getParameter(path spec.PathItem, name string) (*spec.Parameter, bool) {
	for _, param := range path.Get.Parameters {
		if param.Name == name {
			return &param, true
		}
	}
	return nil, false
}

func checkPattern(t *testing.T, path spec.PathItem, paramName string, pattern string) {
	param, exists := getParameter(path, paramName)
	if !exists {
		t.Errorf("Expected Parameter %s to exist", paramName)
	}
	if param.Pattern != pattern {
		t.Errorf("Expected pattern %s to equal %s", param.Pattern, pattern)
	}
}

func TestMultipleMethodsRouteToPath(t *testing.T) {
	ws := new(restful.WebService)
	ws.Path("/tests/a")
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)
	ws.Route(ws.GET("/a/b").To(dummy).
		Doc("get a b test").
		Returns(200, "list of a b tests", []Sample{}).
		Writes([]Sample{}))
	ws.Route(ws.POST("/a/b").To(dummy).
		Doc("post a b test").
		Returns(200, "list of a b tests", []Sample{}).
		Returns(500, "internal server error", []Sample{}).
		Reads(Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	if p.Paths["/tests/a/a/b"].Get.Summary != "get a b test" {
		t.Errorf("GET summary incorrect")
	}
	if p.Paths["/tests/a/a/b"].Post.Summary != "post a b test" {
		t.Errorf("POST summary incorrect")
	}
	if _, exists := p.Paths["/tests/a/a/b"].Post.Responses.StatusCodeResponses[500]; !exists {
		t.Errorf("Response code 500 not added to spec.")
	}

	expectedRef := spec.MustCreateRef("#/definitions/restfulspec.Sample")
	postBodyparam := p.Paths["/tests/a/a/b"].Post.Parameters[0]
	postBodyRef := postBodyparam.Schema.Ref
	if postBodyRef.String() != expectedRef.String() {
		t.Errorf("Expected: %s, Got: %s", expectedRef.String(), postBodyRef.String())
	}

	if postBodyparam.Format != "" || postBodyparam.Type != "" || postBodyparam.Default != nil {
		t.Errorf("Invalid parameter property is set on body property")
	}
}

func TestReadArrayObjectInBody(t *testing.T) {
	ws := new(restful.WebService)
	ws.Path("/tests/a")
	ws.Consumes(restful.MIME_JSON)
	ws.Produces(restful.MIME_XML)

	ws.Route(ws.POST("/a/b").To(dummy).
		Doc("post a b test with array in body").
		Returns(200, "list of a b tests", []Sample{}).
		Returns(500, "internal server error", []Sample{}).
		Reads([]Sample{}).
		Writes([]Sample{}))

	p := buildPaths(ws, Config{})
	t.Log(asJSON(p))

	postInfo := p.Paths["/tests/a/a/b"].Post

	if postInfo.Summary != "post a b test with array in body" {
		t.Errorf("POST description incorrect")
	}
	if _, exists := postInfo.Responses.StatusCodeResponses[500]; !exists {
		t.Errorf("Response code 500 not added to spec.")
	}
	// indentify  element model type in body array
	expectedItemRef := spec.MustCreateRef("#/definitions/restfulspec.Sample")
	postBody := postInfo.Parameters[0]
	if postBody.Schema.Ref.String() != "" {
		t.Errorf("you shouldn't have body Ref setting when using array in body!")
	}
	// check body array dy item ref
	postBodyitems := postBody.Schema.Items.Schema.Ref
	if postBodyitems.String() != expectedItemRef.String() {
		t.Errorf("Expected: %s, Got: %s", expectedItemRef.String(), expectedItemRef.String())
	}

	if postBody.Format != "" || postBody.Type != "" || postBody.Default != nil {
		t.Errorf("Invalid parameter property is set on body property")
	}
}
<|endoftext|>


<commit_before>package builder

import (
	"fmt"

	"github.com/codegangsta/cli"
	"github.com/tsaikd/KDGoLib/cliutil/cmdutil"
	"github.com/tsaikd/KDGoLib/version"
)

func init() {
	version.VERSION = "0.0.2"

	cmdutil.AddCommand(cli.Command{
		Name:   "version",
		Usage:  "Show version detail",
		Action: actionWrapper(versionAction),
	})
}

func versionAction(c *cli.Context) (err error) {
	verjson, err := version.Json()
	if err != nil {
		return
	}
	fmt.Println(verjson)
	return
}
<commit_msg>0.0.3<commit_after>package builder

import (
	"fmt"

	"github.com/codegangsta/cli"
	"github.com/tsaikd/KDGoLib/cliutil/cmdutil"
	"github.com/tsaikd/KDGoLib/version"
)

func init() {
	version.VERSION = "0.0.3"

	cmdutil.AddCommand(cli.Command{
		Name:   "version",
		Usage:  "Show version detail",
		Action: actionWrapper(versionAction),
	})
}

func versionAction(c *cli.Context) (err error) {
	verjson, err := version.Json()
	if err != nil {
		return
	}
	fmt.Println(verjson)
	return
}
<|endoftext|>


<commit_before>package base

import (
	"github.com/tcnksm/go-gitconfig"
	"gopkg.in/nishanths/go-hgconfig.v1"
	"os"
)

const (
	NameEnvVariable = "LICENSE_FULL_NAME"
	defaultName     = ""
)

// getName attempts to implicitly guess the name to use
// on the license. The function looks for a name in the following order:
//
//   * env variable corresponding to `NameEnvVariable`, if it exists
//   * user.name from local git config
//   * user.name from global git config
//   * ui.username from hg config
//   * default (empty string)
//
func getName() string {
	if name, exists := os.LookupEnv(NameEnvVariable); exists {
		return name
	} else if name, err := gitconfig.Username(); err == nil {
		return name
	} else if name, err := gitconfig.Global("user.name"); err == nil {
		return name
	} else if name, err := hgconfig.Username(); err == nil {
		return name
	} else {
		return defaultName
	}
}
<commit_msg>Fix #1: Undefined os.LookupEnv<commit_after>package base

import (
	"github.com/tcnksm/go-gitconfig"
	"gopkg.in/nishanths/go-hgconfig.v1"
	"os"
)

const (
	NameEnvVariable = "LICENSE_FULL_NAME"
	defaultName     = ""
)

// getName attempts to implicitly guess the name to use
// on the license. The function looks for a name in the following order:
//
//   * env variable corresponding to `NameEnvVariable`, if it exists
//   * user.name from local git config
//   * user.name from global git config
//   * ui.username from hg config
//   * default (empty string)
//
func getName() string {
	if name := os.Getenv(NameEnvVariable); name != "" {
		return name
	} else if name, err := gitconfig.Username(); err == nil {
		return name
	} else if name, err := gitconfig.Global("user.name"); err == nil {
		return name
	} else if name, err := hgconfig.Username(); err == nil {
		return name
	} else {
		return defaultName
	}
}
<|endoftext|>


<commit_before>// query_benchmarker speed tests servers using requests from stdin.
//
// It reads encoded Query objects from stdin, and makes concurrent requests
// to the provided HTTP endpoint. This program has no knowledge of the
// internals of the endpoint.
//
// TODO(rw): On my machine, this only decodes 700k/sec messages from stdin.
package main

import (
	"bufio"
	"encoding/gob"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"sort"
	"sync"
)

// Program option vars:
var (
	daemonUrl     string
	workers       int
	debug         int
	limit         int64
	printInterval int64
	memProfile    string
)

// Global vars:
var (
	queryPool    sync.Pool
	queryChan    chan *Query
	statPool     sync.Pool
	statChan     chan *Stat
	workersGroup sync.WaitGroup
	statGroup    sync.WaitGroup
)

// Parse args:
func init() {
	flag.StringVar(&daemonUrl, "url", "http://localhost:8086", "Daemon URL.")
	flag.IntVar(&workers, "workers", 1, "Number of concurrent requests to make.")
	flag.IntVar(&debug, "debug", 0, "Whether to print debug messages.")
	flag.Int64Var(&limit, "limit", -1, "Limit the number of queries to send.")
	flag.Int64Var(&printInterval, "print-interval", 100, "Print timing stats to stderr after this many queries (0 to disable)")
	flag.StringVar(&memProfile, "memprofile", "", "Write a memory profile to this file.")

	flag.Parse()
}

func main() {
	// Make pools to minimize heap usage:
	queryPool = sync.Pool{
		New: func() interface{} {
			return &Query{
				HumanLabel:       make([]byte, 0, 1024),
				HumanDescription: make([]byte, 0, 1024),
				Method:           make([]byte, 0, 1024),
				Path:             make([]byte, 0, 1024),
				Body:             make([]byte, 0, 1024),
			}
		},
	}

	statPool = sync.Pool{
		New: func() interface{} {
			return &Stat{
				Label: make([]byte, 0, 1024),
				Value: 0.0,
			}
		},
	}

	// Make data and control channels:
	queryChan = make(chan *Query, workers)
	statChan = make(chan *Stat, workers)

	// Launch the stats processor:
	statGroup.Add(1)
	go processStats()

	// Launch the query processors:
	for i := 0; i < workers; i++ {
		workersGroup.Add(1)
		w := NewHTTPClient(daemonUrl, debug)
		go processQueries(w)
	}

	// Read in jobs, closing the job channel when done:
	input := bufio.NewReaderSize(os.Stdin, 1<<20)
	scan(input)
	close(queryChan)

	// Block for workers to finish sending requests, closing the stats
	// channel when done:
	workersGroup.Wait()
	close(statChan)

	// Wait on the stat collector to finish (and print its results):
	statGroup.Wait()

	// (Optional) create a memory profile:
	if memProfile != "" {
		f, err := os.Create(memProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
	}
}

// scan reads encoded Queries and places them onto the workqueue.
func scan(r io.Reader) {
	dec := gob.NewDecoder(r)

	n := int64(0)
	for {
		if limit >= 0 && n >= limit {
			break
		}

		q := queryPool.Get().(*Query)
		err := dec.Decode(q)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		queryChan <- q

		n++

	}
}

// processQueries reads byte buffers from queryChan and writes them to the
// target server, while tracking latency.
func processQueries(w *HTTPClient) {
	for q := range queryChan {
		lag, err := w.Do(q)

		stat := statPool.Get().(*Stat)
		stat.Init(q.HumanLabel, lag)
		statChan <- stat

		queryPool.Put(q)
		if err != nil {
			log.Fatalf("Error during request: %s\n", err.Error())
		}
	}
	workersGroup.Done()
}

// processStats collects latency results, aggregating them into summary
// statistics. Optionally, they are printed to stderr at regular intervals.
func processStats() {
	const allQueriesLabel = "all queries            "
	statMapping := map[string]*StatGroup{
		allQueriesLabel: &StatGroup{},
	}

	i := int64(0)
	for stat := range statChan {
		if _, ok := statMapping[string(stat.Label)]; !ok {
			statMapping[string(stat.Label)] = &StatGroup{}
		}

		statMapping[allQueriesLabel].Push(stat.Value)
		statMapping[string(stat.Label)].Push(stat.Value)

		statPool.Put(stat)

		i++

		// print stats to stderr (if printInterval is greater than zero):
		if printInterval > 0 && i > 0 && i%printInterval == 0 && (i < limit || limit < 0) {
			_, err := fmt.Fprintf(os.Stderr, "after %d queries with %d workers:\n", i, workers)
			if err != nil {
				log.Fatal(err)
			}
			fprintStats(os.Stderr, statMapping)
			_, err = fmt.Fprintf(os.Stderr, "\n")
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	// the final stats output goes to stdout:
	_, err := fmt.Printf("run complete after %d queries with %d workers:\n", i, workers)
	if err != nil {
		log.Fatal(err)
	}
	fprintStats(os.Stdout, statMapping)
	statGroup.Done()
}

// fprintStats pretty-prints stats to the given writer.
func fprintStats(w io.Writer, statGroups map[string]*StatGroup) {
	keys := make([]string, 0, len(statGroups))
	for k := range statGroups {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := statGroups[k]
		minRate := 1e3 / v.Min
		meanRate := 1e3 / v.Mean
		maxRate := 1e3 / v.Max
		_, err := fmt.Fprintf(w, "%s: min: %8.2fms (%7.2f/sec), mean: %8.2fms (%7.2f/sec), max: %7.2fms (%6.2f/sec), count: %8d, sum: %5.1fsec \n", k, v.Min, minRate, v.Mean, meanRate, v.Max, maxRate, v.Count, v.Sum/1e3)
		if err != nil {
			log.Fatal(err)
		}
	}

}
<commit_msg>Query benchmarker includes wall clock time.<commit_after>// query_benchmarker speed tests servers using requests from stdin.
//
// It reads encoded Query objects from stdin, and makes concurrent requests
// to the provided HTTP endpoint. This program has no knowledge of the
// internals of the endpoint.
//
// TODO(rw): On my machine, this only decodes 700k/sec messages from stdin.
package main

import (
	"bufio"
	"encoding/gob"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"sort"
	"time"
	"sync"
)

// Program option vars:
var (
	daemonUrl     string
	workers       int
	debug         int
	limit         int64
	printInterval int64
	memProfile    string
)

// Global vars:
var (
	queryPool    sync.Pool
	queryChan    chan *Query
	statPool     sync.Pool
	statChan     chan *Stat
	workersGroup sync.WaitGroup
	statGroup    sync.WaitGroup
)

// Parse args:
func init() {
	flag.StringVar(&daemonUrl, "url", "http://localhost:8086", "Daemon URL.")
	flag.IntVar(&workers, "workers", 1, "Number of concurrent requests to make.")
	flag.IntVar(&debug, "debug", 0, "Whether to print debug messages.")
	flag.Int64Var(&limit, "limit", -1, "Limit the number of queries to send.")
	flag.Int64Var(&printInterval, "print-interval", 100, "Print timing stats to stderr after this many queries (0 to disable)")
	flag.StringVar(&memProfile, "memprofile", "", "Write a memory profile to this file.")

	flag.Parse()
}

func main() {
	// Make pools to minimize heap usage:
	queryPool = sync.Pool{
		New: func() interface{} {
			return &Query{
				HumanLabel:       make([]byte, 0, 1024),
				HumanDescription: make([]byte, 0, 1024),
				Method:           make([]byte, 0, 1024),
				Path:             make([]byte, 0, 1024),
				Body:             make([]byte, 0, 1024),
			}
		},
	}

	statPool = sync.Pool{
		New: func() interface{} {
			return &Stat{
				Label: make([]byte, 0, 1024),
				Value: 0.0,
			}
		},
	}

	// Make data and control channels:
	queryChan = make(chan *Query, workers)
	statChan = make(chan *Stat, workers)

	// Launch the stats processor:
	statGroup.Add(1)
	go processStats()

	// Launch the query processors:
	for i := 0; i < workers; i++ {
		workersGroup.Add(1)
		w := NewHTTPClient(daemonUrl, debug)
		go processQueries(w)
	}

	// Read in jobs, closing the job channel when done:
	input := bufio.NewReaderSize(os.Stdin, 1<<20)
	wallStart := time.Now()
	scan(input)
	close(queryChan)

	// Block for workers to finish sending requests, closing the stats
	// channel when done:
	workersGroup.Wait()
	close(statChan)

	// Wait on the stat collector to finish (and print its results):
	statGroup.Wait()

	wallEnd := time.Now()
	wallTook := wallEnd.Sub(wallStart)
	_, err := fmt.Printf("wall clock time: %fsec\n", float64(wallTook.Nanoseconds()) / 1e9)
	if err != nil {
		log.Fatal(err)
	}

	// (Optional) create a memory profile:
	if memProfile != "" {
		f, err := os.Create(memProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
	}
}

// scan reads encoded Queries and places them onto the workqueue.
func scan(r io.Reader) {
	dec := gob.NewDecoder(r)

	n := int64(0)
	for {
		if limit >= 0 && n >= limit {
			break
		}

		q := queryPool.Get().(*Query)
		err := dec.Decode(q)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		queryChan <- q

		n++

	}
}

// processQueries reads byte buffers from queryChan and writes them to the
// target server, while tracking latency.
func processQueries(w *HTTPClient) {
	for q := range queryChan {
		lag, err := w.Do(q)

		stat := statPool.Get().(*Stat)
		stat.Init(q.HumanLabel, lag)
		statChan <- stat

		queryPool.Put(q)
		if err != nil {
			log.Fatalf("Error during request: %s\n", err.Error())
		}
	}
	workersGroup.Done()
}

// processStats collects latency results, aggregating them into summary
// statistics. Optionally, they are printed to stderr at regular intervals.
func processStats() {
	const allQueriesLabel = "all queries           "
	statMapping := map[string]*StatGroup{
		allQueriesLabel: &StatGroup{},
	}

	i := int64(0)
	for stat := range statChan {
		if _, ok := statMapping[string(stat.Label)]; !ok {
			statMapping[string(stat.Label)] = &StatGroup{}
		}

		statMapping[allQueriesLabel].Push(stat.Value)
		statMapping[string(stat.Label)].Push(stat.Value)

		statPool.Put(stat)

		i++

		// print stats to stderr (if printInterval is greater than zero):
		if printInterval > 0 && i > 0 && i%printInterval == 0 && (i < limit || limit < 0) {
			_, err := fmt.Fprintf(os.Stderr, "after %d queries with %d workers:\n", i, workers)
			if err != nil {
				log.Fatal(err)
			}
			fprintStats(os.Stderr, statMapping)
			_, err = fmt.Fprintf(os.Stderr, "\n")
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	// the final stats output goes to stdout:
	_, err := fmt.Printf("run complete after %d queries with %d workers:\n", i, workers)
	if err != nil {
		log.Fatal(err)
	}
	fprintStats(os.Stdout, statMapping)
	statGroup.Done()
}

// fprintStats pretty-prints stats to the given writer.
func fprintStats(w io.Writer, statGroups map[string]*StatGroup) {
	keys := make([]string, 0, len(statGroups))
	for k := range statGroups {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := statGroups[k]
		minRate := 1e3 / v.Min
		meanRate := 1e3 / v.Mean
		maxRate := 1e3 / v.Max
		_, err := fmt.Fprintf(w, "%s: min: %8.2fms (%7.2f/sec), mean: %8.2fms (%7.2f/sec), max: %7.2fms (%6.2f/sec), count: %8d, sum: %5.1fsec \n", k, v.Min, minRate, v.Mean, meanRate, v.Max, maxRate, v.Count, v.Sum/1e3)
		if err != nil {
			log.Fatal(err)
		}
	}

}
<|endoftext|>


<commit_before>// +build !bare

package e2e

import (
	"fmt"
	"testing"

	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
	log "github.com/sirupsen/logrus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// TestMetrics tests the metrics endpoint of the OLM pod.
func TestMetricsEndpoint(t *testing.T) {
	c := newKubeClient(t)

	listOptions := metav1.ListOptions{LabelSelector: "app=olm-operator"}
	podList, err := c.KubernetesInterface().CoreV1().Pods(operatorNamespace).List(listOptions)
	if err != nil {
		log.Infof("Error %v\n", err)
		t.Fatalf("Listing pods failed: %v\n", err)
	}
	if len(podList.Items) > 1 {
		t.Fatalf("Expected only 1 olm-operator pod, got %v", len(podList.Items))
	}

	podName := podList.Items[0].GetName()

	rawOutput, err := getMetricsFromPod(t, c, podName, operatorNamespace, 8080)
	if err != nil {
		t.Fatalf("Metrics test failed: %v\n", err)
	}

	log.Debugf("Metrics:\n%v", rawOutput)
}

func getMetricsFromPod(t *testing.T, client operatorclient.ClientInterface, podName string, namespace string, port int) (string, error) {
	rawOutput, err := client.KubernetesInterface().CoreV1().RESTClient().Get().
		Namespace(namespace).
		Resource("pods").
		SubResource("proxy").
		Name(fmt.Sprintf("%v:%v", podName, port)).
		Suffix("metrics").
		Do().Raw()
	if err != nil {
		return "", err
	}
	return string(rawOutput), nil
}
<commit_msg>fix(e2e): metrics are now served 8081<commit_after>// +build !bare

package e2e

import (
	"testing"

	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
	log "github.com/sirupsen/logrus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/net"
)

// TestMetrics tests the metrics endpoint of the OLM pod.
func TestMetricsEndpoint(t *testing.T) {
	c := newKubeClient(t)

	listOptions := metav1.ListOptions{LabelSelector: "app=olm-operator"}
	podList, err := c.KubernetesInterface().CoreV1().Pods(operatorNamespace).List(listOptions)
	if err != nil {
		log.Infof("Error %v\n", err)
		t.Fatalf("Listing pods failed: %v\n", err)
	}
	if len(podList.Items) > 1 {
		t.Fatalf("Expected only 1 olm-operator pod, got %v", len(podList.Items))
	}

	podName := podList.Items[0].GetName()
	log.Infof("Looking at pod %v in namespace %v", podName, operatorNamespace)

	rawOutput, err := getMetricsFromPod(t, c, podName, operatorNamespace, "8081")
	if err != nil {
		t.Fatalf("Metrics test failed: %v\n", err)
	}

	log.Debugf("Metrics:\n%v", rawOutput)
}

func getMetricsFromPod(t *testing.T, client operatorclient.ClientInterface, podName string, namespace string, port string) (string, error) {
	olmPod, err := client.KubernetesInterface().CoreV1().Pods(namespace).Get(podName, metav1.GetOptions{})
	if err != nil {
		return "", err
	}
	if len(olmPod.Spec.Containers) != 1 {
		t.Fatalf("Expected only 1 container in olm-operator pod, got %v", len(olmPod.Spec.Containers))
	}

	var foundCert bool
	var foundKey bool
	// assuming -tls-cert and -tls-key aren't used anywhere else as a parameter value
	for _, param := range olmPod.Spec.Containers[0].Args {
		if param == "-tls-cert" {
			foundCert = true
		} else if param == "-tls-key" {
			foundKey = true
		}
	}

	var scheme string
	if foundCert && foundKey {
		scheme = "https"
	} else {
		scheme = "http"
	}
	log.Infof("Retrieving metrics using scheme %v\n", scheme)

	rawOutput, err := client.KubernetesInterface().CoreV1().RESTClient().Get().
		Namespace(namespace).
		Resource("pods").
		SubResource("proxy").
		Name(net.JoinSchemeNamePort(scheme, podName, port)).
		Suffix("metrics").
		Do().Raw()
	if err != nil {
		return "", err
	}
	return string(rawOutput), nil
}
<|endoftext|>


<commit_before>package aws

import (
	"os"

	"github.com/hashicorp/terraform/helper/schema"
)

// Provider returns a schema.Provider for AWS.
//
// NOTE: schema.Provider became available long after the AWS provider
// was started, so resources may not be converted to this new structure
// yet. This is a WIP. To assist with the migration, make sure any resources
// you migrate are acceptance tested, then perform the migration.
func Provider() *schema.Provider {
	// TODO: Move the validation to this, requires conditional schemas
	// TODO: Move the configuration to this, requires validation

	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"region": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_REGION"),
				Description: descriptions["region"],
			},

			"access_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_ACCESS_KEY"),
				Description: descriptions["access_key"],
			},

			"secret_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_SECRET_KEY"),
				Description: descriptions["secret_key"],
			},
		},

		ResourcesMap: map[string]*schema.Resource{
			"aws_eip":             resourceAwsEip(),
			"aws_instance":        resourceAwsInstance(),
			"aws_security_group":  resourceAwsSecurityGroup(),
			"aws_db_subnet_group": resourceAwsDbSubnetGroup(),
		},
	}
}

func envDefaultFunc(k string) schema.SchemaDefaultFunc {
	return func() (interface{}, error) {
		if v := os.Getenv(k); v != "" {
			return v, nil
		}

		return nil, nil
	}
}

var descriptions map[string]string

func init() {
	descriptions = map[string]string{
		"region": "The region where AWS operations will take place. Examples\n" +
			"are us-east-1, us-west-2, etc.",

		"access_key": "The access key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",

		"secret_key": "The secret key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",
	}
}
<commit_msg>helper/scheam: support UI defaults<commit_after>package aws

import (
	"os"

	"github.com/hashicorp/terraform/helper/schema"
)

// Provider returns a schema.Provider for AWS.
//
// NOTE: schema.Provider became available long after the AWS provider
// was started, so resources may not be converted to this new structure
// yet. This is a WIP. To assist with the migration, make sure any resources
// you migrate are acceptance tested, then perform the migration.
func Provider() *schema.Provider {
	// TODO: Move the validation to this, requires conditional schemas
	// TODO: Move the configuration to this, requires validation

	return &schema.Provider{
		Schema: map[string]*schema.Schema{
			"region": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				DefaultFunc:  envDefaultFunc("AWS_REGION"),
				Description:  descriptions["region"],
				InputDefault: "us-east-1",
			},

			"access_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_ACCESS_KEY"),
				Description: descriptions["access_key"],
			},

			"secret_key": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				DefaultFunc: envDefaultFunc("AWS_SECRET_KEY"),
				Description: descriptions["secret_key"],
			},
		},

		ResourcesMap: map[string]*schema.Resource{
			"aws_eip":             resourceAwsEip(),
			"aws_instance":        resourceAwsInstance(),
			"aws_security_group":  resourceAwsSecurityGroup(),
			"aws_db_subnet_group": resourceAwsDbSubnetGroup(),
		},
	}
}

func envDefaultFunc(k string) schema.SchemaDefaultFunc {
	return func() (interface{}, error) {
		if v := os.Getenv(k); v != "" {
			return v, nil
		}

		return nil, nil
	}
}

var descriptions map[string]string

func init() {
	descriptions = map[string]string{
		"region": "The region where AWS operations will take place. Examples\n" +
			"are us-east-1, us-west-2, etc.",

		"access_key": "The access key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",

		"secret_key": "The secret key for API operations. You can retrieve this\n" +
			"from the 'Security & Credentials' section of the AWS console.",
	}
}
<|endoftext|>