<commit_before>package box

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type TaskCollection struct {
	TotalCount int     `json:"total_count"`
	Entries    []*Task `json:"entries"`
}

// Documentation: https://developers.box.com/docs/#tasks-task-object
// TODO(ttacon): add missing fields
type Task struct {
	Type                     string                    `json:"type"`
	Id                       string                    `json:"id"`
	Item                     *Item                     `json:"item"`
	DueAt                    *string                   `json:"due_at"`     // TODO(ttacon): time.Time
	CreatedAt                *string                   `json:"created_at"` // TODO(ttacon): time.Time
	CreatedBy                *Item                     `json:"created_by"` // TODO(ttacon): change to user
	Action                   *string                   `json:"action"`     //TODO(ttacon): validation as this must be 'review'?
	Message                  *string                   `json:"message"`
	IsCompleted              *bool                     `json:"is_completed"`
	TaskAssignmentCollection *TaskAssignmentCollection `json:"task_assignment_collection"`
}

type TaskAssignmentCollection struct {
	TotalCount int               `json:"total_count"`
	Entries    []*TaskAssignment `json:"entries"`
}

// TODO(ttacon): find out where the deuce this is defined in their documentation?!?!?!
type TaskAssignment struct {
	Type            *string `json:"type"`
	Id              string  `json:"id"`
	Item            *Item   `json:"item"`
	AssignedTo      *Item   `json:"assigned_to"` // TODO(ttacon): change to mini-user
	Message         *string `json:"message"`
	ResolutionState *string `json:"resolution_state"`
	AssignedBy      *Item   `json:"assigned_by"`  // TODO(ttacon): change to mini-user
	CompletedAt     *string `json:"completed_at"` // TODO(ttacon): time.Time
	AssignedAt      *string `json:"assigned_at"`  // TODO(ttacon): time.Time
	RemindedAt      *string `json:"reminded_at"`  // TODO(ttacon): time.Time
}

// Documentation: https://developers.box.com/docs/#tasks-create-a-task
func (c *Client) CreateTask(itemId, itemType, action, message, due_at string) (*http.Response, *Task, error) {
	var dataMap = map[string]interface{}{
		"item": map[string]string{
			"id":   itemId,
			"type": itemType,
		},
	}
	if len(action) > 0 {
		// TODO(ttacon): make sure this is "review"
		dataMap["action"] = action
	}
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(due_at) > 0 {
		dataMap["due_at"] = due_at
	}

	req, err := c.NewRequest(
		"POST",
		fmt.Sprintf("/tasks"),
		dataMap,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-get-a-task
func (c *Client) GetTask(taskId string) (*http.Response, *Task, error) {
	req, err := c.NewRequest(
		"GET",
		fmt.Sprintf("/tasks/%s", taskId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-update-a-task
func (c *Client) UpdateTask(taskId, action, message, due_at string) (*http.Response, *Task, error) {
	var dataMap = make(map[string]interface{})
	if len(action) > 0 {
		dataMap["action"] = action
	}
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(due_at) > 0 {
		dataMap["due_at"] = due_at
	}

	req, err := c.NewRequest(
		"PUT",
		fmt.Sprintf("/tasks/%s", taskId),
		dataMap,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-delete-a-task
func (c *Client) DeleteTask(taskId string) (*http.Response, error) {
	req, err := c.NewRequest(
		"DELETE",
		fmt.Sprintf("%s/tasks/%s", BASE_URL, taskId),
		nil,
	)
	if err != nil {
		return nil, err
	}

	return c.Do(req, nil)
}

// Documentation: https://developers.box.com/docs/#tasks-get-the-assignments-for-a-task
func (c *Client) GetAssignmentsForTask(taskId string) (*http.Response, *TaskAssignmentCollection, error) {
	req, err := http.NewRequest(
		"GET",
		fmt.Sprintf("%s/tasks/%s/assignments", BASE_URL, taskId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data TaskAssignmentCollection
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#tasks-create-a-task-assignment
func (c *Client) CreateTaskAssignment(taskId, taskType, assignToId, assignToLogin string) (*http.Response, *TaskAssignment, error) {
	var dataMap = map[string]map[string]string{
		"task": map[string]string{
			"id":   taskId,
			"type": taskType,
		},
		"assign_to": make(map[string]string),
	}
	if len(assignToId) > 0 {
		dataMap["assign_to"]["id"] = assignToId
	}
	if len(assignToLogin) > 0 {
		dataMap["assign_to"]["login"] = assignToLogin
	}

	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("%s/task_assignments", BASE_URL),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data *TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#tasks-get-a-task-assignment
func (c *Client) GetTaskAssignment(taskAssignmentId string) (*http.Response, *TaskAssignment, error) {
	req, err := http.NewRequest(
		"GET",
		fmt.Sprintf("%s/task_assignments/%s", taskAssignmentId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#tasks-delete-a-task-assignment
func (c *Client) DeleteTaskAssignment(taskAssignmentId string) (*http.Response, error) {
	req, err := http.NewRequest(
		"DELETE",
		fmt.Sprintf("%s/task_assignments/%s", BASE_URL, taskAssignmentId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	return c.Trans.Client().Do(req)
}

// Documentation: https://developers.box.com/docs/#tasks-update-a-task-assignment
func (c *Client) UpdateTaskAssignment(taskAssignmentId, message, resolution_state string) (*http.Response, *TaskAssignment, error) {
	var dataMap = make(map[string]string)
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(resolution_state) > 0 {
		dataMap["resolution_state"] = resolution_state
	}

	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"PUT",
		fmt.Sprintf("%s/task_assignments/%s", BASE_URL, taskAssignmentId),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}
<commit_msg>refactor get assignments for task<commit_after>package box

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type TaskCollection struct {
	TotalCount int     `json:"total_count"`
	Entries    []*Task `json:"entries"`
}

// Documentation: https://developers.box.com/docs/#tasks-task-object
// TODO(ttacon): add missing fields
type Task struct {
	Type                     string                    `json:"type"`
	Id                       string                    `json:"id"`
	Item                     *Item                     `json:"item"`
	DueAt                    *string                   `json:"due_at"`     // TODO(ttacon): time.Time
	CreatedAt                *string                   `json:"created_at"` // TODO(ttacon): time.Time
	CreatedBy                *Item                     `json:"created_by"` // TODO(ttacon): change to user
	Action                   *string                   `json:"action"`     //TODO(ttacon): validation as this must be 'review'?
	Message                  *string                   `json:"message"`
	IsCompleted              *bool                     `json:"is_completed"`
	TaskAssignmentCollection *TaskAssignmentCollection `json:"task_assignment_collection"`
}

type TaskAssignmentCollection struct {
	TotalCount int               `json:"total_count"`
	Entries    []*TaskAssignment `json:"entries"`
}

// TODO(ttacon): find out where the deuce this is defined in their documentation?!?!?!
type TaskAssignment struct {
	Type            *string `json:"type"`
	Id              string  `json:"id"`
	Item            *Item   `json:"item"`
	AssignedTo      *Item   `json:"assigned_to"` // TODO(ttacon): change to mini-user
	Message         *string `json:"message"`
	ResolutionState *string `json:"resolution_state"`
	AssignedBy      *Item   `json:"assigned_by"`  // TODO(ttacon): change to mini-user
	CompletedAt     *string `json:"completed_at"` // TODO(ttacon): time.Time
	AssignedAt      *string `json:"assigned_at"`  // TODO(ttacon): time.Time
	RemindedAt      *string `json:"reminded_at"`  // TODO(ttacon): time.Time
}

// Documentation: https://developers.box.com/docs/#tasks-create-a-task
func (c *Client) CreateTask(itemId, itemType, action, message, due_at string) (*http.Response, *Task, error) {
	var dataMap = map[string]interface{}{
		"item": map[string]string{
			"id":   itemId,
			"type": itemType,
		},
	}
	if len(action) > 0 {
		// TODO(ttacon): make sure this is "review"
		dataMap["action"] = action
	}
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(due_at) > 0 {
		dataMap["due_at"] = due_at
	}

	req, err := c.NewRequest(
		"POST",
		fmt.Sprintf("/tasks"),
		dataMap,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-get-a-task
func (c *Client) GetTask(taskId string) (*http.Response, *Task, error) {
	req, err := c.NewRequest(
		"GET",
		fmt.Sprintf("/tasks/%s", taskId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-update-a-task
func (c *Client) UpdateTask(taskId, action, message, due_at string) (*http.Response, *Task, error) {
	var dataMap = make(map[string]interface{})
	if len(action) > 0 {
		dataMap["action"] = action
	}
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(due_at) > 0 {
		dataMap["due_at"] = due_at
	}

	req, err := c.NewRequest(
		"PUT",
		fmt.Sprintf("/tasks/%s", taskId),
		dataMap,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *Task
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-delete-a-task
func (c *Client) DeleteTask(taskId string) (*http.Response, error) {
	req, err := c.NewRequest(
		"DELETE",
		fmt.Sprintf("/tasks/%s", taskId),
		nil,
	)
	if err != nil {
		return nil, err
	}

	return c.Do(req, nil)
}

// Documentation: https://developers.box.com/docs/#tasks-get-the-assignments-for-a-task
func (c *Client) GetAssignmentsForTask(taskId string) (*http.Response, *TaskAssignmentCollection, error) {
	req, err := c.NewRequest(
		"GET",
		fmt.Sprintf("/tasks/%s/assignments", taskId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	var data *TaskAssignmentCollection
	resp, err := c.Do(req, data)
	return resp, data, err
}

// Documentation: https://developers.box.com/docs/#tasks-create-a-task-assignment
func (c *Client) CreateTaskAssignment(taskId, taskType, assignToId, assignToLogin string) (*http.Response, *TaskAssignment, error) {
	var dataMap = map[string]map[string]string{
		"task": map[string]string{
			"id":   taskId,
			"type": taskType,
		},
		"assign_to": make(map[string]string),
	}
	if len(assignToId) > 0 {
		dataMap["assign_to"]["id"] = assignToId
	}
	if len(assignToLogin) > 0 {
		dataMap["assign_to"]["login"] = assignToLogin
	}

	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("%s/task_assignments", BASE_URL),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data *TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#tasks-get-a-task-assignment
func (c *Client) GetTaskAssignment(taskAssignmentId string) (*http.Response, *TaskAssignment, error) {
	req, err := http.NewRequest(
		"GET",
		fmt.Sprintf("%s/task_assignments/%s", taskAssignmentId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#tasks-delete-a-task-assignment
func (c *Client) DeleteTaskAssignment(taskAssignmentId string) (*http.Response, error) {
	req, err := http.NewRequest(
		"DELETE",
		fmt.Sprintf("%s/task_assignments/%s", BASE_URL, taskAssignmentId),
		nil,
	)
	if err != nil {
		return nil, nil, err
	}

	return c.Trans.Client().Do(req)
}

// Documentation: https://developers.box.com/docs/#tasks-update-a-task-assignment
func (c *Client) UpdateTaskAssignment(taskAssignmentId, message, resolution_state string) (*http.Response, *TaskAssignment, error) {
	var dataMap = make(map[string]string)
	if len(message) > 0 {
		dataMap["message"] = message
	}
	if len(resolution_state) > 0 {
		dataMap["resolution_state"] = resolution_state
	}

	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"PUT",
		fmt.Sprintf("%s/task_assignments/%s", BASE_URL, taskAssignmentId),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data TaskAssignment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}
<|endoftext|>


<commit_before>package azurerm

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMAutomationAccount_basic(t *testing.T) {
	ri := acctest.RandInt()
	resourceName := "azurerm_automation_account.test"
	config := testAccAzureRMAutomationAccount_basic(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMAutomationAccountDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMAutomationAccountExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"),
				),
			},
		},
	})
}

func TestAccAzureRMAutomationAccount_complete(t *testing.T) {
	ri := acctest.RandInt()
	resourceName := "azurerm_automation_account.test"
	config := testAccAzureRMAutomationAccount_complete(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMAutomationAccountDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMAutomationAccountExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"),
					resource.TestCheckResourceAttr(resourceName, "tags.0.hello", "world"),
				),
			},
		},
	})
}

func testCheckAzureRMAutomationAccountDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*ArmClient).automationAccountClient

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

		name := rs.Primary.Attributes["name"]
		resourceGroup := rs.Primary.Attributes["resource_group_name"]

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return nil
			}

			return err
		}

		return fmt.Errorf("Automation Account still exists:\n%#v", resp)
	}

	return nil
}

func testCheckAzureRMAutomationAccountExists(name string) resource.TestCheckFunc {

	return func(s *terraform.State) error {
		// Ensure we have enough information in state to look up in API
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for Automation Account: '%s'", name)
		}

		conn := testAccProvider.Meta().(*ArmClient).automationAccountClient

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return fmt.Errorf("Automation Account '%s' (resource group: '%s') was not found: %+v", name, resourceGroup, err)
			}

			return fmt.Errorf("Bad: Get on automationClient: %s", err)
		}

		return nil
	}
}

func testAccAzureRMAutomationAccount_basic(rInt int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
 name = "acctestRG-%d"
 location = "%s"
}

resource "azurerm_automation_account" "test" {
  name                = "acctest-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  sku {
	name = "Basic"
  }
}
`, rInt, location, rInt)
}

func testAccAzureRMAutomationAccount_complete(rInt int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
 name = "acctestRG-%d"
 location = "%s"
}

resource "azurerm_automation_account" "test" {
  name                = "acctest-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  sku {
	name = "Basic"
  }

  tags {
  	"hello" = "world"
  }
}
`, rInt, location, rInt)
}
<commit_msg>Fixing a typo<commit_after>package azurerm

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMAutomationAccount_basic(t *testing.T) {
	ri := acctest.RandInt()
	resourceName := "azurerm_automation_account.test"
	config := testAccAzureRMAutomationAccount_basic(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMAutomationAccountDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMAutomationAccountExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"),
				),
			},
		},
	})
}

func TestAccAzureRMAutomationAccount_complete(t *testing.T) {
	ri := acctest.RandInt()
	resourceName := "azurerm_automation_account.test"
	config := testAccAzureRMAutomationAccount_complete(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMAutomationAccountDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMAutomationAccountExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"),
					resource.TestCheckResourceAttr(resourceName, "tags.hello", "world"),
				),
			},
		},
	})
}

func testCheckAzureRMAutomationAccountDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*ArmClient).automationAccountClient

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

		name := rs.Primary.Attributes["name"]
		resourceGroup := rs.Primary.Attributes["resource_group_name"]

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return nil
			}

			return err
		}

		return fmt.Errorf("Automation Account still exists:\n%#v", resp)
	}

	return nil
}

func testCheckAzureRMAutomationAccountExists(name string) resource.TestCheckFunc {

	return func(s *terraform.State) error {
		// Ensure we have enough information in state to look up in API
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for Automation Account: '%s'", name)
		}

		conn := testAccProvider.Meta().(*ArmClient).automationAccountClient

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return fmt.Errorf("Automation Account '%s' (resource group: '%s') was not found: %+v", name, resourceGroup, err)
			}

			return fmt.Errorf("Bad: Get on automationClient: %s", err)
		}

		return nil
	}
}

func testAccAzureRMAutomationAccount_basic(rInt int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
 name = "acctestRG-%d"
 location = "%s"
}

resource "azurerm_automation_account" "test" {
  name                = "acctest-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  sku {
	name = "Basic"
  }
}
`, rInt, location, rInt)
}

func testAccAzureRMAutomationAccount_complete(rInt int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
 name = "acctestRG-%d"
 location = "%s"
}

resource "azurerm_automation_account" "test" {
  name                = "acctest-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  sku {
	name = "Basic"
  }

  tags {
  	"hello" = "world"
  }
}
`, rInt, location, rInt)
}
<|endoftext|>


<commit_before>package cfg

import (
	"errors"
	"flag"
	"io/ioutil"
	"math/rand"
	"net"
	"os"
	"strconv"
	"time"

	log "github.com/Sirupsen/logrus"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/github"
	"golang.org/x/oauth2/google"

	"github.com/spf13/viper"
)

// config lasso jwt cookie configuration
type config struct {
	LogLevel      string   `mapstructure:"logLevel"`
	Listen        string   `mapstructure:"listen"`
	Port          int      `mapstructure:"port"`
	Domains       []string `mapstructure:"domains"`
	WhiteList     []string `mapstructure:"whitelist"`
	AllowAllUsers bool     `mapstructure:"allowAllUsers"`
	PublicAccess  bool     `mapstructure:"publicAccess"`
	JWT           struct {
		MaxAge   int    `mapstructure:"maxAge"`
		Issuer   string `mapstructure:"issuer"`
		Secret   string `mapstructure:"secret"`
		Compress bool   `mapstructure:"compress"`
	}
	Cookie struct {
		Name     string `mapstructure:"name"`
		Domain   string `mapstructure:"domain"`
		Secure   bool   `mapstructure:"secure"`
		HTTPOnly bool   `mapstructure:"httpOnly"`
	}
	Headers struct {
		JWT         string `mapstructure:"jwt"`
		User        string `mapstructure:"user"`
		QueryString string `mapstructure:"querystring"`
		Redirect    string `mapstructure:"redirect"`
		Success     string `mapstructure:"success"`
	}
	DB struct {
		File string `mapstructure:"file"`
	}
	Session struct {
		Name string `mapstructure:"name"`
	}
	TestURL  string   `mapstructure:"test_url"`
	TestURLs []string `mapstructure:"test_urls"`
	Testing  bool     `mapstructure:"testing"`
	WebApp   bool     `mapstructure:"webapp"`
}

// oauth config items endoint for access
type oauthConfig struct {
	Provider        string   `mapstructure:"provider"`
	ClientID        string   `mapstructure:"client_id"`
	ClientSecret    string   `mapstructure:"client_secret"`
	AuthURL         string   `mapstructure:"auth_url"`
	TokenURL        string   `mapstructure:"token_url"`
	RedirectURL     string   `mapstructure:"callback_url"`
	RedirectURLs    []string `mapstructure:"callback_urls"`
	Scopes          []string `mapstructure:"scopes"`
	UserInfoURL     string   `mapstructure:"user_info_url"`
	PreferredDomain string   `mapstructre:"preferredDomain"`
}

// OAuthProviders holds the stings for
type OAuthProviders struct {
	Google    string
	GitHub    string
	IndieAuth string
	OIDC      string
}

type branding struct {
	LCName string // lower case
	UCName string // upper case
	CcName string // camel case
}

var (
	// Branding that's our name
	Branding = branding{"lasso", "LASSO", "Lasso"}

	// Cfg the main exported config variable
	Cfg config

	// GenOAuth exported OAuth config variable
	// TODO: I think GenOAuth and OAuthConfig can be combined!
	// perhaps by https://golang.org/doc/effective_go.html#embedding
	GenOAuth *oauthConfig

	// OAuthClient is the configured client which will call the provider
	// this actually carries the oauth2 client ala oauthclient.Client(oauth2.NoContext, providerToken)
	OAuthClient *oauth2.Config
	// OAuthopts authentication options
	OAuthopts oauth2.AuthCodeOption

	// Providers static strings to test against
	Providers = &OAuthProviders{
		Google:    "google",
		GitHub:    "github",
		IndieAuth: "indieauth",
		OIDC:      "oidc",
	}
)

// RequiredOptions must have these fields set for minimum viable config
var RequiredOptions = []string{"oauth.provider", "oauth.client_id"}

func init() {
	// from config file
	ParseConfig()

	// can pass loglevel on the command line
	var ll = flag.String("loglevel", Cfg.LogLevel, "enable debug log output")
	flag.Parse()
	if *ll == "debug" {
		log.SetLevel(log.DebugLevel)
		log.Debug("logLevel set to debug")
	}

	setDefaults()

	errT := BasicTest()
	if errT != nil {
		// log.Fatalf(errT.Error())
		panic(errT)
	}

	var listen = Cfg.Listen + ":" + strconv.Itoa(Cfg.Port)
	if !isTCPPortAvailable(listen) {
		log.Fatal(errors.New("check the port availability (is " + Branding.CcName + " already running?)"))
	}

	log.Debug(viper.AllSettings())
}

// ParseConfig parse the config file
func ParseConfig() {
	log.Debug("opening config")
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(os.Getenv(Branding.UCName+"_ROOT") + "config")
	err := viper.ReadInConfig() // Find and read the config file
	if err != nil {             // Handle errors reading the config file
		log.Fatalf("Fatal error config file: %s", err.Error())
		panic(err)
	}
	UnmarshalKey(Branding.LCName, &Cfg)
	// don't log the secret!
	// log.Debugf("secret: %s", string(Cfg.JWT.Secret))
}

// UnmarshalKey populate struct from contents of cfg tree at key
func UnmarshalKey(key string, rawVal interface{}) error {
	return viper.UnmarshalKey(key, rawVal)
}

// Get string value for key
func Get(key string) string {
	return viper.GetString(key)
}

// BasicTest just a quick sanity check to see if the config is sound
func BasicTest() error {
	for _, opt := range RequiredOptions {
		if !viper.IsSet(opt) {
			return errors.New("configuration option " + opt + " is not set in config")
		}
	}
	return nil
}

// setDefaults set default options for some items
func setDefaults() {

	// this should really be done by Viper up in parseConfig but..
	// nested defaults is currently *broken*
	// https://github.com/spf13/viper/issues/309
	// viper.SetDefault("listen", "0.0.0.0")
	// viper.SetDefault(Cfg.Port, 9090)
	// viper.SetDefault("Headers.SSO", "X-"+Branding.CcName+"-Token")
	// viper.SetDefault("Headers.Redirect", "X-"+Branding.CcName+"-Requested-URI")
	// viper.SetDefault("Cookie.Name", "Lasso")

	// logging
	if !viper.IsSet(Branding.LCName + ".logLevel") {
		Cfg.LogLevel = "info"
	}
	// network defaults
	if !viper.IsSet(Branding.LCName + ".listen") {
		Cfg.Listen = "0.0.0.0"
	}
	if !viper.IsSet(Branding.LCName + ".port") {
		Cfg.Port = 9090
	}
	if !viper.IsSet(Branding.LCName + ".allowAllUsers") {
		Cfg.AllowAllUsers = false
	}
	if !viper.IsSet(Branding.LCName + ".publicAccess") {
		Cfg.PublicAccess = false
	}

	// jwt defaults
	if !viper.IsSet(Branding.LCName + ".jwt.secret") {
		Cfg.JWT.Secret = getOrGenerateJWTSecret()
	}
	if !viper.IsSet(Branding.LCName + ".jwt.issuer") {
		Cfg.JWT.Issuer = Branding.CcName
	}
	if !viper.IsSet(Branding.LCName + ".jwt.maxAge") {
		Cfg.JWT.MaxAge = 240
	}
	if !viper.IsSet(Branding.LCName + ".jwt.compress") {
		Cfg.JWT.Compress = true
	}

	// cookie defaults
	if !viper.IsSet(Branding.LCName + ".cookie.name") {
		Cfg.Cookie.Name = "LassoCookie"
	}
	if !viper.IsSet(Branding.LCName + ".cookie.secure") {
		Cfg.Cookie.Secure = false
	}
	if !viper.IsSet(Branding.LCName + ".cookie.httpOnly") {
		Cfg.Cookie.HTTPOnly = true
	}

	// headers defaults
	if !viper.IsSet(Branding.LCName + ".headers.jwt") {
		Cfg.Headers.JWT = "X-" + Branding.CcName + "-Token"
	}
	if !viper.IsSet(Branding.LCName + ".headers.querystring") {
		Cfg.Headers.QueryString = "access_token"
	}
	if !viper.IsSet(Branding.LCName + ".headers.redirect") {
		Cfg.Headers.Redirect = "X-" + Branding.CcName + "-Requested-URI"
	}
	if !viper.IsSet(Branding.LCName + ".headers.user") {
		Cfg.Headers.User = "X-" + Branding.CcName + "-User"
	}
	if !viper.IsSet(Branding.LCName + ".headers.success") {
		Cfg.Headers.Success = "X-" + Branding.CcName + "-Success"
	}

	// db defaults
	if !viper.IsSet(Branding.LCName + ".db.file") {
		Cfg.DB.File = "data/" + Branding.LCName + "_bolt.db"
	}

	// session HERE
	if !viper.IsSet(Branding.LCName + ".session.name") {
		Cfg.Session.Name = Branding.LCName + "Session"
	}

	// testing convenience variable
	if !viper.IsSet(Branding.LCName + ".testing") {
		Cfg.Testing = false
	}
	if viper.IsSet(Branding.LCName + ".test_url") {
		Cfg.TestURLs = append(Cfg.TestURLs, Cfg.TestURL)
	}
	// TODO: proably change this name, maybe set the domain/port the webapp runs on
	if !viper.IsSet(Branding.LCName + ".webapp") {
		Cfg.WebApp = false
	}

	// OAuth defaults and client configuration
	err := UnmarshalKey("oauth", &GenOAuth)
	if err == nil {
		if GenOAuth.Provider == Providers.Google {
			setDefaultsGoogle()
			// setDefaultsGoogle also configures the OAuthClient
		} else if GenOAuth.Provider == Providers.GitHub {
			setDefaultsGitHub()
			configureOAuthClient()
		} else {
			configureOAuthClient()
		}
	}
}

func setDefaultsGoogle() {
	log.Info("configuring Google OAuth")
	GenOAuth.UserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo"
	OAuthClient = &oauth2.Config{
		ClientID:     GenOAuth.ClientID,
		ClientSecret: GenOAuth.ClientSecret,
		Scopes: []string{
			// You have to select a scope from
			// https://developers.google.com/identity/protocols/googlescopes#google_sign-in
			"https://www.googleapis.com/auth/userinfo.email",
		},
		Endpoint: google.Endpoint,
	}
	if GenOAuth.PreferredDomain != "" {
		log.Infof("setting Google OAuth preferred login domain param 'hd' to %s", GenOAuth.PreferredDomain)
		OAuthopts = oauth2.SetAuthURLParam("hd", GenOAuth.PreferredDomain)
	} else {
		OAuthopts = oauth2.SetAuthURLParam("hd", "")
	}
}

func setDefaultsGitHub() {
	// log.Info("configuring GitHub OAuth")
	if GenOAuth.AuthURL == "" {
		GenOAuth.AuthURL = github.Endpoint.AuthURL
	}
	if GenOAuth.TokenURL == "" {
		GenOAuth.TokenURL = github.Endpoint.TokenURL
	}
	if GenOAuth.UserInfoURL == "" {
		GenOAuth.UserInfoURL = "https://api.github.com/user?access_token="
	}
	if len(GenOAuth.Scopes) == 0 {
		GenOAuth.Scopes = []string{"user"}
	}
}

func configureOAuthClient() {
	log.Infof("configuring %s OAuth with Endpoint %s", GenOAuth.Provider, GenOAuth.AuthURL)
	OAuthClient = &oauth2.Config{
		ClientID:     GenOAuth.ClientID,
		ClientSecret: GenOAuth.ClientSecret,
		Endpoint: oauth2.Endpoint{
			AuthURL:  GenOAuth.AuthURL,
			TokenURL: GenOAuth.TokenURL,
		},
		RedirectURL: GenOAuth.RedirectURL,
		Scopes:      GenOAuth.Scopes,
	}
}

var secretFile = os.Getenv("LASSO_ROOT") + "config/secret"

// a-z A-Z 0-9 except no l, o, O
const charRunes = "abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ012346789"

const secretLen = 18

func getOrGenerateJWTSecret() string {
	b, err := ioutil.ReadFile(secretFile)
	if err == nil {
		log.Info("jwt.secret read from " + secretFile)
	} else {
		// then generate a new secret and store it in the file
		log.Debug(err)
		log.Info("jwt.secret not found in " + secretFile)
		log.Warn("generating random jwt.secret and storing it in " + secretFile)

		rand.Seed(time.Now().UnixNano())
		b := make([]byte, secretLen)
		for i := range b {
			b[i] = charRunes[rand.Intn(len(charRunes))]
		}
		err := ioutil.WriteFile(secretFile, b, 0600)
		if err != nil {
			log.Debug(err)
		}
	}
	return string(b)
}

func isTCPPortAvailable(listen string) bool {
	log.Debug("checking availability of tcp port: " + listen)
	conn, err := net.Listen("tcp", listen)
	if err != nil {
		log.Error(err)
		return false
	}
	conn.Close()
	return true
}
<commit_msg>Lets show a help command if needed, and add a flag for port<commit_after>package cfg

import (
	"errors"
	"flag"
	"io/ioutil"
	"math/rand"
	"net"
	"os"
	"strconv"
	"time"

	log "github.com/Sirupsen/logrus"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/github"
	"golang.org/x/oauth2/google"

	"github.com/spf13/viper"
)

// config lasso jwt cookie configuration
type config struct {
	LogLevel      string   `mapstructure:"logLevel"`
	Listen        string   `mapstructure:"listen"`
	Port          int      `mapstructure:"port"`
	Domains       []string `mapstructure:"domains"`
	WhiteList     []string `mapstructure:"whitelist"`
	AllowAllUsers bool     `mapstructure:"allowAllUsers"`
	PublicAccess  bool     `mapstructure:"publicAccess"`
	JWT           struct {
		MaxAge   int    `mapstructure:"maxAge"`
		Issuer   string `mapstructure:"issuer"`
		Secret   string `mapstructure:"secret"`
		Compress bool   `mapstructure:"compress"`
	}
	Cookie struct {
		Name     string `mapstructure:"name"`
		Domain   string `mapstructure:"domain"`
		Secure   bool   `mapstructure:"secure"`
		HTTPOnly bool   `mapstructure:"httpOnly"`
	}
	Headers struct {
		JWT         string `mapstructure:"jwt"`
		User        string `mapstructure:"user"`
		QueryString string `mapstructure:"querystring"`
		Redirect    string `mapstructure:"redirect"`
		Success     string `mapstructure:"success"`
	}
	DB struct {
		File string `mapstructure:"file"`
	}
	Session struct {
		Name string `mapstructure:"name"`
	}
	TestURL  string   `mapstructure:"test_url"`
	TestURLs []string `mapstructure:"test_urls"`
	Testing  bool     `mapstructure:"testing"`
	WebApp   bool     `mapstructure:"webapp"`
}

// oauth config items endoint for access
type oauthConfig struct {
	Provider        string   `mapstructure:"provider"`
	ClientID        string   `mapstructure:"client_id"`
	ClientSecret    string   `mapstructure:"client_secret"`
	AuthURL         string   `mapstructure:"auth_url"`
	TokenURL        string   `mapstructure:"token_url"`
	RedirectURL     string   `mapstructure:"callback_url"`
	RedirectURLs    []string `mapstructure:"callback_urls"`
	Scopes          []string `mapstructure:"scopes"`
	UserInfoURL     string   `mapstructure:"user_info_url"`
	PreferredDomain string   `mapstructre:"preferredDomain"`
}

// OAuthProviders holds the stings for
type OAuthProviders struct {
	Google    string
	GitHub    string
	IndieAuth string
	OIDC      string
}

type branding struct {
	LCName string // lower case
	UCName string // upper case
	CcName string // camel case
}

var (
	// Branding that's our name
	Branding = branding{"lasso", "LASSO", "Lasso"}

	// Cfg the main exported config variable
	Cfg config

	// GenOAuth exported OAuth config variable
	// TODO: I think GenOAuth and OAuthConfig can be combined!
	// perhaps by https://golang.org/doc/effective_go.html#embedding
	GenOAuth *oauthConfig

	// OAuthClient is the configured client which will call the provider
	// this actually carries the oauth2 client ala oauthclient.Client(oauth2.NoContext, providerToken)
	OAuthClient *oauth2.Config
	// OAuthopts authentication options
	OAuthopts oauth2.AuthCodeOption

	// Providers static strings to test against
	Providers = &OAuthProviders{
		Google:    "google",
		GitHub:    "github",
		IndieAuth: "indieauth",
		OIDC:      "oidc",
	}
)

// RequiredOptions must have these fields set for minimum viable config
var RequiredOptions = []string{"oauth.provider", "oauth.client_id"}

func init() {
	// from config file
	ParseConfig()

	// can pass loglevel on the command line
	var ll = flag.String("loglevel", Cfg.LogLevel, "enable debug log output")
	var port = flag.Int("port", -1, "port")
	var help = flag.Bool("help", false, "show usage")
	flag.Parse()
	if *help {
		flag.PrintDefaults()
		os.Exit(1)
	}

	if *port != -1 {
		Cfg.Port = *port
	}

	if *ll == "debug" {
		log.SetLevel(log.DebugLevel)
		log.Debug("logLevel set to debug")
	}

	setDefaults()

	errT := BasicTest()
	if errT != nil {
		// log.Fatalf(errT.Error())
		panic(errT)
	}

	var listen = Cfg.Listen + ":" + strconv.Itoa(Cfg.Port)
	if !isTCPPortAvailable(listen) {
		log.Fatal(errors.New("check the port availability (is " + Branding.CcName + " already running?)"))
	}

	log.Debug(viper.AllSettings())
}

// ParseConfig parse the config file
func ParseConfig() {
	log.Debug("opening config")
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(os.Getenv(Branding.UCName+"_ROOT") + "config")
	err := viper.ReadInConfig() // Find and read the config file
	if err != nil {             // Handle errors reading the config file
		log.Fatalf("Fatal error config file: %s", err.Error())
		panic(err)
	}
	UnmarshalKey(Branding.LCName, &Cfg)
	// don't log the secret!
	// log.Debugf("secret: %s", string(Cfg.JWT.Secret))
}

// UnmarshalKey populate struct from contents of cfg tree at key
func UnmarshalKey(key string, rawVal interface{}) error {
	return viper.UnmarshalKey(key, rawVal)
}

// Get string value for key
func Get(key string) string {
	return viper.GetString(key)
}

// BasicTest just a quick sanity check to see if the config is sound
func BasicTest() error {
	for _, opt := range RequiredOptions {
		if !viper.IsSet(opt) {
			return errors.New("configuration option " + opt + " is not set in config")
		}
	}
	return nil
}

// setDefaults set default options for some items
func setDefaults() {

	// this should really be done by Viper up in parseConfig but..
	// nested defaults is currently *broken*
	// https://github.com/spf13/viper/issues/309
	// viper.SetDefault("listen", "0.0.0.0")
	// viper.SetDefault(Cfg.Port, 9090)
	// viper.SetDefault("Headers.SSO", "X-"+Branding.CcName+"-Token")
	// viper.SetDefault("Headers.Redirect", "X-"+Branding.CcName+"-Requested-URI")
	// viper.SetDefault("Cookie.Name", "Lasso")

	// logging
	if !viper.IsSet(Branding.LCName + ".logLevel") {
		Cfg.LogLevel = "info"
	}
	// network defaults
	if !viper.IsSet(Branding.LCName + ".listen") {
		Cfg.Listen = "0.0.0.0"
	}
	if !viper.IsSet(Branding.LCName + ".port") {
		Cfg.Port = 9090
	}
	if !viper.IsSet(Branding.LCName + ".allowAllUsers") {
		Cfg.AllowAllUsers = false
	}
	if !viper.IsSet(Branding.LCName + ".publicAccess") {
		Cfg.PublicAccess = false
	}

	// jwt defaults
	if !viper.IsSet(Branding.LCName + ".jwt.secret") {
		Cfg.JWT.Secret = getOrGenerateJWTSecret()
	}
	if !viper.IsSet(Branding.LCName + ".jwt.issuer") {
		Cfg.JWT.Issuer = Branding.CcName
	}
	if !viper.IsSet(Branding.LCName + ".jwt.maxAge") {
		Cfg.JWT.MaxAge = 240
	}
	if !viper.IsSet(Branding.LCName + ".jwt.compress") {
		Cfg.JWT.Compress = true
	}

	// cookie defaults
	if !viper.IsSet(Branding.LCName + ".cookie.name") {
		Cfg.Cookie.Name = "LassoCookie"
	}
	if !viper.IsSet(Branding.LCName + ".cookie.secure") {
		Cfg.Cookie.Secure = false
	}
	if !viper.IsSet(Branding.LCName + ".cookie.httpOnly") {
		Cfg.Cookie.HTTPOnly = true
	}

	// headers defaults
	if !viper.IsSet(Branding.LCName + ".headers.jwt") {
		Cfg.Headers.JWT = "X-" + Branding.CcName + "-Token"
	}
	if !viper.IsSet(Branding.LCName + ".headers.querystring") {
		Cfg.Headers.QueryString = "access_token"
	}
	if !viper.IsSet(Branding.LCName + ".headers.redirect") {
		Cfg.Headers.Redirect = "X-" + Branding.CcName + "-Requested-URI"
	}
	if !viper.IsSet(Branding.LCName + ".headers.user") {
		Cfg.Headers.User = "X-" + Branding.CcName + "-User"
	}
	if !viper.IsSet(Branding.LCName + ".headers.success") {
		Cfg.Headers.Success = "X-" + Branding.CcName + "-Success"
	}

	// db defaults
	if !viper.IsSet(Branding.LCName + ".db.file") {
		Cfg.DB.File = "data/" + Branding.LCName + "_bolt.db"
	}

	// session HERE
	if !viper.IsSet(Branding.LCName + ".session.name") {
		Cfg.Session.Name = Branding.LCName + "Session"
	}

	// testing convenience variable
	if !viper.IsSet(Branding.LCName + ".testing") {
		Cfg.Testing = false
	}
	if viper.IsSet(Branding.LCName + ".test_url") {
		Cfg.TestURLs = append(Cfg.TestURLs, Cfg.TestURL)
	}
	// TODO: proably change this name, maybe set the domain/port the webapp runs on
	if !viper.IsSet(Branding.LCName + ".webapp") {
		Cfg.WebApp = false
	}

	// OAuth defaults and client configuration
	err := UnmarshalKey("oauth", &GenOAuth)
	if err == nil {
		if GenOAuth.Provider == Providers.Google {
			setDefaultsGoogle()
			// setDefaultsGoogle also configures the OAuthClient
		} else if GenOAuth.Provider == Providers.GitHub {
			setDefaultsGitHub()
			configureOAuthClient()
		} else {
			configureOAuthClient()
		}
	}
}

func setDefaultsGoogle() {
	log.Info("configuring Google OAuth")
	GenOAuth.UserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo"
	OAuthClient = &oauth2.Config{
		ClientID:     GenOAuth.ClientID,
		ClientSecret: GenOAuth.ClientSecret,
		Scopes: []string{
			// You have to select a scope from
			// https://developers.google.com/identity/protocols/googlescopes#google_sign-in
			"https://www.googleapis.com/auth/userinfo.email",
		},
		Endpoint: google.Endpoint,
	}
	if GenOAuth.PreferredDomain != "" {
		log.Infof("setting Google OAuth preferred login domain param 'hd' to %s", GenOAuth.PreferredDomain)
		OAuthopts = oauth2.SetAuthURLParam("hd", GenOAuth.PreferredDomain)
	} else {
		OAuthopts = oauth2.SetAuthURLParam("hd", "")
	}
}

func setDefaultsGitHub() {
	// log.Info("configuring GitHub OAuth")
	if GenOAuth.AuthURL == "" {
		GenOAuth.AuthURL = github.Endpoint.AuthURL
	}
	if GenOAuth.TokenURL == "" {
		GenOAuth.TokenURL = github.Endpoint.TokenURL
	}
	if GenOAuth.UserInfoURL == "" {
		GenOAuth.UserInfoURL = "https://api.github.com/user?access_token="
	}
	if len(GenOAuth.Scopes) == 0 {
		GenOAuth.Scopes = []string{"user"}
	}
}

func configureOAuthClient() {
	log.Infof("configuring %s OAuth with Endpoint %s", GenOAuth.Provider, GenOAuth.AuthURL)
	OAuthClient = &oauth2.Config{
		ClientID:     GenOAuth.ClientID,
		ClientSecret: GenOAuth.ClientSecret,
		Endpoint: oauth2.Endpoint{
			AuthURL:  GenOAuth.AuthURL,
			TokenURL: GenOAuth.TokenURL,
		},
		RedirectURL: GenOAuth.RedirectURL,
		Scopes:      GenOAuth.Scopes,
	}
}

var secretFile = os.Getenv("LASSO_ROOT") + "config/secret"

// a-z A-Z 0-9 except no l, o, O
const charRunes = "abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ012346789"

const secretLen = 18

func getOrGenerateJWTSecret() string {
	b, err := ioutil.ReadFile(secretFile)
	if err == nil {
		log.Info("jwt.secret read from " + secretFile)
	} else {
		// then generate a new secret and store it in the file
		log.Debug(err)
		log.Info("jwt.secret not found in " + secretFile)
		log.Warn("generating random jwt.secret and storing it in " + secretFile)

		rand.Seed(time.Now().UnixNano())
		b := make([]byte, secretLen)
		for i := range b {
			b[i] = charRunes[rand.Intn(len(charRunes))]
		}
		err := ioutil.WriteFile(secretFile, b, 0600)
		if err != nil {
			log.Debug(err)
		}
	}
	return string(b)
}

func isTCPPortAvailable(listen string) bool {
	log.Debug("checking availability of tcp port: " + listen)
	conn, err := net.Listen("tcp", listen)
	if err != nil {
		log.Error(err)
		return false
	}
	conn.Close()
	return true
}
<|endoftext|>


<commit_before>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `# {{name}}

## Documentation

To view generated docs for {{name}}, run the below command and point your brower to http://127.0.0.1:6060/pkg/

    godoc -http=:6060 2>/dev/null &

### Buffalo

http://gobuffalo.io/docs/getting-started

### Pop/Soda

http://gobuffalo.io/docs/db

## Database Configuration

 	development:
 		dialect: postgres
 		database: {{name}}_development
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 5

 	test:
 		dialect: postgres
 		database: {{name}}_test
 		user: <username>
 		password: <password>
 		host: 127.0.0.1

 	production:
 		dialect: postgres
 		database: {{name}}_production
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 25

 ### Running Migrations

    buffalo soda migrate

 ## Run Tests

    buffalo test

 ## Run in dev

    buffalo dev

[Powered by Buffalo](http://gobuffalo.io)

`
const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
bin/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: /tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  golint:
    enabled: true
  govet:
    enabled: true
  gofmt:
    enabled: true
  fixme:
    enabled: true
 ratings:
   paths:
    - "**.go"
 exclude_paths:
   - "grifts/**/*"
   - "**/*_test.go"
   - "*_test.go"
   - "**_test.go"
   - "logs/*"
   - "public/*"
   - "templates/*"

`
<commit_msg>build_path does not work for Windows closes #124<commit_after>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `# {{name}}

## Documentation

To view generated docs for {{name}}, run the below command and point your brower to http://127.0.0.1:6060/pkg/

    godoc -http=:6060 2>/dev/null &

### Buffalo

http://gobuffalo.io/docs/getting-started

### Pop/Soda

http://gobuffalo.io/docs/db

## Database Configuration

 	development:
 		dialect: postgres
 		database: {{name}}_development
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 5

 	test:
 		dialect: postgres
 		database: {{name}}_test
 		user: <username>
 		password: <password>
 		host: 127.0.0.1

 	production:
 		dialect: postgres
 		database: {{name}}_production
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 25

 ### Running Migrations

    buffalo soda migrate

 ## Run Tests

    buffalo test

 ## Run in dev

    buffalo dev

[Powered by Buffalo](http://gobuffalo.io)

`
const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
bin/
tmp/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  golint:
    enabled: true
  govet:
    enabled: true
  gofmt:
    enabled: true
  fixme:
    enabled: true
 ratings:
   paths:
    - "**.go"
 exclude_paths:
   - "grifts/**/*"
   - "**/*_test.go"
   - "*_test.go"
   - "**_test.go"
   - "logs/*"
   - "public/*"
   - "templates/*"

`
<|endoftext|>


<commit_before><commit_msg>remove stupid print statements<commit_after><|endoftext|>


<commit_before>package sudoku

import (
	"testing"
)

func TestRandomWeightedIndex(t *testing.T) {
	result := randomIndexWithNormalizedWeights([]float64{1.0, 0.0})
	if result != 0 {
		t.Log("Got wrong result with random weights")
		t.Fail()
	}
	result = randomIndexWithNormalizedWeights([]float64{0.5, 0.0, 0.5})
	if result != 0 && result != 2 {
		t.Log("Didn't get one of two legal weights")
		t.Fail()
	}
	result = randomIndexWithNormalizedWeights([]float64{0.0, 0.0, 1.0})
	if result != 2 {
		t.Log("Should have gotten last item in random weights; we didn't")
		t.Fail()
	}
	if weightsNormalized([]float64{1.0, 0.000001}) {
		t.Log("thought weights were normalized when they weren't")
		t.Fail()
	}
	if !weightsNormalized([]float64{0.5, 0.25, 0.25}) {
		t.Log("Didn't think weights were normalized but they were")
		t.Fail()
	}

	if weightsNormalized([]float64{0.5, -0.25, 0.25}) {
		t.Error("A negative weight was considered normal.")
	}

	result = randomIndexWithInvertedWeights([]float64{0.0, 0.0, 1.0})
	if result == 2 {
		t.Log("Got the wrong index for inverted weights")
		t.Fail()
	}

	//TODO: this test is inherently flaky
	for i := 0; i < 10; i++ {
		result = randomIndexWithInvertedWeights([]float64{0.5, 1.0, 0.0})
		if result == 2 {
			t.Error("RandominzedIndexWithInvertedWeights returned wrong result")
			break
		}
	}

	weightResult := normalizedWeights([]float64{2.0, 1.0, 1.0})
	if weightResult[0] != 0.5 || weightResult[1] != 0.25 || weightResult[2] != 0.25 {
		t.Log("Nomralized weights came back wrong")
		t.Fail()
	}

	weightResult = normalizedWeights([]float64{1.0, 1.0, -0.5})
	if weightResult[0] != 0.5 || weightResult[1] != 0.5 || weightResult[2] != 0 {
		t.Error("Normalized weights with a negative came back wrong: ", weightResult)
	}

	weightResult = normalizedWeights([]float64{-0.25, -0.5, 0.25})
	if weightResult[0] != 0.25 || weightResult[1] != 0 || weightResult[2] != 0.75 {
		t.Error("Normalized weights with two different negative numbers came back wrong: ", weightResult)
	}

	result = randomIndexWithWeights([]float64{1.0, 0.0})
	if result != 0 {
		t.Log("Got wrong result with random weights")
		t.Fail()
	}
	result = randomIndexWithWeights([]float64{5.0, 0.0, 5.0})
	if result != 0 && result != 2 {
		t.Log("Didn't get one of two legal weights")
		t.Fail()
	}
	result = randomIndexWithWeights([]float64{0.0, 0.0, 5.0})
	if result != 2 {
		t.Log("Should have gotten last item in random weights; we didn't")
		t.Fail()
	}
}
<commit_msg>TESTS FAIL. Fixed a bug in the new inverted weights test.<commit_after>package sudoku

import (
	"testing"
)

func TestRandomWeightedIndex(t *testing.T) {
	result := randomIndexWithNormalizedWeights([]float64{1.0, 0.0})
	if result != 0 {
		t.Log("Got wrong result with random weights")
		t.Fail()
	}
	result = randomIndexWithNormalizedWeights([]float64{0.5, 0.0, 0.5})
	if result != 0 && result != 2 {
		t.Log("Didn't get one of two legal weights")
		t.Fail()
	}
	result = randomIndexWithNormalizedWeights([]float64{0.0, 0.0, 1.0})
	if result != 2 {
		t.Log("Should have gotten last item in random weights; we didn't")
		t.Fail()
	}
	if weightsNormalized([]float64{1.0, 0.000001}) {
		t.Log("thought weights were normalized when they weren't")
		t.Fail()
	}
	if !weightsNormalized([]float64{0.5, 0.25, 0.25}) {
		t.Log("Didn't think weights were normalized but they were")
		t.Fail()
	}

	if weightsNormalized([]float64{0.5, -0.25, 0.25}) {
		t.Error("A negative weight was considered normal.")
	}

	result = randomIndexWithInvertedWeights([]float64{0.0, 0.0, 1.0})
	if result == 2 {
		t.Log("Got the wrong index for inverted weights")
		t.Fail()
	}

	//TODO: this test is inherently flaky
	for i := 0; i < 10; i++ {
		result = randomIndexWithInvertedWeights([]float64{0.5, 1.0, 0.0})
		if result == 1 {
			t.Error("RandominzedIndexWithInvertedWeights returned wrong result")
			break
		}
	}

	weightResult := normalizedWeights([]float64{2.0, 1.0, 1.0})
	if weightResult[0] != 0.5 || weightResult[1] != 0.25 || weightResult[2] != 0.25 {
		t.Log("Nomralized weights came back wrong")
		t.Fail()
	}

	weightResult = normalizedWeights([]float64{1.0, 1.0, -0.5})
	if weightResult[0] != 0.5 || weightResult[1] != 0.5 || weightResult[2] != 0 {
		t.Error("Normalized weights with a negative came back wrong: ", weightResult)
	}

	weightResult = normalizedWeights([]float64{-0.25, -0.5, 0.25})
	if weightResult[0] != 0.25 || weightResult[1] != 0 || weightResult[2] != 0.75 {
		t.Error("Normalized weights with two different negative numbers came back wrong: ", weightResult)
	}

	result = randomIndexWithWeights([]float64{1.0, 0.0})
	if result != 0 {
		t.Log("Got wrong result with random weights")
		t.Fail()
	}
	result = randomIndexWithWeights([]float64{5.0, 0.0, 5.0})
	if result != 0 && result != 2 {
		t.Log("Didn't get one of two legal weights")
		t.Fail()
	}
	result = randomIndexWithWeights([]float64{0.0, 0.0, 5.0})
	if result != 2 {
		t.Log("Should have gotten last item in random weights; we didn't")
		t.Fail()
	}
}
<|endoftext|>


<commit_before>package main

import(
	"fmt"
	"os"
	"github.com/rmera/gochem"
	"github.com/rmera/scu"
)

//This program will align the best plane passing through a set of atoms in a molecule with the XY-plane.
//Usage:
func main() {
	if len(os.Args)<2{
		fmt.Printf("Usage:\n%s file.xyz [indexes.dat]\nindexes.dat is a file containing one single line, with all the atoms defining the plane separated by spaces. If it is not given, all the atoms of the molecule will be taken to define the plane.\n",os.Args[0])
		os.Exit(1)
	}
	mol, err := chem.XYZRead(os.Args[1])
	if err != nil {
		panic(err.Error())
	}
	var indexes []int
	//if no file with indexes given, will just use all the atoms.
	if len(os.Args)<3{
		indexes=make([]int,mol.Len())
		for k,v:=range(indexes){
			indexes[k]=v
		}
	}else{
		indexes,err=scu.IndexFileParse(os.Args[2])
		if err!=nil{
			panic(err.Error())
		}
	}
	some := chem.ZeroVecs(len(indexes)) //will contain the atoms selected to define the plane.
	some.SomeVecs(mol.Coords[0], indexes)
	//for most rotation things it is good to have the molecule centered on its mean.
	mol.Coords[0], _, _ = chem.MassCentrate(mol.Coords[0], some, nil)
	//As we changed the atomic positions, must extract the plane-defining atoms again.
	some.SomeVecs(mol.Coords[0], indexes)
	//The strategy is: Take the normal to the plane of the molecule (os molecular subset), and rotate it until it matches the Z-axis
	//This will mean that the plane of the molecule will now match the XY-plane.
	best, err := chem.BestPlane(some, nil)
	if err != nil {
		panic(err.Error())
	}
	z, _ := chem.NewVecs([]float64{0, 0, 1})
	zero, _ := chem.NewVecs([]float64{0, 0, 0})
	fmt.Fprintln(os.Stderr,"Best  Plane", best, z,indexes)
	axis := chem.ZeroVecs(1)
	axis.Cross(best, z)
	fmt.Fprintln(os.Stderr,"axis", axis)
	//The main part of the program, where the rotation actually happens. Note that we rotate the whole
	//molecule, not just the planar subset, this is only used to calculate the rotation angle.
	mol.Coords[0], err = chem.RotateAbout(mol.Coords[0], zero, axis, chem.Angle(best, z))
	if err != nil {
		panic(err.Error())
	}
	//Now we write the rotated result.
	fmt.Print(chem.XYZStringWrite(mol.Coords[0], mol))
}
<commit_msg>gofmt'd<commit_after>package main

import (
	"fmt"
	"github.com/rmera/gochem"
	"github.com/rmera/scu"
	"os"
)

//This program will align the best plane passing through a set of atoms in a molecule with the XY-plane.
//Usage:
func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage:\n%s file.xyz [indexes.dat]\nindexes.dat is a file containing one single line, with all the atoms defining the plane separated by spaces. If it is not given, all the atoms of the molecule will be taken to define the plane.\n", os.Args[0])
		os.Exit(1)
	}
	mol, err := chem.XYZRead(os.Args[1])
	if err != nil {
		panic(err.Error())
	}
	var indexes []int
	//if no file with indexes given, will just use all the atoms.
	if len(os.Args) < 3 {
		indexes = make([]int, mol.Len())
		for k, v := range indexes {
			indexes[k] = v
		}
	} else {
		indexes, err = scu.IndexFileParse(os.Args[2])
		if err != nil {
			panic(err.Error())
		}
	}
	some := chem.ZeroVecs(len(indexes)) //will contain the atoms selected to define the plane.
	some.SomeVecs(mol.Coords[0], indexes)
	//for most rotation things it is good to have the molecule centered on its mean.
	mol.Coords[0], _, _ = chem.MassCentrate(mol.Coords[0], some, nil)
	//As we changed the atomic positions, must extract the plane-defining atoms again.
	some.SomeVecs(mol.Coords[0], indexes)
	//The strategy is: Take the normal to the plane of the molecule (os molecular subset), and rotate it until it matches the Z-axis
	//This will mean that the plane of the molecule will now match the XY-plane.
	best, err := chem.BestPlane(some, nil)
	if err != nil {
		panic(err.Error())
	}
	z, _ := chem.NewVecs([]float64{0, 0, 1})
	zero, _ := chem.NewVecs([]float64{0, 0, 0})
	fmt.Fprintln(os.Stderr, "Best  Plane", best, z, indexes)
	axis := chem.ZeroVecs(1)
	axis.Cross(best, z)
	fmt.Fprintln(os.Stderr, "axis", axis)
	//The main part of the program, where the rotation actually happens. Note that we rotate the whole
	//molecule, not just the planar subset, this is only used to calculate the rotation angle.
	mol.Coords[0], err = chem.RotateAbout(mol.Coords[0], zero, axis, chem.Angle(best, z))
	if err != nil {
		panic(err.Error())
	}
	//Now we write the rotated result.
	fmt.Print(chem.XYZStringWrite(mol.Coords[0], mol))
}
<|endoftext|>


<commit_before>// Copyright 2017 HenryLee. 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 plugin

import (
	"fmt"
	"net"

	"github.com/henrylee2cn/goutil"
	tp "github.com/henrylee2cn/teleport"
	"github.com/henrylee2cn/teleport/socket"
)

// A auth plugin for verifying peer at the first time.

// LaunchAuth creates a plugin for initiating authorization.
func LaunchAuth(fn GenerateAuthInfoFunc) tp.Plugin {
	return &auth{generateAuthInfoFunc: fn}
}

// VerifyAuth creates a plugin for verifying authorization.
func VerifyAuth(fn VerifyAuthInfoFunc) tp.Plugin {
	return &auth{verifyAuthInfoFunc: fn}
}

type (
	// AuthSession auth session provides Swap,Id and SetId methods in early session
	AuthSession interface {
		// SetId sets the session id.
		SetId(newId string)
		// RemoteAddr returns the remote network address.
		RemoteAddr() net.Addr
		// Swap returns custom data swap of the session(socket).
		Swap() goutil.Map
	}
	// GenerateAuthInfoFunc the function used to generate auth info
	GenerateAuthInfoFunc func() string
	// VerifyAuthInfoFunc the function used to verify auth info
	VerifyAuthInfoFunc func(authInfo string, sess AuthSession) *tp.Rerror
	auth               struct {
		generateAuthInfoFunc GenerateAuthInfoFunc
		verifyAuthInfoFunc   VerifyAuthInfoFunc
	}
)

var (
	_ tp.PostDialPlugin   = new(auth)
	_ tp.PostAcceptPlugin = new(auth)
)

const authURI = "/auth/verify"

func (a *auth) Name() string {
	return "auth"
}

func (a *auth) PostDial(sess tp.PreSession) *tp.Rerror {
	if a.generateAuthInfoFunc == nil {
		return nil
	}
	rerr := sess.Send(authURI, a.generateAuthInfoFunc(), nil, socket.WithBodyCodec('s'))
	if rerr != nil {
		return rerr
	}
	_, rerr = sess.Receive(func(header socket.Header) interface{} {
		return nil
	})
	return rerr
}

func (a *auth) PostAccept(sess tp.PreSession) *tp.Rerror {
	if a.verifyAuthInfoFunc == nil {
		return nil
	}
	input, rerr := sess.Receive(func(header socket.Header) interface{} {
		if header.Uri() == authURI {
			return new(string)
		}
		return nil
	})
	if rerr != nil {
		return rerr
	}
	if input.Uri() != authURI {
		return tp.NewRerror(
			tp.CodeUnauthorized,
			tp.CodeText(tp.CodeUnauthorized),
			fmt.Sprintf("the 1th package want: PULL %s, but have: %s %s", authURI, tp.TypeText(input.Ptype()), input.Uri()),
		)
	}
	authInfo := *input.Body().(*string)
	rerr = a.verifyAuthInfoFunc(authInfo, sess)
	rerr2 := sess.Send(authURI, nil, rerr)
	if rerr == nil {
		rerr = rerr2
	}
	return rerr
}
<commit_msg>fix comment<commit_after>// Copyright 2017 HenryLee. 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 plugin

import (
	"fmt"
	"net"

	"github.com/henrylee2cn/goutil"
	tp "github.com/henrylee2cn/teleport"
	"github.com/henrylee2cn/teleport/socket"
)

// A auth plugin for verifying peer at the first time.

// LaunchAuth creates a plugin for initiating authorization.
func LaunchAuth(fn GenerateAuthInfoFunc) tp.Plugin {
	return &auth{generateAuthInfoFunc: fn}
}

// VerifyAuth creates a plugin for verifying authorization.
func VerifyAuth(fn VerifyAuthInfoFunc) tp.Plugin {
	return &auth{verifyAuthInfoFunc: fn}
}

type (
	// AuthSession auth session provides SetId, RemoteAddr and Swap methods in base session
	AuthSession interface {
		// SetId sets the session id.
		SetId(newId string)
		// RemoteAddr returns the remote network address.
		RemoteAddr() net.Addr
		// Swap returns custom data swap of the session(socket).
		Swap() goutil.Map
	}
	// GenerateAuthInfoFunc the function used to generate auth info
	GenerateAuthInfoFunc func() string
	// VerifyAuthInfoFunc the function used to verify auth info
	VerifyAuthInfoFunc func(authInfo string, sess AuthSession) *tp.Rerror
	auth               struct {
		generateAuthInfoFunc GenerateAuthInfoFunc
		verifyAuthInfoFunc   VerifyAuthInfoFunc
	}
)

var (
	_ tp.PostDialPlugin   = new(auth)
	_ tp.PostAcceptPlugin = new(auth)
)

const authURI = "/auth/verify"

func (a *auth) Name() string {
	return "auth"
}

func (a *auth) PostDial(sess tp.PreSession) *tp.Rerror {
	if a.generateAuthInfoFunc == nil {
		return nil
	}
	rerr := sess.Send(authURI, a.generateAuthInfoFunc(), nil, socket.WithBodyCodec('s'))
	if rerr != nil {
		return rerr
	}
	_, rerr = sess.Receive(func(header socket.Header) interface{} {
		return nil
	})
	return rerr
}

func (a *auth) PostAccept(sess tp.PreSession) *tp.Rerror {
	if a.verifyAuthInfoFunc == nil {
		return nil
	}
	input, rerr := sess.Receive(func(header socket.Header) interface{} {
		if header.Uri() == authURI {
			return new(string)
		}
		return nil
	})
	if rerr != nil {
		return rerr
	}
	if input.Uri() != authURI {
		return tp.NewRerror(
			tp.CodeUnauthorized,
			tp.CodeText(tp.CodeUnauthorized),
			fmt.Sprintf("the 1th package want: PULL %s, but have: %s %s", authURI, tp.TypeText(input.Ptype()), input.Uri()),
		)
	}
	authInfo := *input.Body().(*string)
	rerr = a.verifyAuthInfoFunc(authInfo, sess)
	rerr2 := sess.Send(authURI, nil, rerr)
	if rerr == nil {
		rerr = rerr2
	}
	return rerr
}
<|endoftext|>


<commit_before>package koding

import (
	"errors"
	"time"

	"github.com/koding/kloud/eventer"
	"github.com/koding/kloud/machinestate"
	"github.com/koding/kloud/protocol"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var (
	FreeUserTimeout = time.Minute * 30
)

// RunChecker runs the checker everny given interval time. It fetches a single
// document.
func (p *Provider) RunChecker(interval time.Duration) {
	for _ = range time.Tick(interval) {
		machine, err := p.FetchOne()
		if err != nil {
			// do not show an error if the query didn't find anything, that
			// means there is no such a document, which we don't care
			if err != mgo.ErrNotFound {
				p.Log.Error("FetchOne err: %v", err)
			}

			p.Log.Info("checker no machines available to check: %s", err.Error())

			// move one with the next one
			continue
		}

		if err := p.CheckUsage(machine); err != nil {
			p.Log.Warning("check usage of kite err: %v", err)
		}
	}
}

func (p *Provider) CheckUsage(machine *Machine) error {
	if machine == nil {
		return errors.New("machine is nil")
	}

	// release the lock from mongodb after we are done
	defer p.ResetAssignee(machine.Id.Hex())

	klient, err := p.Connect(machine.QueryString)
	if err != nil {
		return err
	}
	defer klient.Close()

	usg, err := klient.Usage()
	if err != nil {
		p.Log.Error("[%s] couldn't get usage to klient: %s", machine.Id.Hex(), err)
		return err
	}

	p.Log.Info("[%s] machine with ip %s is inactive since %s",
		machine.Id.Hex(), machine.IpAddress, usg.InactiveDuration)

	// It still have plenty of time to work, do not stop it
	if usg.InactiveDuration <= FreeUserTimeout {
		return nil
	}

	// populare a protocol.Machine instance that is needed for the Stop()
	// method
	credential := p.GetCredential(machine.Credential)

	m := &protocol.Machine{
		MachineId:   machine.Id.Hex(),
		Provider:    machine.Provider,
		Builder:     machine.Meta,
		Credential:  credential.Meta,
		State:       machine.State(),
		CurrentData: machine,
	}

	m.Builder["username"] = "kloud"

	// add a fake eventer, meanse we are not reporting anyone and prevent also
	// panicing the code when someone try to call the eventer
	m.Eventer = &eventer.Events{}

	// stop the machine
	err = p.Stop(m)
	if err != nil {
		return err
	}

	// update the state too
	return p.UpdateState(machine.Id.Hex(), machinestate.Stopped)
}

// FetchOne() fetches a single machine document from mongodb. This document is
// locked and cannot be retrieved from others anymore. After finishin work with
// this document ResetAssignee needs to be called that it's unlocked again and
// can be fetcy by others.
func (p *Provider) FetchOne() (*Machine, error) {
	machine := &Machine{}
	query := func(c *mgo.Collection) error {
		// check only machines that are running and belongs to koding provider
		// which are not assigned to anyone yet. We also check the date to not
		// pick up fresh documents. That means documents that are proccessed
		// and put into the DB will not selected until 10 seconds pass.
		egligibleMachines := bson.M{
			"provider":            "koding",
			"status.state":        "Running",
			"assignee.name":       nil,
			"assignee.assignedAt": bson.M{"$lt": time.Now().UTC().Add(-time.Second * 10)},
		}

		// once we found something, lock it by modifing the assignee.name.
		change := mgo.Change{
			Update: bson.M{
				"$set": bson.M{
					"assignee.name":       p.Assignee(),
					"assignee.assignedAt": time.Now().UTC(),
				},
			},
			ReturnNew: true,
		}

		_, err := c.Find(egligibleMachines).Apply(change, &machine)
		if err != nil {
			return err
		}

		return nil
	}

	if err := p.Session.Run("jMachines", query); err != nil {
		return nil, err
	}

	return machine, nil
}
<commit_msg>kloud/koding/queue: improve fetching by fetching the oldest<commit_after>package koding

import (
	"errors"
	"time"

	"github.com/koding/kloud/eventer"
	"github.com/koding/kloud/machinestate"
	"github.com/koding/kloud/protocol"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var (
	FreeUserTimeout = time.Minute * 30
)

// RunChecker runs the checker everny given interval time. It fetches a single
// document.
func (p *Provider) RunChecker(interval time.Duration) {
	for _ = range time.Tick(interval) {
		machine, err := p.FetchOne()
		if err != nil {
			// do not show an error if the query didn't find anything, that
			// means there is no such a document, which we don't care
			if err != mgo.ErrNotFound {
				p.Log.Error("FetchOne err: %v", err)
			}

			p.Log.Info("checker no machines available to check: %s", err.Error())

			// move one with the next one
			continue
		}

		if err := p.CheckUsage(machine); err != nil {
			p.Log.Warning("check usage of kite err: %v", err)
		}
	}
}

func (p *Provider) CheckUsage(machine *Machine) error {
	if machine == nil {
		return errors.New("machine is nil")
	}

	// release the lock from mongodb after we are done
	defer p.ResetAssignee(machine.Id.Hex())

	klient, err := p.Connect(machine.QueryString)
	if err != nil {
		return err
	}
	defer klient.Close()

	usg, err := klient.Usage()
	if err != nil {
		p.Log.Error("[%s] couldn't get usage to klient: %s", machine.Id.Hex(), err)
		return err
	}

	p.Log.Info("[%s] machine with ip %s is inactive since %s",
		machine.Id.Hex(), machine.IpAddress, usg.InactiveDuration)

	// It still have plenty of time to work, do not stop it
	if usg.InactiveDuration <= FreeUserTimeout {
		return nil
	}

	// populare a protocol.Machine instance that is needed for the Stop()
	// method
	credential := p.GetCredential(machine.Credential)

	m := &protocol.Machine{
		MachineId:   machine.Id.Hex(),
		Provider:    machine.Provider,
		Builder:     machine.Meta,
		Credential:  credential.Meta,
		State:       machine.State(),
		CurrentData: machine,
	}

	m.Builder["username"] = "kloud"

	// add a fake eventer, meanse we are not reporting anyone and prevent also
	// panicing the code when someone try to call the eventer
	m.Eventer = &eventer.Events{}

	// stop the machine
	err = p.Stop(m)
	if err != nil {
		return err
	}

	// update the state too
	return p.UpdateState(machine.Id.Hex(), machinestate.Stopped)
}

// FetchOne() fetches a single machine document from mongodb. This document is
// locked and cannot be retrieved from others anymore. After finishin work with
// this document ResetAssignee needs to be called that it's unlocked again and
// can be fetcy by others.
func (p *Provider) FetchOne() (*Machine, error) {
	machine := &Machine{}
	query := func(c *mgo.Collection) error {
		// check only machines that are running and belongs to koding provider
		// which are not assigned to anyone yet. We also check the date to not
		// pick up fresh documents. That means documents that are proccessed
		// and put into the DB will not selected until 10 seconds pass.
		egligibleMachines := bson.M{
			"provider":            "koding",
			"status.state":        "Running",
			"assignee.name":       nil,
			"assignee.assignedAt": bson.M{"$lt": time.Now().UTC().Add(-time.Second * 10)},
		}

		// once we found something, lock it by modifing the assignee.name. Also
		// create a new timestamp (assignee.assignedAt) which is needed for
		// several cases like (explained above and below)
		change := mgo.Change{
			Update: bson.M{
				"$set": bson.M{
					"assignee.name":       p.Assignee(),
					"assignee.assignedAt": time.Now().UTC(),
				},
			},
			ReturnNew: true,
		}

		// We sort according to the latest assignment date, which let's us pick
		// always the oldest one instead of random/first. Returning an error
		// means there is no document that matches our criterias.
		_, err := c.Find(egligibleMachines).Sort("assignee.assignedAt").Apply(change, &machine)
		if err != nil {
			return err
		}

		return nil
	}

	if err := p.Session.Run("jMachines", query); err != nil {
		return nil, err
	}

	return machine, nil
}
<|endoftext|>


<commit_before>// FORMAT
//
// The dns package implements String() for all RR types, but sometimes you will
// need more flexibility. The functions Printf, Sprintf, etc. implemented formatted I/O
// for the RR type.
//
// Printing
//
// The verbs:
//
// Generic part of RRs:
//
//	%N	the owner name of the RR
//	%C	the class: IN, CH, CLASS15, etc.
//	%D	the TTL in seconds
//	%Y	the type: MX, A, etc.
//
// The rdata of each RR differs, we allow each field to be printed as a string.
//
// Rdata: (TODO)
//
//	%0	the first rdata field
//	%1	the second rdata field
//	%2	the third rdata field
//	..	...
//	%9      the nineth rdata field
//	%R	all rdata fields
//
package dns

import (
	"fmt"
	"strconv"
)

func format(r RR, f fmt.State, c rune) {
	switch c {
	case 'N':
		f.Write([]byte(r.Header().Name))
	case 'C':
		f.Write([]byte(Class(r.Header().Class).String()))
	case 'D':
		f.Write([]byte(strconv.Itoa(int(r.Header().Ttl))))
	case 'Y':
		f.Write([]byte(Type(r.Header().Rrtype).String()))
	case 's':
		f.Write([]byte(r.String()))

	}
}

func format_Header(h *RR_Header, f fmt.State, c rune) {
	switch c {
	case 'N':
		f.Write([]byte(h.Name))
	case 'C':
		f.Write([]byte(Class(h.Class).String()))
	case 'D':
		f.Write([]byte(strconv.Itoa(int(h.Ttl))))
	case 'Y':
		f.Write([]byte(Type(h.Rrtype).String()))
	case 's':
		f.Write([]byte(h.String()))
	}
}

func (h *RR_Header) Format(f fmt.State, c rune)  { format_Header(h, f, c) }
func (rr *RFC3597) Format(f fmt.State, c rune)   { format(rr, f, c) }
func (rr *PrivateRR) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *IPSECKEY) Format(f fmt.State, c rune)  { format(rr, f, c) }
func (rr *ANY) Format(f fmt.State, c rune)       { format(rr, f, c) }

// Quick 'n dirty:
// for i in $(egrep '\sType.*:.*new\(' types.go | awk '{ print $6 } ' | sed 's/new(//' | sed 's/)//'); do
// echo "func (rr *$i) Format(f fmt.State, c rune) { format(rr, f, c) }" ; done

func (rr *A) Format(f fmt.State, c rune)          { format(rr, f, c) }
func (rr *AAAA) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *AFSDB) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *CDS) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *CERT) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *CNAME) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *DHCID) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *DLV) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *DNAME) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *KEY) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *DNSKEY) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *DS) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *EUI48) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *EUI64) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *GID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *GPOS) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *EID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *HINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *HIP) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *KX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *L32) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *L64) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *LOC) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *LP) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MB) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MD) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MF) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MG) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *MR) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *NAPTR) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *NINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NIMLOC) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *NS) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *NSAP) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *NSAPPTR) Format(f fmt.State, c rune)    { format(rr, f, c) }
func (rr *NSEC3) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NSEC3PARAM) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *NSEC) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *OPENPGPKEY) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *OPT) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *PTR) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *RKEY) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *RP) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *PX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *SIG) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *RRSIG) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *RT) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *SOA) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SPF) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SRV) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SSHFP) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *TA) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *TALINK) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *TKEY) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TLSA) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TSIG) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TXT) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *UID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *UINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *URI) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *WKS) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *X25) Format(f fmt.State, c rune)        { format(rr, f, c) }
<commit_msg>Better docs<commit_after>// FORMAT
//
// The dns package implements String() for all RR types, but sometimes you will
// need more flexibility. Here we define an extra set of formatting verbs that
// can be used in the formatted I/O package fmt.
//
// Printing
//
// The verbs:
//
// Generic parts of RRs:
//
//	%N	the owner name of the RR
//	%C	the class: IN, CH, CLASS15, etc.
//	%D	the TTL in seconds
//	%Y	the type: MX, A, etc.
//
// The rdata of each RR differs, we allow each field to be printed as a string.
//
// Rdata: (TODO)
//
//	%0	the first rdata field
//	%1	the second rdata field
//	%2	the third rdata field
//	..	...
//	%9      the nineth rdata field
//	%R	all rdata fields
//
// Non exsiting rdata fields will be printed as the empty string.
//
package dns

import (
	"fmt"
	"strconv"
)

func format(r RR, f fmt.State, c rune) {
	switch c {
	case 'N':
		f.Write([]byte(r.Header().Name))
	case 'C':
		f.Write([]byte(Class(r.Header().Class).String()))
	case 'D':
		f.Write([]byte(strconv.Itoa(int(r.Header().Ttl))))
	case 'Y':
		f.Write([]byte(Type(r.Header().Rrtype).String()))
	case 's':
		f.Write([]byte(r.String()))

	}
}

func format_Header(h *RR_Header, f fmt.State, c rune) {
	switch c {
	case 'N':
		f.Write([]byte(h.Name))
	case 'C':
		f.Write([]byte(Class(h.Class).String()))
	case 'D':
		f.Write([]byte(strconv.Itoa(int(h.Ttl))))
	case 'Y':
		f.Write([]byte(Type(h.Rrtype).String()))
	case 's':
		f.Write([]byte(h.String()))
	}
}

func (h *RR_Header) Format(f fmt.State, c rune)  { format_Header(h, f, c) }
func (rr *RFC3597) Format(f fmt.State, c rune)   { format(rr, f, c) }
func (rr *PrivateRR) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *IPSECKEY) Format(f fmt.State, c rune)  { format(rr, f, c) }
func (rr *ANY) Format(f fmt.State, c rune)       { format(rr, f, c) }

// Quick 'n dirty:
// for i in $(egrep '\sType.*:.*new\(' types.go | awk '{ print $6 } ' | sed 's/new(//' | sed 's/)//'); do
// echo "func (rr *$i) Format(f fmt.State, c rune) { format(rr, f, c) }" ; done

func (rr *A) Format(f fmt.State, c rune)          { format(rr, f, c) }
func (rr *AAAA) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *AFSDB) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *CDS) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *CERT) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *CNAME) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *DHCID) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *DLV) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *DNAME) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *KEY) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *DNSKEY) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *DS) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *EUI48) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *EUI64) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *GID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *GPOS) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *EID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *HINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *HIP) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *KX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *L32) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *L64) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *LOC) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *LP) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MB) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MD) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MF) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MG) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *MR) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *MX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *NAPTR) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *NINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NIMLOC) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *NS) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *NSAP) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *NSAPPTR) Format(f fmt.State, c rune)    { format(rr, f, c) }
func (rr *NSEC3) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *NSEC3PARAM) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *NSEC) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *OPENPGPKEY) Format(f fmt.State, c rune) { format(rr, f, c) }
func (rr *OPT) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *PTR) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *RKEY) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *RP) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *PX) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *SIG) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *RRSIG) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *RT) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *SOA) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SPF) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SRV) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *SSHFP) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *TA) Format(f fmt.State, c rune)         { format(rr, f, c) }
func (rr *TALINK) Format(f fmt.State, c rune)     { format(rr, f, c) }
func (rr *TKEY) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TLSA) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TSIG) Format(f fmt.State, c rune)       { format(rr, f, c) }
func (rr *TXT) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *UID) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *UINFO) Format(f fmt.State, c rune)      { format(rr, f, c) }
func (rr *URI) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *WKS) Format(f fmt.State, c rune)        { format(rr, f, c) }
func (rr *X25) Format(f fmt.State, c rune)        { format(rr, f, c) }
<|endoftext|>